From 279010a2e73aaac24560cd1ecbbf9d9755f5350a Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Mon, 18 May 2026 23:55:06 -0700 Subject: [PATCH 01/13] improvement(execution): memory usage for aggregated results (#4650) * improvement(execution): memory usage for aggregated results * progress * address comments * loop/parallel results compaction * address comment * remove build files, harden edge cases * remove hotpath serialiazation * display change to make use of only preview * materialize refs before sending in response block * preserve exact large-value access through workflow materialization * address comments * progress * fix notif error + sync manifest undefined exit * fix streaming ref materialization * fix tests --- apps/docs/content/docs/en/blocks/function.mdx | 4 +- .../docs/en/execution/api-deployment.mdx | 2 +- .../app/api/function/execute/route.test.ts | 136 +++- apps/sim/app/api/function/execute/route.ts | 64 +- .../[id]/execute/response-block.test.ts | 328 +++++++++- .../app/api/workflows/[id]/execute/route.ts | 83 ++- .../components/structured-output.tsx | 25 +- .../utils/workflow-execution-utils.ts | 8 + .../executor/execution/block-executor.test.ts | 129 ++++ apps/sim/executor/execution/block-executor.ts | 3 + apps/sim/executor/execution/executor.ts | 24 +- .../execution/snapshot-serializer.test.ts | 24 +- .../executor/execution/snapshot-serializer.ts | 131 ++++ apps/sim/executor/execution/types.ts | 4 + .../executor/handlers/agent/agent-handler.ts | 2 + .../handlers/function/function-handler.ts | 6 + .../handlers/mothership/mothership-handler.ts | 2 + .../variables/variables-handler.test.ts | 296 +++++++++ .../handlers/variables/variables-handler.ts | 82 ++- apps/sim/executor/orchestrators/loop.test.ts | 150 +++++ apps/sim/executor/orchestrators/loop.ts | 32 +- apps/sim/executor/orchestrators/parallel.ts | 8 +- apps/sim/executor/types.ts | 4 + apps/sim/executor/utils/output-filter.test.ts | 42 ++ apps/sim/executor/utils/output-filter.ts | 15 +- .../executor/utils/subflow-utils.server.ts | 126 ++++ apps/sim/executor/utils/subflow-utils.test.ts | 147 ++++- apps/sim/executor/utils/subflow-utils.ts | 78 +-- apps/sim/executor/variables/resolver.test.ts | 338 +++++++++- apps/sim/executor/variables/resolver.ts | 116 +++- apps/sim/executor/variables/resolvers/loop.ts | 27 +- .../executor/variables/resolvers/parallel.ts | 27 +- .../resolvers/reference-async.server.ts | 137 +++- .../variables/resolvers/reference.test.ts | 32 + .../executor/variables/resolvers/reference.ts | 97 ++- .../variables/resolvers/workflow.test.ts | 118 +++- .../executor/variables/resolvers/workflow.ts | 93 ++- apps/sim/lib/api/contracts/hotspots.ts | 2 + .../tools/handlers/workflow/mutations.test.ts | 88 ++- .../tools/handlers/workflow/mutations.ts | 56 +- .../lib/core/utils/response-format.test.ts | 58 ++ apps/sim/lib/core/utils/response-format.ts | 13 + apps/sim/lib/core/utils/user-file.ts | 36 ++ apps/sim/lib/execution/isolated-vm-worker.cjs | 1 + .../sim/lib/execution/payloads/access-keys.ts | 41 ++ apps/sim/lib/execution/payloads/cache.ts | 4 + .../lib/execution/payloads/hydration.test.ts | 144 +++++ apps/sim/lib/execution/payloads/hydration.ts | 31 +- .../payloads/inline-materialization.server.ts | 167 +++++ .../payloads/large-array-manifest-metadata.ts | 80 +++ .../payloads/large-array-manifest.test.ts | 183 ++++++ .../payloads/large-array-manifest.ts | 250 ++++++++ .../payloads/large-execution-value.test.ts | 72 +++ .../payloads/large-execution-value.ts | 130 ++++ .../payloads/materialization.server.ts | 32 +- .../lib/execution/payloads/serializer.test.ts | 158 ++++- apps/sim/lib/execution/payloads/serializer.ts | 37 +- apps/sim/lib/execution/payloads/store.ts | 3 + .../lib/execution/sandbox/bundles/docx.cjs | 27 - .../lib/execution/sandbox/bundles/pdf-lib.cjs | 55 -- .../execution/sandbox/bundles/pptxgenjs.cjs | 124 ---- .../logs/execution/trace-spans/trace-spans.ts | 11 +- .../utils/user-file-base64.server.test.ts | 143 +++++ .../uploads/utils/user-file-base64.server.ts | 59 +- .../workflows/executor/execute-workflow.ts | 6 + .../workflows/executor/execution-core.test.ts | 48 ++ .../lib/workflows/executor/execution-core.ts | 32 +- .../lib/workflows/executor/execution-state.ts | 20 +- .../lib/workflows/streaming/streaming.test.ts | 606 ++++++++++++++++++ apps/sim/lib/workflows/streaming/streaming.ts | 348 +++++++--- apps/sim/lib/workflows/utils.test.ts | 35 +- apps/sim/lib/workflows/utils.ts | 12 +- .../sim/stores/terminal/console/store.test.ts | 36 ++ apps/sim/stores/terminal/console/store.ts | 10 +- apps/sim/stores/terminal/console/types.ts | 2 + apps/sim/tools/function/execute.ts | 6 + apps/sim/tools/function/types.ts | 2 + apps/sim/tools/types.ts | 2 + 78 files changed, 5583 insertions(+), 527 deletions(-) create mode 100644 apps/sim/executor/execution/block-executor.test.ts create mode 100644 apps/sim/executor/handlers/variables/variables-handler.test.ts create mode 100644 apps/sim/executor/orchestrators/loop.test.ts create mode 100644 apps/sim/executor/utils/output-filter.test.ts create mode 100644 apps/sim/executor/utils/subflow-utils.server.ts create mode 100644 apps/sim/lib/core/utils/response-format.test.ts create mode 100644 apps/sim/lib/execution/payloads/access-keys.ts create mode 100644 apps/sim/lib/execution/payloads/hydration.test.ts create mode 100644 apps/sim/lib/execution/payloads/inline-materialization.server.ts create mode 100644 apps/sim/lib/execution/payloads/large-array-manifest-metadata.ts create mode 100644 apps/sim/lib/execution/payloads/large-array-manifest.test.ts create mode 100644 apps/sim/lib/execution/payloads/large-array-manifest.ts create mode 100644 apps/sim/lib/execution/payloads/large-execution-value.test.ts create mode 100644 apps/sim/lib/execution/payloads/large-execution-value.ts delete mode 100644 apps/sim/lib/execution/sandbox/bundles/docx.cjs delete mode 100644 apps/sim/lib/execution/sandbox/bundles/pdf-lib.cjs delete mode 100644 apps/sim/lib/execution/sandbox/bundles/pptxgenjs.cjs create mode 100644 apps/sim/lib/workflows/streaming/streaming.test.ts diff --git a/apps/docs/content/docs/en/blocks/function.mdx b/apps/docs/content/docs/en/blocks/function.mdx index 4f5037be127..e8c0bc5b7bd 100644 --- a/apps/docs/content/docs/en/blocks/function.mdx +++ b/apps/docs/content/docs/en/blocks/function.mdx @@ -198,7 +198,7 @@ const file = ; const base64 = await sim.files.readBase64(file); ``` -`sim.files.readBase64(file)`, `sim.files.readText(file)`, `sim.files.readBase64Chunk(file, { offset, length })`, and `sim.files.readTextChunk(file, { offset, length })` read from server-side execution storage under memory caps. `sim.values.read(ref)` can explicitly read a large execution value reference. These helpers are available only in JavaScript functions without imports. JavaScript with imports, Python, and shell do not support these lazy helpers yet. +`sim.files.readBase64(file)`, `sim.files.readText(file)`, `sim.files.readBase64Chunk(file, { offset, length })`, and `sim.files.readTextChunk(file, { offset, length })` read from server-side execution storage under memory caps. `sim.values.read(ref)` explicitly reads a large execution value reference, and `sim.values.readArray(ref)` reads a manifest-backed large array. These helpers are available only in JavaScript functions without imports. JavaScript with imports, Python, and shell do not support these lazy helpers yet. Very large full reads can still fail by design; use chunk helpers or return a file when you need to handle more data. @@ -228,7 +228,7 @@ return { name: file.name, chunk: firstMegabyteBase64 }; Chunk `offset` and `length` are byte-based. For Unicode text, a chunk can split a multi-byte character at the boundary; use text chunks for approximate text processing and prefer smaller structured references when exact parsing matters. -Avoid passing a full large object into a Function block when you only need one field. For example, prefer `` over `` when the API response is large. If a JavaScript Function without imports references a large execution value, Sim automatically reads it through `sim.values.read(...)` at runtime under memory caps. +Avoid passing a full large object into a Function block when you only need one field. For example, prefer `` over `` when the API response is large. If a JavaScript Function without imports references a whole large execution value, Sim automatically rewrites it to `sim.values.read(...)` at runtime under memory caps. If the value is a manifest-backed array, Sim rewrites it to `sim.values.readArray(...)` so array variables can stay compact between blocks. For large generated data, write the result to a file or table with `outputPath`, `outputSandboxPath`, or `outputTable` instead of returning the entire payload inline. diff --git a/apps/docs/content/docs/en/execution/api-deployment.mdx b/apps/docs/content/docs/en/execution/api-deployment.mdx index b7f1de3fbf9..8bcc9094e87 100644 --- a/apps/docs/content/docs/en/execution/api-deployment.mdx +++ b/apps/docs/content/docs/en/execution/api-deployment.mdx @@ -232,7 +232,7 @@ Workflow execution responses are capped by platform request and response limits. } ``` -The `version` field is part of the external API contract. Treat the reference as an opaque placeholder for a value that could not be safely embedded in the response. `id`, `key`, and `executionId` are not fetch URLs; `key` points to execution-scoped server storage. Use `selectedOutputs` to request a smaller nested field, reduce the data passed between blocks, or return the data from a Response block when your workflow intentionally owns the HTTP response body. File outputs are metadata-first; request `.base64` only when you need inline file content. JavaScript Function blocks can explicitly read large files or value refs with the `sim.files` and `sim.values` helpers under memory caps. +The `version` field is part of the external API contract. Treat the reference as an opaque placeholder for a value that could not be safely embedded in the response. `id`, `key`, and `executionId` are not fetch URLs; `key` points to execution-scoped server storage. Use `selectedOutputs` to request a smaller nested field, reduce the data passed between blocks, or return the data from a Response block when your workflow intentionally owns the HTTP response body. File outputs are metadata-first; request `.base64` only when you need inline file content. JavaScript Function blocks can explicitly read large files, value refs, and manifest-backed arrays with the `sim.files` and `sim.values` helpers under memory caps. ### Asynchronous diff --git a/apps/sim/app/api/function/execute/route.test.ts b/apps/sim/app/api/function/execute/route.test.ts index fe2ccc59b1a..3b191146c48 100644 --- a/apps/sim/app/api/function/execute/route.test.ts +++ b/apps/sim/app/api/function/execute/route.test.ts @@ -12,9 +12,10 @@ import { import { NextRequest } from 'next/server' import { beforeEach, describe, expect, it, vi } from 'vitest' -const { mockExecuteInE2B, mockExecuteInIsolatedVM } = vi.hoisted(() => ({ +const { mockExecuteInE2B, mockExecuteInIsolatedVM, mockUploadFile } = vi.hoisted(() => ({ mockExecuteInE2B: vi.fn(), mockExecuteInIsolatedVM: vi.fn(), + mockUploadFile: vi.fn(), })) vi.mock('@/lib/execution/isolated-vm', () => ({ @@ -42,16 +43,26 @@ vi.mock('@/lib/uploads/contexts/workspace/workspace-file-manager', () => ({ uploadWorkspaceFile: vi.fn(), })) +vi.mock('@/lib/uploads', () => ({ + StorageService: { + uploadFile: mockUploadFile, + }, +})) + vi.mock('@/lib/workflows/utils', () => workflowsUtilsMock) vi.mock('@/lib/core/config/feature-flags', () => featureFlagsMock) import { validateProxyUrl } from '@/lib/core/security/input-validation' +import { clearLargeValueCacheForTests } from '@/lib/execution/payloads/cache' +import { isLargeArrayManifest } from '@/lib/execution/payloads/large-array-manifest-metadata' +import { isLargeValueRef } from '@/lib/execution/payloads/large-value-ref' import { POST } from '@/app/api/function/execute/route' describe('Function Execute API Route', () => { beforeEach(() => { vi.clearAllMocks() + featureFlagsMock.isE2bEnabled = false hybridAuthMockFns.mockCheckInternalAuth.mockResolvedValue({ success: true, @@ -60,6 +71,8 @@ describe('Function Execute API Route', () => { }) mockExecuteInIsolatedVM.mockResolvedValue({ result: 'test', stdout: '' }) + mockUploadFile.mockImplementation(async ({ customKey }) => ({ key: customKey })) + clearLargeValueCacheForTests() mockExecuteInE2B.mockResolvedValue({ result: 'e2b success', @@ -201,6 +214,60 @@ describe('Function Execute API Route', () => { expect(data.output).toHaveProperty('executionTime') }) + it('compacts large array result fields to manifests when execution context is durable', async () => { + mockExecuteInIsolatedVM.mockResolvedValueOnce({ + result: { + rows: Array.from({ length: 120_000 }, (_, index) => ({ + key: `SIM-${index}`, + payload: 'x'.repeat(100), + })), + }, + stdout: '', + }) + + const req = createMockRequest('POST', { + code: 'return rows', + workflowId: 'workflow-1', + workspaceId: 'workspace-1', + executionId: 'execution-1', + }) + + const response = await POST(req) + const data = await response.json() + + expect(response.status).toBe(200) + expect(data.success).toBe(true) + expect(isLargeArrayManifest(data.output.result.rows)).toBe(true) + expect(data.output.result.rows).toMatchObject({ + __simLargeArrayManifest: true, + kind: 'array', + totalCount: 120_000, + }) + }) + + it('keeps large string result fields as generic large value refs', async () => { + mockExecuteInIsolatedVM.mockResolvedValueOnce({ + result: { + text: 'x'.repeat(9 * 1024 * 1024), + }, + stdout: '', + }) + + const req = createMockRequest('POST', { + code: 'return text', + workflowId: 'workflow-1', + workspaceId: 'workspace-1', + executionId: 'execution-1', + }) + + const response = await POST(req) + const data = await response.json() + + expect(response.status).toBe(200) + expect(data.success).toBe(true) + expect(isLargeValueRef(data.output.result.text)).toBe(true) + }) + it('should return computed result for multi-line code', async () => { mockExecuteInIsolatedVM.mockResolvedValueOnce({ result: 10, stdout: '' }) @@ -240,6 +307,73 @@ describe('Function Execute API Route', () => { expect(response.status).toBe(200) expect(data.success).toBe(true) }) + + it('rejects large refs in runtimes without ref-native helpers', async () => { + featureFlagsMock.isE2bEnabled = true + const req = createMockRequest('POST', { + code: 'echo "$__blockRef_0"', + language: 'shell', + contextVariables: { + __blockRef_0: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 12 * 1024 * 1024, + executionId: 'execution-1', + }, + }, + }) + + const response = await POST(req) + const data = await response.json() + + expect(response.status).toBe(500) + expect(data.success).toBe(false) + expect(data.error).toContain( + 'Large execution values require the JavaScript isolated-vm runtime' + ) + }) + + it('registers manifest array read broker for isolated-vm execution', async () => { + const req = createMockRequest('POST', { + code: 'return await sim.values.readArray(__blockRef_0)', + language: 'javascript', + contextVariables: { + __blockRef_0: { + __simLargeArrayManifest: true, + version: 2, + kind: 'array', + totalCount: 1, + chunkCount: 1, + byteSize: 16, + chunks: [ + { + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 16, + executionId: 'execution-1', + }, + count: 1, + byteSize: 16, + }, + ], + preview: [{ id: 1 }], + }, + }, + }) + + const response = await POST(req) + const data = await response.json() + const [, options] = mockExecuteInIsolatedVM.mock.calls.at(-1) ?? [] + + expect(response.status).toBe(200) + expect(data.success).toBe(true) + expect(options?.brokers).toHaveProperty('sim.values.readArray') + }) }) describe('Template Variable Resolution', () => { diff --git a/apps/sim/app/api/function/execute/route.ts b/apps/sim/app/api/function/execute/route.ts index 1b2d5f844e1..5fa058736d2 100644 --- a/apps/sim/app/api/function/execute/route.ts +++ b/apps/sim/app/api/function/execute/route.ts @@ -14,7 +14,12 @@ import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { executeInE2B, executeShellInE2B } from '@/lib/execution/e2b' import { executeInIsolatedVM, type IsolatedVMBrokerHandler } from '@/lib/execution/isolated-vm' import { CodeLanguage, DEFAULT_CODE_LANGUAGE, isValidCodeLanguage } from '@/lib/execution/languages' -import { isLargeValueRef } from '@/lib/execution/payloads/large-value-ref' +import { recordMaterializedAccessKeys } from '@/lib/execution/payloads/access-keys' +import { + isLargeArrayManifest, + materializeLargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest' +import { containsLargeValueRef, isLargeValueRef } from '@/lib/execution/payloads/large-value-ref' import { MAX_FUNCTION_INLINE_BYTES, MAX_INLINE_MATERIALIZATION_BYTES, @@ -699,6 +704,8 @@ interface FunctionRouteExecutionContext { workspaceId?: string executionId?: string largeValueExecutionIds?: string[] + largeValueKeys?: string[] + fileKeys?: string[] allowLargeValueWorkflowScope?: boolean userId?: string requestId: string @@ -741,17 +748,26 @@ function getBrokerFileArgs(args: unknown): { function createFunctionRuntimeBrokers( context: FunctionRouteExecutionContext ): Record { + context.largeValueKeys ??= [] + context.fileKeys ??= [] + const largeValueKeys = context.largeValueKeys + const fileKeys = context.fileKeys const base = { requestId: context.requestId, workflowId: context.workflowId, workspaceId: context.workspaceId, executionId: context.executionId, largeValueExecutionIds: context.largeValueExecutionIds, + largeValueKeys, + fileKeys, allowLargeValueWorkflowScope: context.allowLargeValueWorkflowScope, userId: context.userId, logger, } + const recordMaterializedKeys = (value: unknown) => + recordMaterializedAccessKeys({ largeValueKeys, fileKeys }, value) + const readFile = async (args: unknown, encoding: 'base64' | 'text', chunked = false) => { const fileArgs = getBrokerFileArgs(args) return readUserFileContent(fileArgs.file, { @@ -786,6 +802,24 @@ function createFunctionRuntimeBrokers( if (value === undefined) { throw unavailableLargeValueError(ref) } + recordMaterializedKeys(value) + return value + }, + 'sim.values.readArray': async (args) => { + const record = asRecord(args) + const options = asRecord(record.options) + const manifest = record.ref + if (!isLargeArrayManifest(manifest)) { + throw new Error('Expected a large array manifest.') + } + if (!context.executionId) { + throw new Error('Large array manifests require an execution context.') + } + const value = await materializeLargeArrayManifest(manifest, { + ...base, + maxBytes: clampInlineBytes(options.maxBytes, MAX_INLINE_MATERIALIZATION_BYTES), + }) + recordMaterializedKeys(value) return value }, } @@ -810,7 +844,17 @@ async function functionJsonResponse( context: FunctionRouteExecutionContext, init?: ResponseInit ) { - return NextResponse.json(await compactFunctionRouteBody(body, context), init) + return NextResponse.json( + await compactFunctionRouteBody( + { + ...body, + largeValueKeys: context.largeValueKeys, + fileKeys: context.fileKeys, + }, + context + ), + init + ) } async function maybeExportSandboxFileToWorkspace(args: { @@ -955,6 +999,8 @@ export const POST = withRouteHandler(async (req: NextRequest) => { workflowId, executionId, largeValueExecutionIds, + largeValueKeys, + fileKeys, allowLargeValueWorkflowScope = false, workspaceId, isCustomTool = false, @@ -979,6 +1025,8 @@ export const POST = withRouteHandler(async (req: NextRequest) => { workspaceId, executionId, largeValueExecutionIds, + largeValueKeys, + fileKeys, allowLargeValueWorkflowScope, userId: auth.userId, requestId, @@ -1013,6 +1061,12 @@ export const POST = withRouteHandler(async (req: NextRequest) => { contextVariables = { ...codeResolution.contextVariables, ...preResolvedContextVariables } } + if (lang === CodeLanguage.Shell && containsLargeValueRef(contextVariables)) { + throw new Error( + 'Large execution values require the JavaScript isolated-vm runtime. Select a nested field or read the value in a JavaScript function.' + ) + } + let jsImports = '' let jsRemainingCode = resolvedCode let hasImports = false @@ -1124,6 +1178,12 @@ export const POST = withRouteHandler(async (req: NextRequest) => { !isCustomTool && (lang === CodeLanguage.Python || (lang === CodeLanguage.JavaScript && hasImports)) + if (useE2B && containsLargeValueRef(contextVariables)) { + throw new Error( + 'Large execution values require the JavaScript isolated-vm runtime. Remove imports, select a nested field, or read the value in a JavaScript function without E2B.' + ) + } + if (useE2B) { logger.info(`[${requestId}] E2B status`, { enabled: isE2bEnabled, diff --git a/apps/sim/app/api/workflows/[id]/execute/response-block.test.ts b/apps/sim/app/api/workflows/[id]/execute/response-block.test.ts index 16808cca6f9..38e476f6522 100644 --- a/apps/sim/app/api/workflows/[id]/execute/response-block.test.ts +++ b/apps/sim/app/api/workflows/[id]/execute/response-block.test.ts @@ -5,11 +5,36 @@ * @vitest-environment node */ -import { beforeEach, describe, expect, it } from 'vitest' +import { beforeEach, describe, expect, it, vi } from 'vitest' import { AuthType } from '@/lib/auth/hybrid' +import { clearLargeValueCacheForTests } from '@/lib/execution/payloads/cache' +import { createLargeArrayManifest } from '@/lib/execution/payloads/large-array-manifest' +import { compactExecutionPayload } from '@/lib/execution/payloads/serializer' +import { storeLargeValue } from '@/lib/execution/payloads/store' +import { EXECUTION_RESOURCE_LIMIT_CODE } from '@/lib/execution/resource-errors' import type { ExecutionResult } from '@/lib/workflows/types' import { createHttpResponseFromBlock, workflowHasResponseBlock } from '@/lib/workflows/utils' +const { mockDownloadFile, mockUploadFile, uploadedFiles } = vi.hoisted(() => ({ + mockDownloadFile: vi.fn(), + mockUploadFile: vi.fn(), + uploadedFiles: new Map(), +})) + +const MATERIALIZATION_CONTEXT = { + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + executionId: 'execution-1', + userId: 'user-1', +} + +vi.mock('@/lib/uploads', () => ({ + StorageService: { + downloadFile: mockDownloadFile, + uploadFile: mockUploadFile, + }, +})) + function buildExecutionResult(overrides: Partial = {}): ExecutionResult { return { success: true, @@ -38,6 +63,16 @@ describe('Response block gating by auth type', () => { let resultWithResponseBlock: ExecutionResult beforeEach(() => { + vi.clearAllMocks() + clearLargeValueCacheForTests() + uploadedFiles.clear() + mockUploadFile.mockImplementation(async ({ customKey, file }) => { + uploadedFiles.set(customKey, file) + return { key: customKey } + }) + mockDownloadFile.mockImplementation( + async ({ key }) => uploadedFiles.get(key) ?? Buffer.from('{}') + ) resultWithResponseBlock = buildExecutionResult() }) @@ -75,14 +110,14 @@ describe('Response block gating by auth type', () => { expect(shouldFormatAsResponseBlock).toBe(false) }) - it('should apply Response block formatting for API key callers', () => { + it('should apply Response block formatting for API key callers', async () => { const authType = AuthType.API_KEY const hasResponseBlock = workflowHasResponseBlock(resultWithResponseBlock) const shouldFormatAsResponseBlock = authType !== AuthType.INTERNAL_JWT && hasResponseBlock expect(shouldFormatAsResponseBlock).toBe(true) - const response = createHttpResponseFromBlock(resultWithResponseBlock) + const response = await createHttpResponseFromBlock(resultWithResponseBlock) expect(response.status).toBe(200) }) @@ -95,7 +130,7 @@ describe('Response block gating by auth type', () => { }) it('should return raw user data via createHttpResponseFromBlock', async () => { - const response = createHttpResponseFromBlock(resultWithResponseBlock) + const response = await createHttpResponseFromBlock(resultWithResponseBlock) const body = await response.json() // Response block returns the user-defined data directly (no success/executionId wrapper) @@ -104,12 +139,293 @@ describe('Response block gating by auth type', () => { expect(body.executionId).toBeUndefined() }) - it('should respect custom status codes from Response block', () => { + it('should respect custom status codes from Response block', async () => { const result = buildExecutionResult({ output: { data: { error: 'Not found' }, status: 404, headers: {} }, }) - const response = createHttpResponseFromBlock(result) + const response = await createHttpResponseFromBlock(result) expect(response.status).toBe(404) }) + + it('should materialize manifest data for Response block HTTP output', async () => { + const rows = Array.from({ length: 100 }, (_, index) => ({ + key: `SIM-${index}`, + payload: 'x'.repeat(100), + })) + const output = await compactExecutionPayload( + { + data: { rows }, + status: 200, + headers: {}, + }, + { + ...MATERIALIZATION_CONTEXT, + requireDurable: true, + preserveRoot: true, + thresholdBytes: 1024, + } + ) + const response = await createHttpResponseFromBlock( + buildExecutionResult({ output }), + MATERIALIZATION_CONTEXT + ) + const body = await response.json() + + expect(response.status).toBe(200) + expect(body.rows).toEqual(rows) + expect(body.success).toBeUndefined() + }) + + it('should materialize Response block manifests from an allowed source execution', async () => { + const rows = [{ key: 'SIM-1' }, { key: 'SIM-2' }] + const manifest = await createLargeArrayManifest(rows, { + ...MATERIALIZATION_CONTEXT, + executionId: 'source-execution-1', + }) + + const response = await createHttpResponseFromBlock( + buildExecutionResult({ + output: { + data: { rows: manifest }, + status: 200, + headers: {}, + }, + }), + { + ...MATERIALIZATION_CONTEXT, + largeValueExecutionIds: ['source-execution-1'], + } + ) + const body = await response.json() + + expect(body.rows).toEqual(rows) + }) + + it('should reject Response block manifests from non-source same-workflow executions', async () => { + const manifest = await createLargeArrayManifest([{ key: 'SIM-stale' }], { + ...MATERIALIZATION_CONTEXT, + executionId: 'stale-execution-1', + }) + + await expect( + createHttpResponseFromBlock( + buildExecutionResult({ + output: { + data: { rows: manifest }, + status: 200, + headers: {}, + }, + }), + { + ...MATERIALIZATION_CONTEXT, + largeValueExecutionIds: ['source-execution-1'], + } + ) + ).rejects.toThrow('Large execution value is not available in this execution') + }) + + it('should materialize Response block manifests inherited by the source snapshot', async () => { + const rows = [{ key: 'SIM-inherited' }] + const manifest = await createLargeArrayManifest(rows, { + ...MATERIALIZATION_CONTEXT, + executionId: 'original-execution-1', + }) + + const response = await createHttpResponseFromBlock( + buildExecutionResult({ + output: { + data: { rows: manifest }, + status: 200, + headers: {}, + }, + }), + { + ...MATERIALIZATION_CONTEXT, + largeValueExecutionIds: ['source-execution-1', 'original-execution-1'], + } + ) + + const body = await response.json() + + expect(body.rows).toEqual(rows) + }) + + it('should recursively materialize refs inside Response block manifest rows', async () => { + const text = 'nested'.repeat(2 * 1024 * 1024) + const nestedOutput = await compactExecutionPayload( + { text }, + { + ...MATERIALIZATION_CONTEXT, + executionId: 'original-execution-1', + requireDurable: true, + preserveRoot: true, + } + ) + const nestedRef = (nestedOutput as unknown as { text: unknown }).text + const manifest = await createLargeArrayManifest([{ nested: nestedRef }], { + ...MATERIALIZATION_CONTEXT, + executionId: 'source-execution-1', + }) + const response = await createHttpResponseFromBlock( + buildExecutionResult({ + output: { + data: { rows: manifest }, + status: 200, + headers: {}, + }, + }), + { + ...MATERIALIZATION_CONTEXT, + largeValueExecutionIds: ['source-execution-1'], + } + ) + + const body = await response.json() + + expect(body.rows).toEqual([{ nested: text }]) + }) + + it('should recursively materialize refs inside stored Response block objects', async () => { + const text = 'nested'.repeat(2 * 1024 * 1024) + const nestedOutput = await compactExecutionPayload( + { text }, + { + ...MATERIALIZATION_CONTEXT, + executionId: 'original-execution-1', + requireDurable: true, + preserveRoot: true, + } + ) + const nestedRef = (nestedOutput as unknown as { text: unknown }).text + const storedValue = { + wrapper: { + nested: nestedRef, + padding: 'x'.repeat(2048), + }, + } + const storedJson = JSON.stringify(storedValue) + const storedOutput = await storeLargeValue( + storedValue, + storedJson, + Buffer.byteLength(storedJson), + { + ...MATERIALIZATION_CONTEXT, + executionId: 'source-execution-1', + requireDurable: true, + } + ) + + const response = await createHttpResponseFromBlock( + buildExecutionResult({ + output: { + data: storedOutput, + status: 200, + headers: {}, + }, + }), + { + ...MATERIALIZATION_CONTEXT, + largeValueExecutionIds: ['source-execution-1'], + } + ) + + const body = await response.json() + + expect(body.wrapper.nested).toEqual(text) + }) + + it('should memoize repeated materialized objects while resolving nested refs', async () => { + const text = 'nested'.repeat(2 * 1024 * 1024) + const nestedOutput = await compactExecutionPayload( + { text }, + { + ...MATERIALIZATION_CONTEXT, + executionId: 'original-execution-1', + requireDurable: true, + preserveRoot: true, + } + ) + const nestedRef = (nestedOutput as unknown as { text: unknown }).text + const sourceValue = { nested: nestedRef } + const sourceJson = JSON.stringify(sourceValue) + const sourceRef = await storeLargeValue( + sourceValue, + sourceJson, + Buffer.byteLength(sourceJson), + { + ...MATERIALIZATION_CONTEXT, + executionId: 'source-execution-1', + requireDurable: true, + } + ) + + const response = await createHttpResponseFromBlock( + buildExecutionResult({ + output: { + data: { first: sourceRef, second: sourceRef }, + status: 200, + headers: {}, + }, + }), + { + ...MATERIALIZATION_CONTEXT, + largeValueKeys: sourceRef.key ? [sourceRef.key] : [], + } + ) + + const body = await response.json() + + expect(body).toEqual({ + first: { nested: text }, + second: { nested: text }, + }) + }) + + it('should materialize large string refs for Response block HTTP output', async () => { + const text = 'x'.repeat(9 * 1024 * 1024) + const output = await compactExecutionPayload( + { + data: { text }, + status: 200, + headers: {}, + }, + { + ...MATERIALIZATION_CONTEXT, + requireDurable: true, + preserveRoot: true, + } + ) + const response = await createHttpResponseFromBlock( + buildExecutionResult({ output }), + MATERIALIZATION_CONTEXT + ) + const body = await response.json() + + expect(response.status).toBe(200) + expect(body.text).toBe(text) + }) + + it('should reject Response block HTTP output that is too large to inline', async () => { + const output = await compactExecutionPayload( + { + data: { + text: 'x'.repeat(17 * 1024 * 1024), + }, + status: 200, + headers: {}, + }, + { + ...MATERIALIZATION_CONTEXT, + requireDurable: true, + preserveRoot: true, + } + ) + + await expect( + createHttpResponseFromBlock(buildExecutionResult({ output }), MATERIALIZATION_CONTEXT) + ).rejects.toMatchObject({ + code: EXECUTION_RESOURCE_LIMIT_CODE, + }) + }) }) diff --git a/apps/sim/app/api/workflows/[id]/execute/route.ts b/apps/sim/app/api/workflows/[id]/execute/route.ts index 71403444637..dc35f7b6a93 100644 --- a/apps/sim/app/api/workflows/[id]/execute/route.ts +++ b/apps/sim/app/api/workflows/[id]/execute/route.ts @@ -399,7 +399,11 @@ async function handleExecutePost( // Resolve runFromBlock snapshot from executionId if needed let resolvedRunFromBlock: - | { startBlockId: string; sourceSnapshot: SerializableExecutionState } + | { + startBlockId: string + sourceSnapshot: SerializableExecutionState + sourceExecutionId?: string + } | undefined if (rawRunFromBlock) { if (rawRunFromBlock.sourceSnapshot && auth.authType === 'api_key') { @@ -424,13 +428,16 @@ async function handleExecutePost( sourceSnapshot: rawRunFromBlock.sourceSnapshot as SerializableExecutionState, } } else if (rawRunFromBlock.executionId) { - const { getExecutionStateForWorkflow, getLatestExecutionState } = await import( - '@/lib/workflows/executor/execution-state' - ) - const snapshot = + const { getExecutionStateForWorkflow, getLatestExecutionStateWithExecutionId } = + await import('@/lib/workflows/executor/execution-state') + const sourceExecution = rawRunFromBlock.executionId === 'latest' - ? await getLatestExecutionState(workflowId) - : await getExecutionStateForWorkflow(rawRunFromBlock.executionId, workflowId) + ? await getLatestExecutionStateWithExecutionId(workflowId) + : { + executionId: rawRunFromBlock.executionId, + state: await getExecutionStateForWorkflow(rawRunFromBlock.executionId, workflowId), + } + const snapshot = sourceExecution?.state if (!snapshot) { return NextResponse.json( { @@ -442,6 +449,7 @@ async function handleExecutePost( resolvedRunFromBlock = { startBlockId: rawRunFromBlock.startBlockId, sourceSnapshot: snapshot, + sourceExecutionId: sourceExecution.executionId, } } else { return NextResponse.json( @@ -687,6 +695,12 @@ async function handleExecutePost( const effectiveWorkflowStateOverride = sanitizedWorkflowStateOverride || cachedWorkflowData || undefined + const largeValueExecutionIds = [executionId] + const largeValueKeys: string[] = [] + const fileKeys: string[] = [] + const allowLargeValueWorkflowScope = Boolean( + resolvedRunFromBlock?.sourceSnapshot && !resolvedRunFromBlock.sourceExecutionId + ) if (!enableSSE) { reqLogger.info('Using non-SSE execution (direct JSON response)') @@ -705,6 +719,10 @@ async function handleExecutePost( isClientSession, enforceCredentialAccess: useAuthenticatedUserAsActor, workflowStateOverride: effectiveWorkflowStateOverride, + largeValueExecutionIds, + largeValueKeys, + fileKeys, + allowLargeValueWorkflowScope, callChain, executionMode: 'sync', } @@ -773,20 +791,47 @@ async function handleExecutePost( ) } + const outputLargeValueKeys = result.metadata?.largeValueKeys ?? largeValueKeys + const outputFileKeys = result.metadata?.fileKeys ?? fileKeys + const outputWithBase64 = includeFileBase64 ? ((await hydrateUserFilesWithBase64(result.output, { requestId, workspaceId, workflowId, executionId, - allowLargeValueWorkflowScope: Boolean(resolvedRunFromBlock?.sourceSnapshot), + largeValueExecutionIds, + largeValueKeys: outputLargeValueKeys, + fileKeys: outputFileKeys, + allowLargeValueWorkflowScope, userId: actorUserId, maxBytes: base64MaxBytes, + preserveLargeValueMetadata: true, })) as NormalizedBlockOutput) : result.output if (auth.authType !== AuthType.INTERNAL_JWT && workflowHasResponseBlock(result)) { - return createHttpResponseFromBlock({ ...result, output: outputWithBase64 }) + const compactResponseBlockOutput = await compactRoutePayload(outputWithBase64, { + workspaceId, + workflowId, + executionId, + userId: actorUserId, + preserveUserFileBase64: true, + preserveRoot: true, + }) + return await createHttpResponseFromBlock( + { ...result, output: compactResponseBlockOutput }, + { + workspaceId, + workflowId, + executionId, + largeValueExecutionIds, + largeValueKeys: outputLargeValueKeys, + fileKeys: outputFileKeys, + userId: actorUserId, + allowLargeValueWorkflowScope, + } + ) } const compactOutput = await compactRoutePayload(outputWithBase64, { @@ -884,10 +929,13 @@ async function handleExecutePost( timeoutMs: preprocessResult.executionTimeout?.sync, }, executionId, + largeValueExecutionIds, + largeValueKeys, + fileKeys, workspaceId, workflowId, userId: actorUserId, - allowLargeValueWorkflowScope: Boolean(resolvedRunFromBlock?.sourceSnapshot), + allowLargeValueWorkflowScope, executeFn: async ({ onStream, onBlockComplete, abortSignal }) => executeWorkflow( streamWorkflow, @@ -906,6 +954,8 @@ async function handleExecutePost( base64MaxBytes, abortSignal, executionMode: 'stream', + largeValueKeys, + fileKeys, stopAfterBlockId, runFromBlock: resolvedRunFromBlock, }, @@ -1185,6 +1235,10 @@ async function handleExecutePost( isClientSession, enforceCredentialAccess: useAuthenticatedUserAsActor, workflowStateOverride: effectiveWorkflowStateOverride, + largeValueExecutionIds, + largeValueKeys, + fileKeys, + allowLargeValueWorkflowScope, callChain, executionMode: 'sync', } @@ -1309,15 +1363,22 @@ async function handleExecutePost( return } + const outputLargeValueKeys = result.metadata?.largeValueKeys ?? largeValueKeys + const outputFileKeys = result.metadata?.fileKeys ?? fileKeys + const sseOutput = includeFileBase64 ? await hydrateUserFilesWithBase64(result.output, { requestId, workspaceId, workflowId, executionId, - allowLargeValueWorkflowScope: Boolean(resolvedRunFromBlock?.sourceSnapshot), + largeValueExecutionIds, + largeValueKeys: outputLargeValueKeys, + fileKeys: outputFileKeys, + allowLargeValueWorkflowScope, userId: actorUserId, maxBytes: base64MaxBytes, + preserveLargeValueMetadata: true, }) : result.output const compactSseOutput = await compactRoutePayload(sseOutput, { diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/components/structured-output.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/components/structured-output.tsx index 3144de9d5e4..b8bb8ae022b 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/components/structured-output.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/components/structured-output.tsx @@ -15,6 +15,10 @@ import { List, type RowComponentProps, useListRef } from 'react-window' import { Badge, ChevronDown } from '@/components/emcn' import { cn } from '@/lib/core/utils/cn' import { isUserFileDisplayMetadata } from '@/lib/core/utils/user-file' +import { + isLargeArrayManifest, + type LargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest-metadata' import { isLargeValueRef, type LargeValueRef } from '@/lib/execution/payloads/large-value-ref' type ValueType = 'null' | 'undefined' | 'array' | 'string' | 'number' | 'boolean' | 'object' @@ -86,8 +90,27 @@ function getLargeValueDisplayValue(ref: LargeValueRef): unknown { return ref.preview ?? `[Large value: ${formatLargeValueSize(ref.size)}]` } +function getLargeArrayManifestDisplayValue(manifest: LargeArrayManifest): unknown[] { + const preview = manifest.preview + if (manifest.totalCount <= preview.length) { + return preview + } + + const remainingCount = manifest.totalCount - preview.length + return [ + ...preview, + `[... ${remainingCount.toLocaleString()} more item${remainingCount === 1 ? '' : 's'}]`, + ] +} + function getDisplayValue(value: unknown): unknown { - return isLargeValueRef(value) ? getLargeValueDisplayValue(value) : value + if (isLargeValueRef(value)) { + return getLargeValueDisplayValue(value) + } + if (isLargeArrayManifest(value)) { + return getLargeArrayManifestDisplayValue(value) + } + return value } function getTypeLabel(value: unknown): ValueType { diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts index 6e26e92fe81..782e00428f9 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts @@ -302,6 +302,8 @@ export function createBlockEventHandlers( updateConsole( data.blockId, { + blockName: data.blockName, + blockType: data.blockType, executionOrder: data.executionOrder, input: data.input || {}, replaceOutput: data.output, @@ -320,6 +322,8 @@ export function createBlockEventHandlers( updateConsole( data.blockId, { + blockName: data.blockName, + blockType: data.blockType, executionOrder: data.executionOrder, input: data.input || {}, replaceOutput: {}, @@ -493,6 +497,8 @@ export function reconcileFinalBlockLogs( log.blockId, { executionOrder: log.executionOrder, + blockName: log.blockName, + blockType: log.blockType, replaceOutput: (log.output ?? {}) as Record, ...(log.input ? { input: log.input } : {}), success: log.success, @@ -576,6 +582,8 @@ function spanConsoleIdentity(span: TraceSpan, childWorkflowInstanceId: string): const iterationContainerId = span.loopId ?? span.parallelId const iterationType = span.loopId ? 'loop' : span.parallelId ? 'parallel' : undefined return { + blockName: span.name, + blockType: span.type, ...(span.executionOrder !== undefined && { executionOrder: span.executionOrder }), ...(span.iterationIndex !== undefined && { iterationCurrent: span.iterationIndex }), ...(iterationType !== undefined && { iterationType }), diff --git a/apps/sim/executor/execution/block-executor.test.ts b/apps/sim/executor/execution/block-executor.test.ts new file mode 100644 index 00000000000..5e5d130c1d3 --- /dev/null +++ b/apps/sim/executor/execution/block-executor.test.ts @@ -0,0 +1,129 @@ +/** + * @vitest-environment node + */ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { clearLargeValueCacheForTests } from '@/lib/execution/payloads/cache' +import { isLargeArrayManifest } from '@/lib/execution/payloads/large-array-manifest-metadata' +import { BlockType } from '@/executor/constants' +import type { DAGNode } from '@/executor/dag/builder' +import { BlockExecutor } from '@/executor/execution/block-executor' +import { ExecutionState } from '@/executor/execution/state' +import type { BlockHandler, ExecutionContext } from '@/executor/types' +import { VariableResolver } from '@/executor/variables/resolver' +import type { SerializedBlock, SerializedWorkflow } from '@/serializer/types' + +const { mockUploadFile } = vi.hoisted(() => ({ + mockUploadFile: vi.fn(), +})) + +vi.mock('@/ee/access-control/utils/permission-check', () => ({ + validateBlockType: vi.fn(), +})) + +vi.mock('@/lib/uploads', () => ({ + StorageService: { + uploadFile: mockUploadFile, + }, +})) + +function createBlock(): SerializedBlock { + return { + id: 'function-block-1', + metadata: { id: BlockType.FUNCTION, name: 'Function' }, + position: { x: 0, y: 0 }, + config: { tool: BlockType.FUNCTION, params: {} }, + inputs: {}, + outputs: {}, + enabled: true, + } +} + +function createContext(state: ExecutionState): ExecutionContext { + return { + workflowId: 'workflow-1', + workspaceId: 'workspace-1', + executionId: 'execution-1', + userId: 'user-1', + blockStates: state.getBlockStates(), + blockLogs: [], + metadata: { requestId: 'request-1', duration: 0 }, + environmentVariables: {}, + workflowVariables: {}, + decisions: { router: new Map(), condition: new Map() }, + loopExecutions: new Map(), + executedBlocks: new Set(), + activeExecutionPath: new Set(), + completedLoops: new Set(), + } as ExecutionContext +} + +function createNode(block: SerializedBlock): DAGNode { + return { + id: block.id, + block, + incomingEdges: new Set(), + outgoingEdges: new Map(), + metadata: {}, + } +} + +describe('BlockExecutor', () => { + beforeEach(() => { + vi.clearAllMocks() + clearLargeValueCacheForTests() + mockUploadFile.mockImplementation(async ({ customKey }) => ({ key: customKey })) + }) + + it('persists function output arrays as manifests in execution state', async () => { + const block = createBlock() + const workflow: SerializedWorkflow = { + version: '1', + blocks: [block], + connections: [], + loops: {}, + parallels: {}, + } + const state = new ExecutionState() + const resolver = new VariableResolver(workflow, {}, state) + const output = { + result: Array.from({ length: 120_000 }, (_, index) => ({ + key: `SIM-${index}`, + payload: 'x'.repeat(100), + })), + } + const handler: BlockHandler = { + canHandle: () => true, + execute: async () => output, + } + const executor = new BlockExecutor( + [handler], + resolver, + { + workspaceId: 'workspace-1', + executionId: 'execution-1', + userId: 'user-1', + metadata: { + requestId: 'request-1', + executionId: 'execution-1', + workflowId: 'workflow-1', + workspaceId: 'workspace-1', + userId: 'user-1', + triggerType: 'manual', + useDraftState: false, + startTime: new Date().toISOString(), + }, + }, + state + ) + + await executor.execute(createContext(state), createNode(block), block) + + const storedOutput = state.getBlockOutput(block.id) + expect(isLargeArrayManifest(storedOutput?.result)).toBe(true) + expect(storedOutput?.result).toMatchObject({ + __simLargeArrayManifest: true, + kind: 'array', + totalCount: output.result.length, + }) + }) +}) diff --git a/apps/sim/executor/execution/block-executor.ts b/apps/sim/executor/execution/block-executor.ts index a8fd36c63a7..88aa9b20461 100644 --- a/apps/sim/executor/execution/block-executor.ts +++ b/apps/sim/executor/execution/block-executor.ts @@ -202,9 +202,12 @@ export class BlockExecutor { workflowId: ctx.workflowId, executionId: ctx.executionId, largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + fileKeys: ctx.fileKeys, allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, userId: ctx.userId, maxBytes: ctx.base64MaxBytes, + preserveLargeValueMetadata: true, })) as NormalizedBlockOutput } diff --git a/apps/sim/executor/execution/executor.ts b/apps/sim/executor/execution/executor.ts index 4866ebeba81..0d4fb5364c4 100644 --- a/apps/sim/executor/execution/executor.ts +++ b/apps/sim/executor/execution/executor.ts @@ -1,6 +1,9 @@ import { createLogger, type Logger } from '@sim/logger' import { normalizeStringArray } from '@/lib/core/utils/arrays' import { normalizeStringRecord, normalizeWorkflowVariables } from '@/lib/core/utils/records' +import { collectUserFileKeys } from '@/lib/core/utils/user-file' +import { mergeFileKeys, mergeLargeValueKeys } from '@/lib/execution/payloads/access-keys' +import { collectLargeValueKeys } from '@/lib/execution/payloads/large-execution-value' import { StartBlockPath } from '@/lib/workflows/triggers/triggers' import type { DAG } from '@/executor/dag/builder' import { DAGBuilder } from '@/executor/dag/builder' @@ -210,10 +213,27 @@ export class DAGExecutor { snapshotState: filteredSnapshot, runFromBlockContext, }) + const filteredLargeValueKeys = collectLargeValueKeys({ + blockStates: filteredBlockStates, + loopExecutions: filteredLoopExecutions, + parallelExecutions: filteredParallelExecutions, + }) + mergeLargeValueKeys(context, filteredLargeValueKeys) + const filteredFileKeys = collectUserFileKeys({ + blockStates: filteredBlockStates, + loopExecutions: filteredLoopExecutions, + parallelExecutions: filteredParallelExecutions, + }) + mergeFileKeys(context, filteredFileKeys) context.subflowParentMap = this.buildSubflowParentMap(dag) const engine = this.buildExecutionPipeline(context, dag, state) - return await engine.run() + const result = await engine.run() + if (result.metadata) { + result.metadata.largeValueKeys = context.largeValueKeys + result.metadata.fileKeys = context.fileKeys + } + return result } private restoreSavedIncomingEdges(dag: DAG, savedIncomingEdges?: Record): void { @@ -313,6 +333,8 @@ export class DAGExecutor { workspaceId: this.contextExtensions.workspaceId, executionId: this.contextExtensions.executionId, largeValueExecutionIds: this.contextExtensions.largeValueExecutionIds, + largeValueKeys: this.contextExtensions.largeValueKeys, + fileKeys: this.contextExtensions.fileKeys, allowLargeValueWorkflowScope: this.contextExtensions.allowLargeValueWorkflowScope, userId: this.contextExtensions.userId, isDeployedContext: this.contextExtensions.isDeployedContext, diff --git a/apps/sim/executor/execution/snapshot-serializer.test.ts b/apps/sim/executor/execution/snapshot-serializer.test.ts index 9aa273d2bbd..ffd53b32772 100644 --- a/apps/sim/executor/execution/snapshot-serializer.test.ts +++ b/apps/sim/executor/execution/snapshot-serializer.test.ts @@ -1,7 +1,7 @@ /** * @vitest-environment node */ -import { describe, expect, it } from 'vitest' +import { describe, expect, it, vi } from 'vitest' import { serializePauseSnapshot } from '@/executor/execution/snapshot-serializer' import type { ExecutionContext } from '@/executor/types' @@ -67,4 +67,26 @@ describe('serializePauseSnapshot', () => { }, }) }) + + it('rejects oversized snapshot values without full JSON serialization', () => { + const stringifySpy = vi.spyOn(JSON, 'stringify').mockImplementation(() => { + throw new Error('full stringify should not be used for compactness checks') + }) + const context = createContext({ + workflowVariables: { + oversized: { + type: 'string', + value: 'x'.repeat(9 * 1024 * 1024), + }, + }, + }) + + try { + expect(() => serializePauseSnapshot(context, ['next-block'])).toThrow( + 'Cannot serialize pause snapshot with oversized workflow variables' + ) + } finally { + stringifySpy.mockRestore() + } + }) }) diff --git a/apps/sim/executor/execution/snapshot-serializer.ts b/apps/sim/executor/execution/snapshot-serializer.ts index fbac5b893c2..1c63f9d98c4 100644 --- a/apps/sim/executor/execution/snapshot-serializer.ts +++ b/apps/sim/executor/execution/snapshot-serializer.ts @@ -1,8 +1,136 @@ +import { LARGE_VALUE_THRESHOLD_BYTES } from '@/lib/execution/payloads/large-value-ref' import type { DAG } from '@/executor/dag/builder' import { ExecutionSnapshot } from '@/executor/execution/snapshot' import type { ExecutionMetadata, SerializableExecutionState } from '@/executor/execution/types' import type { ExecutionContext, SerializedSnapshot } from '@/executor/types' +const JSON_SYNTAX_BYTES = { + QUOTE: 1, + COLON: 1, + COMMA: 1, + ARRAY_BRACKETS: 2, + OBJECT_BRACES: 2, + NULL: 4, +} as const + +function getEscapedJsonStringByteLength(value: string): number { + let bytes = JSON_SYNTAX_BYTES.QUOTE * 2 + for (let index = 0; index < value.length; index++) { + const code = value.charCodeAt(index) + if (code === 0x22 || code === 0x5c) { + bytes += 2 + } else if (code === 0x08 || code === 0x09 || code === 0x0a || code === 0x0c || code === 0x0d) { + bytes += 2 + } else if (code < 0x20) { + bytes += 6 + } else if (code >= 0xd800 && code <= 0xdbff) { + const next = value.charCodeAt(index + 1) + if (next >= 0xdc00 && next <= 0xdfff) { + bytes += 4 + index++ + } else { + bytes += 6 + } + } else if (code >= 0xdc00 && code <= 0xdfff) { + bytes += 6 + } else if (code < 0x80) { + bytes += 1 + } else if (code < 0x800) { + bytes += 2 + } else { + bytes += 3 + } + } + return bytes +} + +function getPrimitiveJsonByteLength(value: unknown): number | undefined { + if (value === null) { + return JSON_SYNTAX_BYTES.NULL + } + if (typeof value === 'string') { + return getEscapedJsonStringByteLength(value) + } + if (typeof value === 'number') { + return Number.isFinite(value) + ? Buffer.byteLength(String(value), 'utf8') + : JSON_SYNTAX_BYTES.NULL + } + if (typeof value === 'boolean') { + return value ? 4 : 5 + } + if (typeof value === 'bigint') { + throw new TypeError('Do not know how to serialize a BigInt') + } + return undefined +} + +function getBoundedJsonByteLength( + value: unknown, + maxBytes: number, + seen = new WeakSet() +): number | undefined { + const primitiveSize = getPrimitiveJsonByteLength(value) + if (primitiveSize !== undefined) { + return primitiveSize + } + + if (value === undefined || typeof value === 'function' || typeof value === 'symbol') { + return undefined + } + + if (!value || typeof value !== 'object') { + return undefined + } + + if (seen.has(value)) { + throw new TypeError('Converting circular structure to JSON') + } + seen.add(value) + + let bytes = Array.isArray(value) + ? JSON_SYNTAX_BYTES.ARRAY_BRACKETS + : JSON_SYNTAX_BYTES.OBJECT_BRACES + if (Array.isArray(value)) { + for (let index = 0; index < value.length; index++) { + if (index > 0) bytes += JSON_SYNTAX_BYTES.COMMA + const itemSize = getBoundedJsonByteLength(value[index], maxBytes - bytes, seen) + bytes += itemSize ?? JSON_SYNTAX_BYTES.NULL + if (bytes > maxBytes) return bytes + } + seen.delete(value) + return bytes + } + + let hasEntries = false + for (const key of Object.keys(value)) { + const entryValue = (value as Record)[key] + if ( + entryValue === undefined || + typeof entryValue === 'function' || + typeof entryValue === 'symbol' + ) { + continue + } + if (hasEntries) bytes += JSON_SYNTAX_BYTES.COMMA + bytes += getEscapedJsonStringByteLength(key) + JSON_SYNTAX_BYTES.COLON + const entrySize = getBoundedJsonByteLength(entryValue, maxBytes - bytes, seen) + bytes += entrySize ?? JSON_SYNTAX_BYTES.NULL + hasEntries = true + if (bytes > maxBytes) return bytes + } + + seen.delete(value) + return bytes +} + +function assertSnapshotValueIsCompact(value: unknown, label: string): void { + const byteLength = getBoundedJsonByteLength(value, LARGE_VALUE_THRESHOLD_BYTES) + if (byteLength !== undefined && byteLength > LARGE_VALUE_THRESHOLD_BYTES) { + throw new Error(`Cannot serialize pause snapshot with oversized ${label}; compact it first.`) + } +} + function mapFromEntries(map?: Map): Record | undefined { if (!map) return undefined return Object.fromEntries(map) @@ -94,6 +222,9 @@ export function serializePauseSnapshot( dagIncomingEdges, } + assertSnapshotValueIsCompact(context.workflowVariables, 'workflow variables') + assertSnapshotValueIsCompact(state.loopExecutions, 'loop execution state') + const workspaceId = metadataFromContext?.workspaceId ?? context.workspaceId if (!workspaceId) { throw new Error( diff --git a/apps/sim/executor/execution/types.ts b/apps/sim/executor/execution/types.ts index 0180d9e0ad7..0f80918b1ef 100644 --- a/apps/sim/executor/execution/types.ts +++ b/apps/sim/executor/execution/types.ts @@ -36,6 +36,8 @@ export interface ExecutionMetadata { deploymentVersionId?: string } largeValueExecutionIds?: string[] + largeValueKeys?: string[] + fileKeys?: string[] allowLargeValueWorkflowScope?: boolean callChain?: string[] correlation?: AsyncExecutionCorrelation @@ -146,6 +148,8 @@ export interface ContextExtensions { workspaceId?: string executionId?: string largeValueExecutionIds?: string[] + largeValueKeys?: string[] + fileKeys?: string[] allowLargeValueWorkflowScope?: boolean userId?: string stream?: boolean diff --git a/apps/sim/executor/handlers/agent/agent-handler.ts b/apps/sim/executor/handlers/agent/agent-handler.ts index 9c6a23e2330..b9c3a3eaad8 100644 --- a/apps/sim/executor/handlers/agent/agent-handler.ts +++ b/apps/sim/executor/handlers/agent/agent-handler.ts @@ -755,6 +755,8 @@ export class AgentBlockHandler implements BlockHandler { workflowId: ctx.workflowId, executionId: ctx.executionId, largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + fileKeys: ctx.fileKeys, allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, userId: ctx.userId, logger, diff --git a/apps/sim/executor/handlers/function/function-handler.ts b/apps/sim/executor/handlers/function/function-handler.ts index c22205212e3..d08ff8aca44 100644 --- a/apps/sim/executor/handlers/function/function-handler.ts +++ b/apps/sim/executor/handlers/function/function-handler.ts @@ -5,6 +5,7 @@ import { } from '@/lib/core/utils/records' import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants' import { DEFAULT_CODE_LANGUAGE } from '@/lib/execution/languages' +import { mergeFileKeys, mergeLargeValueKeys } from '@/lib/execution/payloads/access-keys' import { BlockType } from '@/executor/constants' import type { BlockHandler, ExecutionContext } from '@/executor/types' import { collectBlockData } from '@/executor/utils/block-data' @@ -69,6 +70,8 @@ export class FunctionBlockHandler implements BlockHandler { workspaceId: ctx.workspaceId, executionId: ctx.executionId, largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + fileKeys: ctx.fileKeys, allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, userId: ctx.userId, isDeployedContext: ctx.isDeployedContext, @@ -82,6 +85,9 @@ export class FunctionBlockHandler implements BlockHandler { throw new Error(result.error || 'Function execution failed') } + mergeLargeValueKeys(ctx, result.largeValueKeys ?? []) + mergeFileKeys(ctx, result.fileKeys ?? []) + return result.output } } diff --git a/apps/sim/executor/handlers/mothership/mothership-handler.ts b/apps/sim/executor/handlers/mothership/mothership-handler.ts index 4fc5b58e0d0..60e2873f0ae 100644 --- a/apps/sim/executor/handlers/mothership/mothership-handler.ts +++ b/apps/sim/executor/handlers/mothership/mothership-handler.ts @@ -298,6 +298,8 @@ async function buildMothershipFileAttachments( workflowId: ctx.workflowId, executionId: ctx.executionId, largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + fileKeys: ctx.fileKeys, allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, requestId, logger, diff --git a/apps/sim/executor/handlers/variables/variables-handler.test.ts b/apps/sim/executor/handlers/variables/variables-handler.test.ts new file mode 100644 index 00000000000..086d5bf5cf0 --- /dev/null +++ b/apps/sim/executor/handlers/variables/variables-handler.test.ts @@ -0,0 +1,296 @@ +/** + * @vitest-environment node + */ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { clearLargeValueCacheForTests } from '@/lib/execution/payloads/cache' +import { isLargeArrayManifest } from '@/lib/execution/payloads/large-array-manifest-metadata' +import { BlockType } from '@/executor/constants' +import { VariablesBlockHandler } from '@/executor/handlers/variables/variables-handler' +import type { ExecutionContext } from '@/executor/types' +import type { SerializedBlock } from '@/serializer/types' + +const { mockUploadFile } = vi.hoisted(() => ({ + mockUploadFile: vi.fn(), +})) + +vi.mock('@/lib/uploads', () => ({ + StorageService: { + uploadFile: mockUploadFile, + }, +})) + +function createContext(overrides: Partial = {}): ExecutionContext { + return { + workflowId: 'workflow-1', + workspaceId: 'workspace-1', + executionId: 'execution-1', + userId: 'user-1', + blockStates: new Map(), + blockLogs: [], + metadata: { duration: 0 }, + environmentVariables: {}, + workflowVariables: { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: [] }, + }, + decisions: { router: new Map(), condition: new Map() }, + loopExecutions: new Map(), + executedBlocks: new Set(), + activeExecutionPath: new Set(), + completedLoops: new Set(), + ...overrides, + } +} + +function createBlock(): SerializedBlock { + return { + id: 'variables-block-1', + metadata: { id: BlockType.VARIABLES, name: 'Variables' }, + position: { x: 0, y: 0 }, + config: { tool: BlockType.VARIABLES, params: {} }, + inputs: {}, + outputs: {}, + enabled: true, + } +} + +describe('VariablesBlockHandler', () => { + beforeEach(() => { + vi.clearAllMocks() + clearLargeValueCacheForTests() + mockUploadFile.mockImplementation(async ({ customKey }) => ({ key: customKey })) + }) + + it('preserves small assignments inline', async () => { + const handler = new VariablesBlockHandler() + const ctx = createContext() + const value = [{ key: 'SIM-1', summary: 'Small issue' }] + + const output = await handler.execute(ctx, createBlock(), { + variables: [ + { + variableId: 'var-1', + variableName: 'issues', + type: 'array', + value, + }, + ], + }) + + expect(ctx.workflowVariables?.['var-1'].value).toEqual(value) + expect(output).toEqual({ issues: value }) + expect(mockUploadFile).not.toHaveBeenCalled() + }) + + it('includes unmatched assignments in block output without mutating workflow variables', async () => { + const handler = new VariablesBlockHandler() + const ctx = createContext() + const value = [{ key: 'SIM-1', summary: 'Transient issue' }] + + const output = await handler.execute(ctx, createBlock(), { + variables: [ + { + variableName: 'transientIssues', + type: 'array', + value, + }, + ], + }) + + expect(ctx.workflowVariables).not.toHaveProperty('transientIssues') + expect(output).toEqual({ transientIssues: value }) + }) + + it('keeps special unmatched assignment names as own output fields', async () => { + const handler = new VariablesBlockHandler() + const ctx = createContext() + const value = { polluted: true } + + const output = await handler.execute(ctx, createBlock(), { + variables: [ + { + variableName: '__proto__', + type: 'object', + value, + }, + ], + }) + + expect(Object.hasOwn(output, '__proto__')).toBe(true) + expect(output.__proto__).toEqual(value) + expect(Object.getPrototypeOf(output)).toBe(Object.prototype) + }) + + it('does not treat inherited prototype keys as existing workflow variable IDs', async () => { + const handler = new VariablesBlockHandler() + const ctx = createContext() + const value = { safe: true } + const originalPrototype = Object.getPrototypeOf(ctx.workflowVariables) + + const output = await handler.execute(ctx, createBlock(), { + variables: [ + { + variableId: '__proto__', + variableName: 'prototypeAssignment', + type: 'object', + value, + }, + ], + }) + + expect(Object.getPrototypeOf(ctx.workflowVariables)).toBe(originalPrototype) + expect(ctx.workflowVariables).not.toHaveProperty('__proto__') + expect(output).toEqual({ prototypeAssignment: value }) + }) + + it('stores oversized array assignments as durable manifests in variables and block output', async () => { + const handler = new VariablesBlockHandler() + const ctx = createContext() + const value = Array.from({ length: 120_000 }, (_, index) => ({ + key: `SIM-${index}`, + summary: 'Issue summary that keeps each item small', + })) + + const output = await handler.execute(ctx, createBlock(), { + variables: [ + { + variableId: 'var-1', + variableName: 'issues', + type: 'array', + value, + }, + ], + }) + + const storedValue = ctx.workflowVariables?.['var-1'].value + expect(isLargeArrayManifest(storedValue)).toBe(true) + expect(output.issues).toBe(storedValue) + expect(storedValue).toMatchObject({ + __simLargeArrayManifest: true, + kind: 'array', + totalCount: value.length, + }) + expect(storedValue.chunkCount).toBeGreaterThan(1) + expect(mockUploadFile).toHaveBeenCalledWith( + expect.objectContaining({ + context: 'execution', + preserveKey: true, + customKey: expect.stringContaining('/execution-1/large-value-'), + }) + ) + }) + + it('fails clearly when durable context is missing for oversized assignments', async () => { + const handler = new VariablesBlockHandler() + const ctx = createContext({ workspaceId: undefined, executionId: undefined }) + const value = Array.from({ length: 120_000 }, (_, index) => ({ + key: `SIM-${index}`, + summary: 'Issue summary that keeps each item small', + })) + + await expect( + handler.execute(ctx, createBlock(), { + variables: [ + { + variableId: 'var-1', + variableName: 'issues', + type: 'array', + value, + }, + ], + }) + ).rejects.toThrow( + 'Cannot persist large execution value without workspace, workflow, and execution IDs' + ) + + expect(mockUploadFile).not.toHaveBeenCalled() + }) + + it('preserves whole large refs before scalar type coercion', async () => { + const handler = new VariablesBlockHandler() + const ref = { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'object', + size: 12 * 1024 * 1024, + executionId: 'execution-1', + } + const ctx = createContext({ + workflowVariables: { + stringVar: { id: 'stringVar', name: 'stringRef', type: 'string', value: '' }, + plainVar: { id: 'plainVar', name: 'plainRef', type: 'plain', value: '' }, + numberVar: { id: 'numberVar', name: 'numberRef', type: 'number', value: 0 }, + booleanVar: { id: 'booleanVar', name: 'booleanRef', type: 'boolean', value: false }, + }, + }) + + await handler.execute(ctx, createBlock(), { + variables: [ + { + variableId: 'stringVar', + variableName: 'stringRef', + type: 'string', + value: JSON.stringify(ref), + }, + { + variableId: 'plainVar', + variableName: 'plainRef', + type: 'plain', + value: JSON.stringify(ref), + }, + { + variableId: 'numberVar', + variableName: 'numberRef', + type: 'number', + value: JSON.stringify(ref), + }, + { + variableId: 'booleanVar', + variableName: 'booleanRef', + type: 'boolean', + value: JSON.stringify(ref), + }, + ], + }) + + expect(ctx.workflowVariables?.stringVar.value).toEqual(ref) + expect(ctx.workflowVariables?.plainVar.value).toEqual(ref) + expect(ctx.workflowVariables?.numberVar.value).toEqual(ref) + expect(ctx.workflowVariables?.booleanVar.value).toEqual(ref) + }) + + it('preserves existing variable metadata when compacting reassignment', async () => { + const handler = new VariablesBlockHandler() + const ctx = createContext({ + workflowVariables: { + 'var-1': { + id: 'var-1', + name: 'issues', + type: 'array', + value: [], + isExisting: true, + }, + }, + }) + const value = [{ key: 'SIM-1', summary: 'Updated' }] + + await handler.execute(ctx, createBlock(), { + variables: [ + { + variableId: 'var-1', + variableName: 'issues', + type: 'array', + value, + }, + ], + }) + + expect(ctx.workflowVariables?.['var-1']).toEqual({ + id: 'var-1', + name: 'issues', + type: 'array', + value, + isExisting: true, + }) + }) +}) diff --git a/apps/sim/executor/handlers/variables/variables-handler.ts b/apps/sim/executor/handlers/variables/variables-handler.ts index 93579682f9c..2634ae141c1 100644 --- a/apps/sim/executor/handlers/variables/variables-handler.ts +++ b/apps/sim/executor/handlers/variables/variables-handler.ts @@ -1,4 +1,7 @@ import { createLogger } from '@sim/logger' +import { toError } from '@sim/utils/errors' +import { parseLargeExecutionValue } from '@/lib/execution/payloads/large-execution-value' +import { compactWorkflowVariableValue } from '@/lib/execution/payloads/serializer' import type { BlockOutput } from '@/blocks/types' import { BlockType } from '@/executor/constants' import type { BlockHandler, ExecutionContext } from '@/executor/types' @@ -6,6 +9,38 @@ import type { SerializedBlock } from '@/serializer/types' const logger = createLogger('VariablesBlockHandler') +function setOutputValue(output: Record, key: string, value: any): void { + Object.defineProperty(output, key, { + value, + enumerable: true, + configurable: true, + writable: true, + }) +} + +function getWorkflowVariableEntry( + workflowVariables: Record, + variableId: string | undefined +): [string, any] | undefined { + if (!variableId || !Object.hasOwn(workflowVariables, variableId)) { + return undefined + } + return [variableId, workflowVariables[variableId]] +} + +function setWorkflowVariableEntry( + workflowVariables: Record, + id: string, + value: any +): void { + Object.defineProperty(workflowVariables, id, { + value, + enumerable: true, + configurable: true, + writable: true, + }) +} + export class VariablesBlockHandler implements BlockHandler { canHandle(block: SerializedBlock): boolean { const canHandle = block.metadata?.id === BlockType.VARIABLES @@ -24,36 +59,46 @@ export class VariablesBlockHandler implements BlockHandler { const assignments = this.parseAssignments(inputs.variables) + const output: Record = {} + for (const assignment of assignments) { - const existingEntry = assignment.variableId - ? [assignment.variableId, ctx.workflowVariables[assignment.variableId]] - : Object.entries(ctx.workflowVariables).find( - ([_, v]) => v.name === assignment.variableName - ) + const existingEntry = + getWorkflowVariableEntry(ctx.workflowVariables, assignment.variableId) ?? + Object.entries(ctx.workflowVariables).find(([_, v]) => v.name === assignment.variableName) + const value = await this.compactAssignmentValue(ctx, assignment.value) if (existingEntry?.[1]) { const [id, variable] = existingEntry - ctx.workflowVariables[id] = { + setWorkflowVariableEntry(ctx.workflowVariables, id, { ...variable, - value: assignment.value, - } + value, + }) } else { logger.warn(`Variable "${assignment.variableName}" not found in workflow variables`) } - } - - const output: Record = {} - for (const assignment of assignments) { - output[assignment.variableName] = assignment.value + setOutputValue(output, assignment.variableName, value) } return output - } catch (error: any) { - logger.error('Variables block execution failed:', error) - throw new Error(`Variables block execution failed: ${error.message}`) + } catch (error) { + const normalizedError = toError(error) + logger.error('Variables block execution failed:', normalizedError) + throw new Error(`Variables block execution failed: ${normalizedError.message}`) } } + private async compactAssignmentValue(ctx: ExecutionContext, value: any): Promise { + return compactWorkflowVariableValue(value, { + workspaceId: ctx.workspaceId, + workflowId: ctx.workflowId, + executionId: ctx.executionId, + userId: ctx.userId, + largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, + }) + } + private parseAssignments( assignmentsInput: any ): Array<{ variableId?: string; variableName: string; type: string; value: any }> { @@ -83,6 +128,11 @@ export class VariablesBlockHandler implements BlockHandler { } private parseValueByType(value: any, type: string, variableName?: string): any { + const refValue = parseLargeExecutionValue(value) + if (refValue !== undefined) { + return refValue + } + if (value === null || value === undefined || value === '') { if (type === 'number') return 0 if (type === 'boolean') return false diff --git a/apps/sim/executor/orchestrators/loop.test.ts b/apps/sim/executor/orchestrators/loop.test.ts new file mode 100644 index 00000000000..bd6ddd83c86 --- /dev/null +++ b/apps/sim/executor/orchestrators/loop.test.ts @@ -0,0 +1,150 @@ +/** + * @vitest-environment node + */ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { clearLargeValueCacheForTests } from '@/lib/execution/payloads/cache' +import { isLargeArrayManifest } from '@/lib/execution/payloads/large-array-manifest-metadata' +import { EDGE } from '@/executor/constants' +import { LoopOrchestrator } from '@/executor/orchestrators/loop' +import type { ExecutionContext } from '@/executor/types' + +const { mockUploadFile } = vi.hoisted(() => ({ + mockUploadFile: vi.fn(), +})) + +vi.mock('@/lib/uploads', () => ({ + StorageService: { + uploadFile: mockUploadFile, + }, +})) + +function createContext(scope: Record): ExecutionContext { + return { + workflowId: 'workflow-1', + workspaceId: 'workspace-1', + executionId: 'execution-1', + userId: 'user-1', + blockStates: new Map(), + executedBlocks: new Set(), + blockLogs: [], + metadata: { requestId: 'request-1' }, + environmentVariables: {}, + workflowVariables: {}, + decisions: { router: new Map(), condition: new Map() }, + completedLoops: new Set(), + activeExecutionPath: new Set(), + loopExecutions: new Map([['loop-1', scope as any]]), + } as ExecutionContext +} + +function createOrchestrator(loopConfigs = new Map()) { + const setBlockOutput = vi.fn() + const orchestrator = new LoopOrchestrator( + { loopConfigs, parallelConfigs: new Map(), nodes: new Map() } as any, + { setBlockOutput, unmarkExecuted: vi.fn() } as any, + { resolveSingleReference: vi.fn() } as any + ) + return { orchestrator, setBlockOutput } +} + +describe('LoopOrchestrator', () => { + beforeEach(() => { + vi.clearAllMocks() + clearLargeValueCacheForTests() + mockUploadFile.mockImplementation(async ({ customKey }) => ({ key: customKey })) + }) + + it('exits doWhile loops when the configured iteration cap is reached', async () => { + const { orchestrator } = createOrchestrator() + const ctx = createContext({ + iteration: 4, + maxIterations: 5, + loopType: 'doWhile', + condition: 'true', + currentIterationOutputs: new Map([['block-1', { result: 'done' }]]), + allIterationOutputs: [], + }) + + const result = await orchestrator.evaluateLoopContinuation(ctx, 'loop-1') + + expect(result).toMatchObject({ + shouldContinue: false, + shouldExit: true, + selectedRoute: EDGE.LOOP_EXIT, + totalIterations: 1, + }) + }) + + it('does not treat doWhile iterations of zero as an immediate configured cap', async () => { + const { orchestrator } = createOrchestrator( + new Map([ + [ + 'loop-1', + { + loopType: 'doWhile', + iterations: 0, + doWhileCondition: 'true', + nodes: ['block-1'], + }, + ], + ]) + ) + const ctx = createContext({}) + + const scope = await orchestrator.initializeLoopScope(ctx, 'loop-1') + + expect(scope.maxIterations).toBeUndefined() + expect(scope.condition).toBe('true') + }) + + it('keeps doWhile condition semantics when iterations are also configured', async () => { + const { orchestrator } = createOrchestrator( + new Map([ + [ + 'loop-1', + { + loopType: 'doWhile', + iterations: 2, + doWhileCondition: 'true', + nodes: ['block-1'], + }, + ], + ]) + ) + const ctx = createContext({}) + + const scope = await orchestrator.initializeLoopScope(ctx, 'loop-1') + + expect(scope.maxIterations).toBeUndefined() + expect(scope.condition).toBe('true') + }) + + it('compacts current iteration outputs before retaining them', async () => { + const { orchestrator, setBlockOutput } = createOrchestrator() + const ctx = createContext({ + iteration: 0, + maxIterations: 1, + loopType: 'doWhile', + condition: 'true', + currentIterationOutputs: new Map([ + [ + 'block-1', + { + result: Array.from({ length: 200_000 }, (_, index) => ({ + id: index, + summary: 'Issue summary that keeps each item small', + })), + }, + ], + ]), + allIterationOutputs: [], + }) + + await orchestrator.evaluateLoopContinuation(ctx, 'loop-1') + + const output = setBlockOutput.mock.calls[0][1] + expect(Array.isArray(output.results[0])).toBe(true) + expect(isLargeArrayManifest(output.results[0][0].result)).toBe(true) + expect(output.results[0][0].result.totalCount).toBe(200_000) + }) +}) diff --git a/apps/sim/executor/orchestrators/loop.ts b/apps/sim/executor/orchestrators/loop.ts index 2087bf09c45..02ec0d9a73a 100644 --- a/apps/sim/executor/orchestrators/loop.ts +++ b/apps/sim/executor/orchestrators/loop.ts @@ -22,8 +22,8 @@ import { emitEmptySubflowEvents, emitSubflowSuccessEvents, extractBaseBlockId, - resolveArrayInputAsync, } from '@/executor/utils/subflow-utils' +import { resolveArrayInputAsync } from '@/executor/utils/subflow-utils.server' import type { VariableResolver } from '@/executor/variables/resolver' import type { SerializedLoop } from '@/serializer/types' @@ -249,11 +249,25 @@ export class LoopOrchestrator { } if (iterationResults.length > 0) { - scope.allIterationOutputs.push(iterationResults) + const compactedIterationResults = await compactSubflowResults(iterationResults, { + workspaceId: ctx.workspaceId, + workflowId: ctx.workflowId, + executionId: ctx.executionId, + largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, + userId: ctx.userId, + requireDurable: true, + }) + scope.allIterationOutputs.push(compactedIterationResults) } scope.currentIterationOutputs.clear() + if (this.hasReachedConfiguredIterationLimit(scope, scope.iteration + 1)) { + return await this.createExitResult(ctx, loopId, scope) + } + if (!(await this.evaluateCondition(ctx, scope, scope.iteration + 1))) { return await this.createExitResult(ctx, loopId, scope) } @@ -271,6 +285,13 @@ export class LoopOrchestrator { } } + private hasReachedConfiguredIterationLimit(scope: LoopScope, nextIteration: number): boolean { + if (scope.loopType !== 'doWhile' || scope.maxIterations === undefined) { + return false + } + return nextIteration >= scope.maxIterations + } + private async createExitResult( ctx: ExecutionContext, loopId: string, @@ -282,6 +303,9 @@ export class LoopOrchestrator { workspaceId: ctx.workspaceId, workflowId: ctx.workflowId, executionId: ctx.executionId, + largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, userId: ctx.userId, requireDurable: true, }) @@ -651,14 +675,14 @@ export class LoopOrchestrator { logger.info('Evaluating loop condition', { originalCondition: condition, iteration: scope.iteration, - workflowVariables: ctx.workflowVariables, + workflowVariableCount: Object.keys(ctx.workflowVariables ?? {}).length, }) const evaluatedCondition = await replaceLoopConditionReferences(condition, async (match) => { const resolved = await this.resolver.resolveSingleReference(ctx, '', match, scope) logger.debug('Resolved variable reference in loop condition', { reference: match, - resolvedValue: resolved, + resolvedType: resolved === null ? 'null' : typeof resolved, }) if (resolved !== undefined) { if (typeof resolved === 'boolean' || typeof resolved === 'number') { diff --git a/apps/sim/executor/orchestrators/parallel.ts b/apps/sim/executor/orchestrators/parallel.ts index aa9d0ad8c6e..36e5b124589 100644 --- a/apps/sim/executor/orchestrators/parallel.ts +++ b/apps/sim/executor/orchestrators/parallel.ts @@ -13,8 +13,8 @@ import { emitEmptySubflowEvents, emitSubflowSuccessEvents, extractBranchIndex, - resolveArrayInputAsync, } from '@/executor/utils/subflow-utils' +import { resolveArrayInputAsync } from '@/executor/utils/subflow-utils.server' import type { VariableResolver } from '@/executor/variables/resolver' import type { SerializedParallel } from '@/serializer/types' @@ -350,6 +350,9 @@ export class ParallelOrchestrator { workspaceId: ctx.workspaceId, workflowId: ctx.workflowId, executionId: ctx.executionId, + largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, userId: ctx.userId, requireDurable: true, }) @@ -377,6 +380,9 @@ export class ParallelOrchestrator { workspaceId: ctx.workspaceId, workflowId: ctx.workflowId, executionId: ctx.executionId, + largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, userId: ctx.userId, requireDurable: true, }) diff --git a/apps/sim/executor/types.ts b/apps/sim/executor/types.ts index d2569706085..ba6e80983f7 100644 --- a/apps/sim/executor/types.ts +++ b/apps/sim/executor/types.ts @@ -265,6 +265,8 @@ interface ExecutionMetadata { context?: ExecutionContext workflowConnections?: Array<{ source: string; target: string }> credentialAccountUserId?: string + largeValueKeys?: string[] + fileKeys?: string[] status?: 'running' | 'paused' | 'completed' pausePoints?: string[] resumeChain?: { @@ -291,6 +293,8 @@ export interface ExecutionContext { workspaceId?: string executionId?: string largeValueExecutionIds?: string[] + largeValueKeys?: string[] + fileKeys?: string[] allowLargeValueWorkflowScope?: boolean userId?: string isDeployedContext?: boolean diff --git a/apps/sim/executor/utils/output-filter.test.ts b/apps/sim/executor/utils/output-filter.test.ts new file mode 100644 index 00000000000..9ef7b0fe9cd --- /dev/null +++ b/apps/sim/executor/utils/output-filter.test.ts @@ -0,0 +1,42 @@ +/** + * @vitest-environment node + */ +import { describe, expect, it, vi } from 'vitest' +import { filterHiddenOutputKeys } from '@/lib/logs/execution/trace-spans/trace-spans' +import { filterOutputForLog } from '@/executor/utils/output-filter' + +vi.mock('@/blocks', () => ({ + getBlock: () => undefined, +})) + +describe('output filtering', () => { + it('preserves special top-level output keys as own fields', () => { + const rawOutput: Record = {} + Object.defineProperty(rawOutput, 'constructor', { + value: { safe: true }, + enumerable: true, + }) + + const output = filterOutputForLog('', rawOutput) + + expect(Object.hasOwn(output, 'constructor')).toBe(true) + expect(output.constructor).toEqual({ safe: true }) + expect(Object.getPrototypeOf(output)).toBe(Object.prototype) + }) + + it('preserves special nested output keys as own fields', () => { + const nested: Record = {} + Object.defineProperty(nested, '__proto__', { + value: { safe: true }, + enumerable: true, + }) + + const filtered = filterHiddenOutputKeys({ + nested, + }) as { nested: Record } + + expect(Object.hasOwn(filtered.nested, '__proto__')).toBe(true) + expect(filtered.nested.__proto__).toEqual({ safe: true }) + expect(Object.getPrototypeOf(filtered.nested)).toBe(Object.prototype) + }) +}) diff --git a/apps/sim/executor/utils/output-filter.ts b/apps/sim/executor/utils/output-filter.ts index 95c3cab5397..f5403bc534d 100644 --- a/apps/sim/executor/utils/output-filter.ts +++ b/apps/sim/executor/utils/output-filter.ts @@ -6,6 +6,19 @@ import { isTriggerBehavior, isTriggerInternalKey } from '@/executor/constants' import type { NormalizedBlockOutput } from '@/executor/types' import type { SerializedBlock } from '@/serializer/types' +function setFilteredOutputValue( + output: Record, + key: string, + value: unknown +): void { + Object.defineProperty(output, key, { + value, + enumerable: true, + configurable: true, + writable: true, + }) +} + /** * Filters block output for logging/display purposes. * Removes internal fields and fields marked with hiddenFromDisplay. @@ -54,7 +67,7 @@ export function filterOutputForLog( } // Recursively filter globally hidden keys from nested objects - filtered[key] = filterHiddenOutputKeys(value) + setFilteredOutputValue(filtered, key, filterHiddenOutputKeys(value)) } return filtered diff --git a/apps/sim/executor/utils/subflow-utils.server.ts b/apps/sim/executor/utils/subflow-utils.server.ts new file mode 100644 index 00000000000..a748daffcda --- /dev/null +++ b/apps/sim/executor/utils/subflow-utils.server.ts @@ -0,0 +1,126 @@ +import { toError } from '@sim/utils/errors' +import { recordMaterializedAccessKeys } from '@/lib/execution/payloads/access-keys' +import { + isLargeArrayManifest, + LARGE_ARRAY_MANIFEST_MARKER, + materializeLargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest' +import { isLargeValueRef, LARGE_VALUE_REF_MARKER } from '@/lib/execution/payloads/large-value-ref' +import { MAX_DURABLE_LARGE_VALUE_BYTES } from '@/lib/execution/payloads/materialization.server' +import { materializeLargeValueRef } from '@/lib/execution/payloads/store' +import { REFERENCE } from '@/executor/constants' +import type { ExecutionContext } from '@/executor/types' +import type { VariableResolver } from '@/executor/variables/resolver' + +async function normalizeCollectionValue(ctx: ExecutionContext, value: unknown): Promise { + if (Array.isArray(value)) { + return value + } + + if (isLargeArrayManifest(value)) { + const materialized = await materializeLargeArrayManifest(value, { + workspaceId: ctx.workspaceId, + workflowId: ctx.workflowId, + executionId: ctx.executionId, + largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + fileKeys: ctx.fileKeys, + allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, + userId: ctx.userId, + maxBytes: MAX_DURABLE_LARGE_VALUE_BYTES, + }) + recordMaterializedAccessKeys(ctx, materialized) + return materialized + } + + if (isLargeValueRef(value)) { + const materialized = await materializeLargeValueRef(value, { + workspaceId: ctx.workspaceId, + workflowId: ctx.workflowId, + executionId: ctx.executionId, + largeValueExecutionIds: ctx.largeValueExecutionIds, + largeValueKeys: ctx.largeValueKeys, + fileKeys: ctx.fileKeys, + allowLargeValueWorkflowScope: ctx.allowLargeValueWorkflowScope, + userId: ctx.userId, + maxBytes: MAX_DURABLE_LARGE_VALUE_BYTES, + }) + if (materialized === undefined) { + throw new Error('Large execution value is unavailable.') + } + recordMaterializedAccessKeys(ctx, materialized) + return normalizeCollectionValue(ctx, materialized) + } + + if (typeof value === 'object' && value !== null) { + if ((value as Record)[LARGE_ARRAY_MANIFEST_MARKER] === true) { + throw new Error('Invalid large array manifest.') + } + if ((value as Record)[LARGE_VALUE_REF_MARKER] === true) { + throw new Error('Invalid large value ref.') + } + return Object.entries(value) + } + + if (value === null) { + return [] + } + + throw new Error('Value did not resolve to an array or object') +} + +/** + * Resolves loop/parallel collection inputs on the server, including durable + * execution values that cannot be imported into client-reachable utilities. + */ +export async function resolveArrayInputAsync( + ctx: ExecutionContext, + items: any, + resolver: VariableResolver | null +): Promise { + if (typeof items !== 'string') { + if (items === null) { + return [] + } + if (!Array.isArray(items) && typeof items !== 'object') { + if (!resolver) { + return [] + } + try { + const resolved = (await resolver.resolveInputs(ctx, 'subflow_items', { items })).items + return normalizeCollectionValue(ctx, resolved) + } catch (error) { + if (error instanceof Error && error.message.startsWith('Resolved items')) { + throw error + } + throw new Error(`Failed to resolve items: ${toError(error).message}`) + } + } + return normalizeCollectionValue(ctx, items) + } + + if (items.startsWith(REFERENCE.START) && items.endsWith(REFERENCE.END) && resolver) { + try { + const resolved = await resolver.resolveSingleReference(ctx, '', items, undefined, { + allowLargeValueRefs: true, + }) + return normalizeCollectionValue(ctx, resolved) + } catch (error) { + if (error instanceof Error && error.message.startsWith('Reference "')) { + throw error + } + throw new Error(`Failed to resolve reference "${items}": ${toError(error).message}`) + } + } + + try { + const normalized = items.replace(/'/g, '"') + const parsed = JSON.parse(normalized) + return normalizeCollectionValue(ctx, parsed) + } catch (error) { + if (error instanceof Error && error.message.startsWith('Parsed value')) { + throw error + } + throw new Error(`Failed to parse items as JSON: "${items}"`) + } +} diff --git a/apps/sim/executor/utils/subflow-utils.test.ts b/apps/sim/executor/utils/subflow-utils.test.ts index 478319d6ca9..60f657d9bc6 100644 --- a/apps/sim/executor/utils/subflow-utils.test.ts +++ b/apps/sim/executor/utils/subflow-utils.test.ts @@ -1,13 +1,60 @@ /** * @vitest-environment node */ -import { describe, expect, it, vi } from 'vitest' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { cacheLargeValue, clearLargeValueCacheForTests } from '@/lib/execution/payloads/cache' +import { + LARGE_ARRAY_MANIFEST_MARKER, + LARGE_ARRAY_MANIFEST_VERSION, +} from '@/lib/execution/payloads/large-array-manifest-metadata' +import { LARGE_VALUE_REF_MARKER } from '@/lib/execution/payloads/large-value-ref' import type { ExecutionContext } from '@/executor/types' +import { findEffectiveContainerId } from '@/executor/utils/subflow-utils' +import { resolveArrayInputAsync } from '@/executor/utils/subflow-utils.server' import type { VariableResolver } from '@/executor/variables/resolver' -import { findEffectiveContainerId, resolveArrayInputAsync } from './subflow-utils' describe('resolveArrayInputAsync', () => { - const fakeCtx = {} as unknown as ExecutionContext + const fakeCtx = { + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + executionId: 'execution-1', + userId: 'user-1', + } as unknown as ExecutionContext + + beforeEach(() => { + clearLargeValueCacheForTests() + }) + + function createManifest(items: unknown[]) { + const json = JSON.stringify(items) + const size = Buffer.byteLength(json, 'utf8') + const id = 'lv_ABCDEFGHIJKL' + cacheLargeValue(id, items, size, fakeCtx) + + return { + __simLargeArrayManifest: true, + version: LARGE_ARRAY_MANIFEST_VERSION, + kind: 'array', + totalCount: items.length, + chunkCount: 1, + byteSize: size, + chunks: [ + { + ref: { + __simLargeValueRef: true, + version: 1, + id, + kind: 'array', + size, + executionId: fakeCtx.executionId, + }, + count: items.length, + byteSize: size, + }, + ], + preview: items.slice(0, 3), + } + } it('returns arrays as-is', async () => { await expect(resolveArrayInputAsync(fakeCtx, [1, 2, 3], null)).resolves.toEqual([1, 2, 3]) @@ -20,6 +67,81 @@ describe('resolveArrayInputAsync', () => { ]) }) + it('materializes large array manifests instead of iterating metadata entries', async () => { + const items = [{ id: 1 }, { id: 2 }] + const manifest = createManifest(items) + + await expect(resolveArrayInputAsync(fakeCtx, manifest, null)).resolves.toEqual(items) + }) + + it('records exact nested keys discovered while materializing collection values', async () => { + const ctx = { + ...fakeCtx, + largeValueKeys: [] as string[], + fileKeys: [] as string[], + } as ExecutionContext + const nestedRef = { + __simLargeValueRef: true, + version: 1, + id: 'lv_MNOPQRSTUVWX', + kind: 'object', + size: 12, + key: 'execution/workspace-1/workflow-1/source-execution/large-value-lv_MNOPQRSTUVWX.json', + executionId: 'source-execution', + } + const file = { + id: 'file-1', + name: 'nested.txt', + key: 'execution/workspace-1/workflow-1/source-execution/nested.txt', + url: '/api/files/serve/execution/workspace-1/workflow-1/source-execution/nested.txt?context=execution', + size: 5, + type: 'text/plain', + context: 'execution', + } + const items = [{ nestedRef, file }] + const manifest = createManifest(items) + + await expect(resolveArrayInputAsync(ctx, manifest, null)).resolves.toEqual(items) + + expect(ctx.largeValueKeys).toEqual([nestedRef.key]) + expect(ctx.fileKeys).toEqual([file.key]) + }) + + it('rejects invalid manifest-shaped collection inputs instead of iterating metadata', async () => { + await expect( + resolveArrayInputAsync( + fakeCtx, + { + [LARGE_ARRAY_MANIFEST_MARKER]: true, + version: LARGE_ARRAY_MANIFEST_VERSION, + kind: 'array', + totalCount: 1, + chunkCount: 0, + byteSize: 0, + chunks: [], + preview: [], + }, + null + ) + ).rejects.toThrow('Invalid large array manifest') + }) + + it('rejects invalid large-ref-shaped collection inputs instead of iterating metadata', async () => { + await expect( + resolveArrayInputAsync( + fakeCtx, + { + [LARGE_VALUE_REF_MARKER]: true, + version: 1, + id: 'not-a-valid-large-value-id', + kind: 'array', + size: 1, + }, + null + ) + ).rejects.toThrow('Invalid large value ref') + }) + it('returns empty array when a pure reference resolves to null (skipped block)', async () => { // `resolveSingleReference` returns `null` for a reference that points at a // block that exists in the workflow but did not execute on this path. @@ -45,6 +167,25 @@ describe('resolveArrayInputAsync', () => { ]) }) + it('materializes a manifest returned by a pure reference', async () => { + const items = [{ id: 1 }, { id: 2 }] + const manifest = createManifest(items) + const resolver = { + resolveSingleReference: vi.fn().mockResolvedValue(manifest), + } as unknown as VariableResolver + + await expect(resolveArrayInputAsync(fakeCtx, '', resolver)).resolves.toEqual( + items + ) + expect(resolver.resolveSingleReference).toHaveBeenCalledWith( + fakeCtx, + '', + '', + undefined, + { allowLargeValueRefs: true } + ) + }) + it('converts resolved objects to entries', async () => { const resolver = { resolveSingleReference: vi.fn().mockResolvedValue({ x: 1, y: 2 }), diff --git a/apps/sim/executor/utils/subflow-utils.ts b/apps/sim/executor/utils/subflow-utils.ts index 7f363365627..d87245bccb6 100644 --- a/apps/sim/executor/utils/subflow-utils.ts +++ b/apps/sim/executor/utils/subflow-utils.ts @@ -1,10 +1,9 @@ import { createLogger } from '@sim/logger' import { toError } from '@sim/utils/errors' -import { DEFAULTS, LOOP, PARALLEL, REFERENCE } from '@/executor/constants' +import { DEFAULTS, LOOP, PARALLEL } from '@/executor/constants' import type { ContextExtensions } from '@/executor/execution/types' import { type BlockLog, type ExecutionContext, getNextExecutionOrder } from '@/executor/types' import { buildContainerIterationContext } from '@/executor/utils/iteration-context' -import type { VariableResolver } from '@/executor/variables/resolver' const logger = createLogger('SubflowUtils') @@ -198,81 +197,6 @@ export function normalizeNodeId(nodeId: string): string { return nodeId } -/** - * Async variant used by execution paths that may need durable large-value or - * explicit UserFile.base64 materialization while resolving collection inputs. - */ -export async function resolveArrayInputAsync( - ctx: ExecutionContext, - items: any, - resolver: VariableResolver | null -): Promise { - if (Array.isArray(items)) { - return items - } - - if (typeof items === 'object' && items !== null) { - return Object.entries(items) - } - - if (typeof items === 'string') { - if (items.startsWith(REFERENCE.START) && items.endsWith(REFERENCE.END) && resolver) { - try { - const resolved = await resolver.resolveSingleReference(ctx, '', items) - if (Array.isArray(resolved)) { - return resolved - } - if (typeof resolved === 'object' && resolved !== null) { - return Object.entries(resolved) - } - if (resolved === null) { - return [] - } - throw new Error(`Reference "${items}" did not resolve to an array or object`) - } catch (error) { - if (error instanceof Error && error.message.startsWith('Reference "')) { - throw error - } - throw new Error(`Failed to resolve reference "${items}": ${toError(error).message}`) - } - } - - try { - const normalized = items.replace(/'/g, '"') - const parsed = JSON.parse(normalized) - if (Array.isArray(parsed)) { - return parsed - } - if (typeof parsed === 'object' && parsed !== null) { - return Object.entries(parsed) - } - throw new Error(`Parsed value is not an array or object`) - } catch (error) { - if (error instanceof Error && error.message.startsWith('Parsed value')) { - throw error - } - throw new Error(`Failed to parse items as JSON: "${items}"`) - } - } - - if (resolver) { - try { - const resolved = (await resolver.resolveInputs(ctx, 'subflow_items', { items })).items - if (Array.isArray(resolved)) { - return resolved - } - throw new Error(`Resolved items is not an array`) - } catch (error) { - if (error instanceof Error && error.message.startsWith('Resolved items')) { - throw error - } - throw new Error(`Failed to resolve items: ${toError(error).message}`) - } - } - - return [] -} - /** * Creates and logs an error for a subflow (loop or parallel). */ diff --git a/apps/sim/executor/variables/resolver.test.ts b/apps/sim/executor/variables/resolver.test.ts index 6058a2053e8..84b3bf92d6a 100644 --- a/apps/sim/executor/variables/resolver.test.ts +++ b/apps/sim/executor/variables/resolver.test.ts @@ -1,11 +1,16 @@ /** * @vitest-environment node */ -import { describe, expect, it } from 'vitest' +import { describe, expect, it, vi } from 'vitest' +import { + LARGE_ARRAY_MANIFEST_VERSION, + type LargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest-metadata' import { BlockType } from '@/executor/constants' import { ExecutionState } from '@/executor/execution/state' import type { ExecutionContext } from '@/executor/types' import { VariableResolver } from '@/executor/variables/resolver' +import { navigatePathAsync } from '@/executor/variables/resolvers/reference-async.server' import type { SerializedBlock, SerializedWorkflow } from '@/serializer/types' function createBlock(id: string, name: string, type: string, params = {}): SerializedBlock { @@ -24,7 +29,37 @@ function createBlock(id: string, name: string, type: string, params = {}): Seria } } -function createResolver(language = 'javascript') { +function createTestManifest(totalCount = 100_000): LargeArrayManifest { + return { + __simLargeArrayManifest: true, + version: LARGE_ARRAY_MANIFEST_VERSION, + kind: 'array', + totalCount, + chunkCount: 1, + byteSize: 12 * 1024 * 1024, + chunks: [ + { + count: totalCount, + byteSize: 12 * 1024 * 1024, + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 12 * 1024 * 1024, + key: 'execution/workspace-1/workflow-1/execution-1/large-value-lv_ABCDEFGHIJKL.json', + executionId: 'execution-1', + }, + }, + ], + preview: [{ key: 'SIM-0' }], + } +} + +function createResolver( + language = 'javascript', + options: ConstructorParameters[3] = {} +) { const producer = createBlock('producer', 'Producer', BlockType.API) const functionBlock = createBlock('function', 'Function', BlockType.FUNCTION, { language, @@ -67,7 +102,7 @@ function createResolver(language = 'javascript') { return { block: functionBlock, ctx, - resolver: new VariableResolver(workflow, {}, state), + resolver: new VariableResolver(workflow, {}, state, options), } } @@ -95,6 +130,274 @@ describe('VariableResolver function block inputs', () => { expect(result.contextVariables).toEqual({ __blockRef_0: 'hello world' }) }) + it('allows Variables block assignments to receive whole large refs', async () => { + const producer = createBlock('producer', 'Producer', BlockType.API) + const variablesBlock = createBlock('variables', 'Variables', BlockType.VARIABLES, { + variables: [ + { + variableId: 'var-1', + variableName: 'issues', + type: 'array', + value: '', + }, + ], + }) + const workflow: SerializedWorkflow = { + version: '1', + blocks: [producer, variablesBlock], + connections: [], + loops: {}, + parallels: {}, + } + const state = new ExecutionState() + const ref = { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 12 * 1024 * 1024, + executionId: 'execution-1', + } + state.setBlockOutput('producer', { result: ref }) + const ctx = { + blockStates: state.getBlockStates(), + blockLogs: [], + environmentVariables: {}, + workflowVariables: {}, + decisions: { router: new Map(), condition: new Map() }, + loopExecutions: new Map(), + executedBlocks: new Set(), + activeExecutionPath: new Set(), + completedLoops: new Set(), + metadata: {}, + } as ExecutionContext + + const resolver = new VariableResolver(workflow, {}, state) + const result = await resolver.resolveInputs( + ctx, + 'variables', + variablesBlock.config.params, + variablesBlock + ) + + expect(JSON.parse(result.variables[0].value)).toEqual(ref) + }) + + it('allows Variables block assignments to receive whole large array manifests', async () => { + const producer = createBlock('producer', 'Producer', BlockType.API) + const variablesBlock = createBlock('variables', 'Variables', BlockType.VARIABLES, { + variables: [ + { + variableId: 'var-1', + variableName: 'issues', + type: 'array', + value: '', + }, + ], + }) + const workflow: SerializedWorkflow = { + version: '1', + blocks: [producer, variablesBlock], + connections: [], + loops: {}, + parallels: {}, + } + const state = new ExecutionState() + const manifest = createTestManifest() + state.setBlockOutput('producer', { result: manifest }) + const ctx = { + blockStates: state.getBlockStates(), + blockLogs: [], + environmentVariables: {}, + workflowVariables: {}, + decisions: { router: new Map(), condition: new Map() }, + loopExecutions: new Map(), + executedBlocks: new Set(), + activeExecutionPath: new Set(), + completedLoops: new Set(), + metadata: {}, + } as ExecutionContext + + const resolver = new VariableResolver(workflow, {}, state) + const result = await resolver.resolveInputs( + ctx, + 'variables', + variablesBlock.config.params, + variablesBlock + ) + + expect(JSON.parse(result.variables[0].value)).toEqual(manifest) + }) + + it('allows Response block data to preserve whole large refs', async () => { + const producer = createBlock('producer', 'Producer', BlockType.API) + const responseBlock = createBlock('response', 'Response', BlockType.RESPONSE, { + dataMode: 'json', + data: '', + }) + const workflow: SerializedWorkflow = { + version: '1', + blocks: [producer, responseBlock], + connections: [], + loops: {}, + parallels: {}, + } + const state = new ExecutionState() + const ref = { + __simLargeValueRef: true, + version: 1, + id: 'lv_ZYXWVUTSRQPO', + kind: 'array', + size: 12 * 1024 * 1024, + executionId: 'execution-1', + } + state.setBlockOutput('producer', { result: ref }) + const ctx = { + blockStates: state.getBlockStates(), + blockLogs: [], + environmentVariables: {}, + workflowVariables: {}, + decisions: { router: new Map(), condition: new Map() }, + loopExecutions: new Map(), + executedBlocks: new Set(), + activeExecutionPath: new Set(), + completedLoops: new Set(), + metadata: {}, + } as ExecutionContext + + const resolver = new VariableResolver(workflow, {}, state) + const result = await resolver.resolveInputs( + ctx, + 'response', + responseBlock.config.params, + responseBlock + ) + + expect(JSON.parse(result.data)).toEqual(ref) + }) + + it('resolves workflow variable object references through context variables', async () => { + const { block, ctx, resolver } = createResolver('javascript') + const issues = [{ key: 'SIM-1', summary: 'Small issue' }] + ctx.workflowVariables = { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: issues }, + } + + const result = await resolver.resolveInputsForFunctionBlock( + ctx, + 'function', + { code: 'return ' }, + block + ) + + expect(result.resolvedInputs.code).toBe('return globalThis["__blockRef_0"]') + expect(result.displayInputs.code).toBe('return [{"key":"SIM-1","summary":"Small issue"}]') + expect(result.contextVariables).toEqual({ __blockRef_0: issues }) + }) + + it('resolves large workflow variable refs without embedding large literals', async () => { + const { block, ctx, resolver } = createResolver('javascript') + const ref = { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 12 * 1024 * 1024, + executionId: 'execution-1', + } + ctx.workflowVariables = { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: ref }, + } + + const result = await resolver.resolveInputsForFunctionBlock( + ctx, + 'function', + { code: 'return ' }, + block + ) + + expect(result.resolvedInputs.code).toBe( + 'return (await sim.values.read(globalThis["__blockRef_0"]))' + ) + expect(result.contextVariables).toEqual({ __blockRef_0: ref }) + }) + + it('rewrites whole manifest workflow variables to lazy JavaScript array reads', async () => { + const { block, ctx, resolver } = createResolver('javascript') + const manifest = createTestManifest() + ctx.workflowVariables = { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: manifest }, + } + + const result = await resolver.resolveInputsForFunctionBlock( + ctx, + 'function', + { code: 'return ' }, + block + ) + + expect(result.resolvedInputs.code).toBe( + 'return (await sim.values.readArray(globalThis["__blockRef_0"]))' + ) + expect(result.contextVariables).toEqual({ __blockRef_0: manifest }) + }) + + it('resolves manifest workflow variable length without whole-array context variables', async () => { + const { block, ctx, resolver } = createResolver('javascript', { navigatePathAsync }) + const manifest = createTestManifest() + ctx.workflowVariables = { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: manifest }, + } + + const result = await resolver.resolveInputsForFunctionBlock( + ctx, + 'function', + { code: 'return ' }, + block + ) + + expect(result.resolvedInputs.code).toBe('return 100000') + expect(result.contextVariables).toEqual({}) + }) + + it('keeps manifest internals hidden during async path navigation', async () => { + const { ctx } = createResolver() + const manifest = createTestManifest() + + await expect(navigatePathAsync(manifest, ['totalCount'], ctx)).resolves.toBe(100_000) + await expect(navigatePathAsync(manifest, ['chunkCount'], ctx)).resolves.toBe(1) + await expect(navigatePathAsync(manifest, ['preview'], ctx)).resolves.toEqual([{ key: 'SIM-0' }]) + await expect( + navigatePathAsync(manifest, ['chunks', '0', 'ref', 'id'], ctx) + ).resolves.toBeUndefined() + }) + + it('resolves indexed manifest workflow variable paths without whole-array context variables', async () => { + const manifest = createTestManifest() + const navigateManifestPath = vi.fn(async () => 'SIM-0') + const { block, ctx, resolver } = createResolver('javascript', { + navigatePathAsync: navigateManifestPath, + }) + ctx.workflowVariables = { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: manifest }, + } + + const result = await resolver.resolveInputsForFunctionBlock( + ctx, + 'function', + { code: 'return ' }, + block + ) + + expect(navigateManifestPath).toHaveBeenCalledWith( + manifest, + ['0', 'key'], + expect.objectContaining({ allowLargeValueRefs: true }) + ) + expect(result.resolvedInputs.code).toBe('return "SIM-0"') + expect(result.contextVariables).toEqual({}) + }) + it('resolves named loop result bracket paths in function code', async () => { const loopBlock = createBlock('loop-1', 'Loop 1', 'loop') const functionBlock = createBlock('function', 'Function', BlockType.FUNCTION, { @@ -408,6 +711,35 @@ describe('VariableResolver function block inputs', () => { ).rejects.toThrow('This execution value is too large to inline') }) + it('fails whole large array manifests for Function runtimes without lazy helpers', async () => { + const { block, ctx } = createResolver('python') + const state = new ExecutionState() + state.setBlockOutput('producer', { + result: createTestManifest(), + }) + const workflow: SerializedWorkflow = { + version: '1', + blocks: [createBlock('producer', 'Producer', BlockType.API), block], + connections: [], + loops: {}, + parallels: {}, + } + const largeResolver = new VariableResolver(workflow, {}, state) + const largeCtx = { + ...ctx, + blockStates: state.getBlockStates(), + } as ExecutionContext + + await expect( + largeResolver.resolveInputsForFunctionBlock( + largeCtx, + 'function', + { code: 'return ' }, + block + ) + ).rejects.toThrow('This execution value contains nested large values') + }) + it('fails whole large value refs for JavaScript with imports', async () => { const { block, ctx } = createResolver('javascript') const state = new ExecutionState() diff --git a/apps/sim/executor/variables/resolver.ts b/apps/sim/executor/variables/resolver.ts index 33ac7e181b0..22739fc5bd1 100644 --- a/apps/sim/executor/variables/resolver.ts +++ b/apps/sim/executor/variables/resolver.ts @@ -1,6 +1,7 @@ import { createLogger } from '@sim/logger' import { toError } from '@sim/utils/errors' import { isUserFileWithMetadata } from '@/lib/core/utils/user-file' +import { isLargeArrayManifest } from '@/lib/execution/payloads/large-array-manifest-metadata' import { containsLargeValueRef, getLargeValueMaterializationError, @@ -100,7 +101,7 @@ export class VariableResolver { this.resolvers = [ new LoopResolver(workflow, options.navigatePathAsync), new ParallelResolver(workflow, options.navigatePathAsync), - new WorkflowResolver(workflowVariables), + new WorkflowResolver(workflowVariables, options.navigatePathAsync), new EnvResolver(), this.blockResolver, ] @@ -244,16 +245,31 @@ export class VariableResolver { if (isConditionBlock && key === 'conditions') { continue } - resolved[key] = await this.resolveValue(ctx, currentNodeId, value, undefined, block) + resolved[key] = await this.resolveValue(ctx, currentNodeId, value, undefined, block, { + allowLargeValueRefs: this.canResolveInputToLargeValueRef(block, key), + }) } return resolved } + private canResolveInputToLargeValueRef(block: SerializedBlock | undefined, key: string): boolean { + if (block?.metadata?.id === BlockType.VARIABLES) { + return key === 'variables' + } + + if (block?.metadata?.id === BlockType.RESPONSE) { + return key === 'data' || key === 'builderData' + } + + return false + } + async resolveSingleReference( ctx: ExecutionContext, currentNodeId: string, reference: string, - loopScope?: LoopScope + loopScope?: LoopScope, + options: { allowLargeValueRefs?: boolean } = {} ): Promise { if (typeof reference === 'string') { const trimmed = reference.trim() @@ -263,6 +279,7 @@ export class VariableResolver { executionState: this.state, currentNodeId, loopScope, + allowLargeValueRefs: options.allowLargeValueRefs, } const result = await this.resolveReference(trimmed, resolutionContext) @@ -281,7 +298,8 @@ export class VariableResolver { currentNodeId: string, value: any, loopScope?: LoopScope, - block?: SerializedBlock + block?: SerializedBlock, + options: { allowLargeValueRefs?: boolean } = {} ): Promise { if (value === null || value === undefined) { return value @@ -289,7 +307,7 @@ export class VariableResolver { if (Array.isArray(value)) { return Promise.all( - value.map((v) => this.resolveValue(ctx, currentNodeId, v, loopScope, block)) + value.map((v) => this.resolveValue(ctx, currentNodeId, v, loopScope, block, options)) ) } @@ -297,14 +315,14 @@ export class VariableResolver { const entries = await Promise.all( Object.entries(value).map(async ([key, val]) => [ key, - await this.resolveValue(ctx, currentNodeId, val, loopScope, block), + await this.resolveValue(ctx, currentNodeId, val, loopScope, block, options), ]) ) return Object.fromEntries(entries) } if (typeof value === 'string') { - return this.resolveTemplate(ctx, currentNodeId, value, loopScope, block) + return this.resolveTemplate(ctx, currentNodeId, value, loopScope, block, options) } return value } @@ -383,6 +401,17 @@ export class VariableResolver { throw getLargeValueMaterializationError(effectiveValue) } replacement = lazyReplacement + } else if (isLargeArrayManifest(effectiveValue)) { + const lazyReplacement = this.formatLazyLargeArrayManifestReference( + varName, + language, + template, + index + ) + if (!lazyReplacement) { + throw getNestedLargeValueMaterializationError() + } + replacement = lazyReplacement } else if (containsLargeValueRef(effectiveValue)) { throw getNestedLargeValueMaterializationError() } else { @@ -432,11 +461,53 @@ export class VariableResolver { throw getLargeValueMaterializationError(effectiveValue) } + if (isLargeArrayManifest(effectiveValue)) { + const varName = `__blockRef_${Object.keys(contextVarAccumulator).length}` + contextVarAccumulator[varName] = effectiveValue + const lazyReplacement = this.formatLazyLargeArrayManifestReference( + varName, + language, + template, + index + ) + if (lazyReplacement) { + displayResult += this.formatDisplayValueForCodeContext( + effectiveValue, + language, + template, + index + ) + return lazyReplacement + } + throw getNestedLargeValueMaterializationError() + } + if (containsLargeValueRef(effectiveValue)) { throw getNestedLargeValueMaterializationError() } - // Non-block reference (loop, parallel, workflow, env): embed as literal + if ( + this.isWorkflowVariableReference(match) && + this.shouldUseContextVariable(effectiveValue) + ) { + const varName = `__blockRef_${Object.keys(contextVarAccumulator).length}` + contextVarAccumulator[varName] = effectiveValue + const replacement = this.formatContextVariableReference( + varName, + language, + template, + index, + effectiveValue + ) + displayResult += this.formatDisplayValueForCodeContext( + effectiveValue, + language, + template, + index + ) + return replacement + } + const replacement = this.blockResolver.formatValueForBlock( effectiveValue, BlockType.FUNCTION, @@ -522,6 +593,31 @@ export class VariableResolver { }) } + private formatLazyLargeArrayManifestReference( + varName: string, + language: string | undefined, + template: string, + matchIndex: number + ): string | null { + if (!this.canUseJavaScriptRuntimeHelpers(language, template)) { + return null + } + + const expression = `(await sim.values.readArray(globalThis[${JSON.stringify(varName)}]))` + return this.formatJavaScriptAsyncExpression(expression, template, matchIndex, { + stringifyInStringContext: true, + }) + } + + private isWorkflowVariableReference(reference: string): boolean { + const parts = parseReferencePath(reference) + return parts[0] === REFERENCE.PREFIX.VARIABLE + } + + private shouldUseContextVariable(value: unknown): boolean { + return typeof value === 'object' && value !== null + } + private formatJavaScriptAsyncExpression( expression: string, template: string, @@ -1011,13 +1107,15 @@ export class VariableResolver { currentNodeId: string, template: string, loopScope?: LoopScope, - block?: SerializedBlock + block?: SerializedBlock, + options: { allowLargeValueRefs?: boolean } = {} ): Promise { const resolutionContext: ResolutionContext = { executionContext: ctx, executionState: this.state, currentNodeId, loopScope, + allowLargeValueRefs: options.allowLargeValueRefs, } let replacementError: Error | null = null diff --git a/apps/sim/executor/variables/resolvers/loop.ts b/apps/sim/executor/variables/resolvers/loop.ts index 3b0a3e1b611..ef483c995ce 100644 --- a/apps/sim/executor/variables/resolvers/loop.ts +++ b/apps/sim/executor/variables/resolvers/loop.ts @@ -180,7 +180,10 @@ export class LoopResolver implements Resolver { if (pathParts.length > 0) { return useAsyncPath && this.navigatePathAsync ? this.navigatePathAsync(value, pathParts, context) - : navigatePath(value, pathParts, { executionContext: context.executionContext }) + : navigatePath(value, pathParts, { + allowLargeValueRefs: context.allowLargeValueRefs, + executionContext: context.executionContext, + }) } return value @@ -191,9 +194,15 @@ export class LoopResolver implements Resolver { if (!output || typeof output !== 'object') { return undefined } - const value = (output as Record).results + const value = navigatePath(output, ['results'], { + allowLargeValueRefs: true, + executionContext: context.executionContext, + }) if (pathParts.length > 0) { - return navigatePath(value, pathParts, { executionContext: context.executionContext }) + return navigatePath(value, pathParts, { + allowLargeValueRefs: context.allowLargeValueRefs, + executionContext: context.executionContext, + }) } if (!context.allowLargeValueRefs) { assertNoLargeValueRefs(value) @@ -210,11 +219,19 @@ export class LoopResolver implements Resolver { if (!output || typeof output !== 'object') { return undefined } - const value = (output as Record).results + const value = this.navigatePathAsync + ? await this.navigatePathAsync(output, ['results'], { ...context, allowLargeValueRefs: true }) + : navigatePath(output, ['results'], { + allowLargeValueRefs: true, + executionContext: context.executionContext, + }) if (pathParts.length > 0) { return this.navigatePathAsync ? this.navigatePathAsync(value, pathParts, context) - : navigatePath(value, pathParts, { executionContext: context.executionContext }) + : navigatePath(value, pathParts, { + allowLargeValueRefs: context.allowLargeValueRefs, + executionContext: context.executionContext, + }) } if (!context.allowLargeValueRefs) { assertNoLargeValueRefs(value) diff --git a/apps/sim/executor/variables/resolvers/parallel.ts b/apps/sim/executor/variables/resolvers/parallel.ts index 538fc69780d..e6f033f80ab 100644 --- a/apps/sim/executor/variables/resolvers/parallel.ts +++ b/apps/sim/executor/variables/resolvers/parallel.ts @@ -177,7 +177,10 @@ export class ParallelResolver implements Resolver { if (pathParts.length > 0) { return useAsyncPath && this.navigatePathAsync ? this.navigatePathAsync(value, pathParts, context) - : navigatePath(value, pathParts, { executionContext: context.executionContext }) + : navigatePath(value, pathParts, { + allowLargeValueRefs: context.allowLargeValueRefs, + executionContext: context.executionContext, + }) } return value @@ -281,9 +284,15 @@ export class ParallelResolver implements Resolver { if (!output || typeof output !== 'object') { return undefined } - const value = (output as Record).results + const value = navigatePath(output, ['results'], { + allowLargeValueRefs: true, + executionContext: context.executionContext, + }) if (pathParts.length > 0) { - return navigatePath(value, pathParts, { executionContext: context.executionContext }) + return navigatePath(value, pathParts, { + allowLargeValueRefs: context.allowLargeValueRefs, + executionContext: context.executionContext, + }) } if (!context.allowLargeValueRefs) { assertNoLargeValueRefs(value) @@ -300,11 +309,19 @@ export class ParallelResolver implements Resolver { if (!output || typeof output !== 'object') { return undefined } - const value = (output as Record).results + const value = this.navigatePathAsync + ? await this.navigatePathAsync(output, ['results'], { ...context, allowLargeValueRefs: true }) + : navigatePath(output, ['results'], { + allowLargeValueRefs: true, + executionContext: context.executionContext, + }) if (pathParts.length > 0) { return this.navigatePathAsync ? this.navigatePathAsync(value, pathParts, context) - : navigatePath(value, pathParts, { executionContext: context.executionContext }) + : navigatePath(value, pathParts, { + allowLargeValueRefs: context.allowLargeValueRefs, + executionContext: context.executionContext, + }) } if (!context.allowLargeValueRefs) { assertNoLargeValueRefs(value) diff --git a/apps/sim/executor/variables/resolvers/reference-async.server.ts b/apps/sim/executor/variables/resolvers/reference-async.server.ts index 78dca4a3712..8f40d04b058 100644 --- a/apps/sim/executor/variables/resolvers/reference-async.server.ts +++ b/apps/sim/executor/variables/resolvers/reference-async.server.ts @@ -1,4 +1,10 @@ import { isUserFileWithMetadata } from '@/lib/core/utils/user-file' +import { recordMaterializedAccessKeys } from '@/lib/execution/payloads/access-keys' +import { + isLargeArrayManifest, + type LargeArrayManifest, + readLargeArrayManifestSlice, +} from '@/lib/execution/payloads/large-array-manifest' import { assertNoLargeValueRefs, getLargeValueMaterializationError, @@ -6,42 +12,72 @@ import { } from '@/lib/execution/payloads/large-value-ref' import { materializeLargeValueRef } from '@/lib/execution/payloads/store' import { hydrateUserFileWithBase64 } from '@/lib/uploads/utils/user-file-base64.server' -import type { ResolutionContext } from '@/executor/variables/resolvers/reference' +import type { PathNavigationContext } from '@/executor/variables/resolvers/reference' + +interface MaterializedNavigationValue { + value: unknown + context: PathNavigationContext +} + +function withLocalLargeValueExecutionIds( + context: PathNavigationContext, + materializedValue: unknown +): PathNavigationContext { + if (!context.executionContext) { + return context + } + recordMaterializedAccessKeys(context.executionContext, materializedValue) + return { + ...context, + executionContext: { + ...context.executionContext, + largeValueKeys: context.executionContext.largeValueKeys, + fileKeys: context.executionContext.fileKeys, + }, + } +} async function materializeLargeValueRefOrThrow( value: unknown, - context: ResolutionContext -): Promise { + context: PathNavigationContext +): Promise { if (!isLargeValueRef(value)) { - return value + return { value, context } } const materialized = await materializeLargeValueRef(value, { workspaceId: context.executionContext.workspaceId, workflowId: context.executionContext.workflowId, executionId: context.executionContext.executionId, largeValueExecutionIds: context.executionContext.largeValueExecutionIds, + largeValueKeys: context.executionContext.largeValueKeys, + fileKeys: context.executionContext.fileKeys, allowLargeValueWorkflowScope: context.executionContext.allowLargeValueWorkflowScope, userId: context.executionContext.userId, }) if (materialized === undefined) { throw getLargeValueMaterializationError(value) } - return materialized + return { + value: materialized, + context: withLocalLargeValueExecutionIds(context, materialized), + } } async function hydrateExplicitBase64( file: unknown, - context: ResolutionContext + context: PathNavigationContext ): Promise { if (!isUserFileWithMetadata(file)) { return undefined } const hydrated = await hydrateUserFileWithBase64(file, { - requestId: context.executionContext.metadata.requestId, + requestId: context.executionContext.metadata?.requestId, workspaceId: context.executionContext.workspaceId, workflowId: context.executionContext.workflowId, executionId: context.executionContext.executionId, largeValueExecutionIds: context.executionContext.largeValueExecutionIds, + largeValueKeys: context.executionContext.largeValueKeys, + fileKeys: context.executionContext.fileKeys, allowLargeValueWorkflowScope: context.executionContext.allowLargeValueWorkflowScope, userId: context.executionContext.userId, maxBytes: context.executionContext.base64MaxBytes, @@ -54,6 +90,47 @@ async function hydrateExplicitBase64( return hydrated.base64 } +async function readManifestIndexAsync( + value: LargeArrayManifest, + part: string, + context: PathNavigationContext +): Promise { + const [item] = await readLargeArrayManifestSlice(value, Number.parseInt(part, 10), 1, { + workspaceId: context.executionContext.workspaceId, + workflowId: context.executionContext.workflowId, + executionId: context.executionContext.executionId, + largeValueExecutionIds: context.executionContext.largeValueExecutionIds, + largeValueKeys: context.executionContext.largeValueKeys, + allowLargeValueWorkflowScope: context.executionContext.allowLargeValueWorkflowScope, + userId: context.executionContext.userId, + }) + return item +} + +async function navigateManifestMetadataOrIndexAsync( + value: unknown, + part: string, + context: PathNavigationContext +): Promise { + if (!isLargeArrayManifest(value)) { + return { value: undefined, context } + } + if (part === 'length' || part === 'totalCount') { + return { value: value.totalCount, context } + } + if (part === 'chunkCount' || part === 'byteSize' || part === 'preview') { + return { value: value[part], context: withLocalLargeValueExecutionIds(context, value[part]) } + } + if (/^\d+$/.test(part)) { + const item = await readManifestIndexAsync(value, part, context) + return { + value: item, + context: withLocalLargeValueExecutionIds(context, item), + } + } + return { value: undefined, context } +} + /** * Server-side path navigation used during execution. It can hydrate persisted * large values and UserFile.base64 only when the requested path explicitly asks @@ -62,24 +139,37 @@ async function hydrateExplicitBase64( export async function navigatePathAsync( obj: any, path: string[], - context: ResolutionContext + context: PathNavigationContext ): Promise { let current = obj + let currentContext = context for (const part of path) { - current = await materializeLargeValueRefOrThrow(current, context) + ;({ value: current, context: currentContext } = await materializeLargeValueRefOrThrow( + current, + currentContext + )) if (current === null || current === undefined) { return undefined } if (part === 'base64') { - const base64 = await hydrateExplicitBase64(current, context) + const base64 = await hydrateExplicitBase64(current, currentContext) if (base64 !== undefined) { current = base64 continue } } + if (isLargeArrayManifest(current)) { + ;({ value: current, context: currentContext } = await navigateManifestMetadataOrIndexAsync( + current, + part, + currentContext + )) + continue + } + const arrayMatch = part.match(/^([^[]+)(\[.+)$/) if (arrayMatch) { const [, prop, bracketsPart] = arrayMatch @@ -87,7 +177,10 @@ export async function navigatePathAsync( typeof current === 'object' && current !== null ? (current as Record)[prop] : undefined - current = await materializeLargeValueRefOrThrow(current, context) + ;({ value: current, context: currentContext } = await materializeLargeValueRefOrThrow( + current, + currentContext + )) if (current === undefined || current === null) { return undefined } @@ -95,17 +188,33 @@ export async function navigatePathAsync( const indices = bracketsPart.match(/\[(\d+)\]/g) if (indices) { for (const indexMatch of indices) { - current = await materializeLargeValueRefOrThrow(current, context) + ;({ value: current, context: currentContext } = await materializeLargeValueRefOrThrow( + current, + currentContext + )) if (current === null || current === undefined) { return undefined } const idx = Number.parseInt(indexMatch.slice(1, -1), 10) - current = Array.isArray(current) ? current[idx] : undefined + if (isLargeArrayManifest(current)) { + ;({ value: current, context: currentContext } = + await navigateManifestMetadataOrIndexAsync(current, String(idx), currentContext)) + } else { + current = Array.isArray(current) ? current[idx] : undefined + } } } } else if (/^\d+$/.test(part)) { const index = Number.parseInt(part, 10) - current = Array.isArray(current) ? current[index] : undefined + if (isLargeArrayManifest(current)) { + ;({ value: current, context: currentContext } = await navigateManifestMetadataOrIndexAsync( + current, + part, + currentContext + )) + } else { + current = Array.isArray(current) ? current[index] : undefined + } } else { current = typeof current === 'object' && current !== null diff --git a/apps/sim/executor/variables/resolvers/reference.test.ts b/apps/sim/executor/variables/resolvers/reference.test.ts index 6318af172e3..a4a2c98e442 100644 --- a/apps/sim/executor/variables/resolvers/reference.test.ts +++ b/apps/sim/executor/variables/resolvers/reference.test.ts @@ -176,6 +176,38 @@ describe('navigatePath', () => { }) }) + describe('large array manifests', () => { + it('returns undefined for sync index access when the chunk is not cached', () => { + const manifest = { + __simLargeArrayManifest: true, + version: 2, + kind: 'array', + totalCount: 1, + chunkCount: 1, + byteSize: 16, + chunks: [ + { + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 16, + executionId: 'execution-1', + }, + count: 1, + byteSize: 16, + }, + ], + preview: [{ id: 1 }], + } + + expect(navigatePath(manifest, ['0'])).toBeUndefined() + expect(navigatePath(manifest, ['length'])).toBe(1) + expect(navigatePath(manifest, ['preview'])).toEqual([{ id: 1 }]) + }) + }) + describe('bracket notation edge cases', () => { it.concurrent('should handle bracket notation with property access', () => { const obj = { data: [{ value: 100 }, { value: 200 }] } diff --git a/apps/sim/executor/variables/resolvers/reference.ts b/apps/sim/executor/variables/resolvers/reference.ts index 70a49a4d11b..1f71fa7fb1b 100644 --- a/apps/sim/executor/variables/resolvers/reference.ts +++ b/apps/sim/executor/variables/resolvers/reference.ts @@ -1,7 +1,33 @@ -import { materializeLargeValueRefSyncOrThrow } from '@/lib/execution/payloads/cache' +import { + materializeLargeValueRefSync, + materializeLargeValueRefSyncOrThrow, +} from '@/lib/execution/payloads/cache' +import { + isLargeArrayManifest, + type LargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest-metadata' import { assertNoLargeValueRefs, isLargeValueRef } from '@/lib/execution/payloads/large-value-ref' import type { ExecutionState, LoopScope } from '@/executor/execution/state' import type { ExecutionContext } from '@/executor/types' + +export interface PathNavigationExecutionContext { + workflowId: string + workspaceId?: string + executionId?: string + largeValueExecutionIds?: string[] + largeValueKeys?: string[] + fileKeys?: string[] + allowLargeValueWorkflowScope?: boolean + userId?: string + metadata?: { requestId?: string } + base64MaxBytes?: number +} + +export interface PathNavigationContext { + executionContext: PathNavigationExecutionContext + allowLargeValueRefs?: boolean +} + export interface ResolutionContext { executionContext: ExecutionContext executionState: ExecutionState @@ -19,7 +45,7 @@ export interface Resolver { export type AsyncPathNavigator = ( obj: any, path: string[], - context: ResolutionContext + context: PathNavigationContext ) => Promise /** @@ -43,6 +69,54 @@ export function splitLeadingBracketPath(part: string): { property: string; pathP } } +function readManifestIndexSync( + manifest: LargeArrayManifest, + index: number, + executionContext?: ExecutionContext +): unknown { + if (!Number.isInteger(index) || index < 0 || index >= manifest.totalCount) { + return undefined + } + + let offset = 0 + for (const chunk of manifest.chunks) { + const nextOffset = offset + chunk.count + if (index < nextOffset) { + const materialized = materializeLargeValueRefSync(chunk.ref, executionContext) + if (materialized === undefined) { + return undefined + } + if (!Array.isArray(materialized)) { + throw new Error('Large array manifest chunk must materialize to an array.') + } + if (materialized.length !== chunk.count) { + throw new Error('Large array manifest chunk count does not match materialized data.') + } + return materialized[index - offset] + } + offset = nextOffset + } + + return undefined +} + +function navigateManifestMetadataOrIndexSync( + manifest: LargeArrayManifest, + part: string, + executionContext?: ExecutionContext +): unknown { + if (part === 'length' || part === 'totalCount') { + return manifest.totalCount + } + if (part === 'chunkCount' || part === 'byteSize' || part === 'preview') { + return manifest[part] + } + if (/^\d+$/.test(part)) { + return readManifestIndexSync(manifest, Number.parseInt(part, 10), executionContext) + } + return undefined +} + /** * Navigate through nested object properties using a path array. * Supports dot notation and array indices. @@ -66,6 +140,11 @@ export function navigatePath( return undefined } + if (isLargeArrayManifest(current)) { + current = navigateManifestMetadataOrIndexSync(current, part, options.executionContext) + continue + } + const arrayMatch = part.match(/^([^[]+)(\[.+)$/) if (arrayMatch) { const [, prop, bracketsPart] = arrayMatch @@ -89,13 +168,25 @@ export function navigatePath( if (isLargeValueRef(current)) { current = materializeLargeValueRefSyncOrThrow(current, options.executionContext) } + if (isLargeArrayManifest(current)) { + current = navigateManifestMetadataOrIndexSync( + current, + indexMatch.slice(1, -1), + options.executionContext + ) + continue + } const idx = Number.parseInt(indexMatch.slice(1, -1), 10) current = Array.isArray(current) ? current[idx] : undefined } } } else if (/^\d+$/.test(part)) { const index = Number.parseInt(part, 10) - current = Array.isArray(current) ? current[index] : undefined + current = isLargeArrayManifest(current) + ? readManifestIndexSync(current, index, options.executionContext) + : Array.isArray(current) + ? current[index] + : undefined } else { current = typeof current === 'object' && current !== null diff --git a/apps/sim/executor/variables/resolvers/workflow.test.ts b/apps/sim/executor/variables/resolvers/workflow.test.ts index 610066b17df..6c20e87922d 100644 --- a/apps/sim/executor/variables/resolvers/workflow.test.ts +++ b/apps/sim/executor/variables/resolvers/workflow.test.ts @@ -1,4 +1,10 @@ import { describe, expect, it, vi } from 'vitest' +import { + createLargeArrayManifest, + isLargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest' +import { compactExecutionPayload } from '@/lib/execution/payloads/serializer' +import { navigatePathAsync } from '@/executor/variables/resolvers/reference-async.server' import type { ResolutionContext } from './reference' import { WorkflowResolver } from './workflow' @@ -15,7 +21,12 @@ vi.mock('@/lib/workflows/variables/variable-manager', () => ({ */ function createTestContext(workflowVariables: Record): ResolutionContext { return { - executionContext: { workflowVariables }, + executionContext: { + workflowVariables, + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + executionId: 'execution-1', + }, executionState: {}, currentNodeId: 'test-node', } as ResolutionContext @@ -157,6 +168,111 @@ describe('WorkflowResolver', () => { expect(result).toBe(value) } }) + + it('returns whole large workflow variable manifests only when refs are allowed', async () => { + const compacted = await compactExecutionPayload( + Array.from({ length: 100 }, (_, index) => ({ + key: `SIM-${index}`, + summary: 'Issue summary that keeps each item small', + })), + { + thresholdBytes: 256, + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + executionId: 'execution-1', + } + ) + const variables = { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: compacted }, + } + const resolver = new WorkflowResolver(variables, navigatePathAsync) + const context = createTestContext(variables) + + expect(() => resolver.resolve('', context)).toThrow('too large to inline') + await expect(resolver.resolveAsync('', context)).rejects.toThrow( + 'too large to inline' + ) + + const allowedContext = { ...context, allowLargeValueRefs: true } + expect(isLargeArrayManifest(resolver.resolve('', allowedContext))).toBe(true) + await expect(resolver.resolveAsync('', allowedContext)).resolves.toEqual( + compacted + ) + }) + + it('resolves nested paths through async large workflow variable navigation', async () => { + const compacted = await compactExecutionPayload( + Array.from({ length: 100 }, (_, index) => ({ + key: `SIM-${index + 1}`, + fields: { summary: index === 0 ? 'Large issue' : 'Other issue' }, + })), + { + thresholdBytes: 256, + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + executionId: 'execution-1', + } + ) + const variables = { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: compacted }, + } + const resolver = new WorkflowResolver(variables, navigatePathAsync) + + await expect( + resolver.resolveAsync('', createTestContext(variables)) + ).resolves.toBe('Large issue') + }) + + it('preserves large array manifest workflow variables without array coercion', async () => { + const manifest = await createLargeArrayManifest([{ key: 'SIM-1' }], { + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + executionId: 'execution-1', + }) + const variables = { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: manifest }, + } + const resolver = new WorkflowResolver(variables, navigatePathAsync) + + const allowedContext = { ...createTestContext(variables), allowLargeValueRefs: true } + + expect(resolver.resolve('', allowedContext)).toEqual(manifest) + await expect(resolver.resolveAsync('', allowedContext)).resolves.toEqual( + manifest + ) + }) + + it('resolves bracket-indexed paths through manifest workflow variables', async () => { + const manifest = await createLargeArrayManifest([{ key: 'SIM-1' }], { + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + executionId: 'execution-1', + }) + const variables = { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: manifest }, + } + const resolver = new WorkflowResolver(variables, navigatePathAsync) + + await expect( + resolver.resolveAsync('', createTestContext(variables)) + ).resolves.toBe('SIM-1') + }) + + it('resolves manifest array length without materializing chunks', async () => { + const manifest = await createLargeArrayManifest([{ key: 'SIM-1' }, { key: 'SIM-2' }], { + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + executionId: 'execution-1', + }) + const variables = { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: manifest }, + } + const resolver = new WorkflowResolver(variables, navigatePathAsync) + + await expect( + resolver.resolveAsync('', createTestContext(variables)) + ).resolves.toBe(2) + }) }) describe('edge cases', () => { diff --git a/apps/sim/executor/variables/resolvers/workflow.ts b/apps/sim/executor/variables/resolvers/workflow.ts index ad2c667949e..c327ee88e21 100644 --- a/apps/sim/executor/variables/resolvers/workflow.ts +++ b/apps/sim/executor/variables/resolvers/workflow.ts @@ -1,16 +1,24 @@ import { createLogger } from '@sim/logger' +import { isLargeArrayManifest } from '@/lib/execution/payloads/large-array-manifest-metadata' +import { assertNoLargeValueRefs, isLargeValueRef } from '@/lib/execution/payloads/large-value-ref' import { VariableManager } from '@/lib/workflows/variables/variable-manager' import { isReference, normalizeName, parseReferencePath, REFERENCE } from '@/executor/constants' import { + type AsyncPathNavigator, navigatePath, type ResolutionContext, type Resolver, + splitLeadingBracketPath, } from '@/executor/variables/resolvers/reference' +import type { VariableType } from '@/stores/variables/types' const logger = createLogger('WorkflowResolver') export class WorkflowResolver implements Resolver { - constructor(private workflowVariables: Record) {} + constructor( + private workflowVariables: Record, + private navigatePathAsync?: AsyncPathNavigator + ) {} canResolve(reference: string): boolean { if (!isReference(reference)) { @@ -31,7 +39,10 @@ export class WorkflowResolver implements Resolver { return undefined } - const [_, variableName, ...pathParts] = parts + const [_, rawVariableName, ...rawPathParts] = parts + const { property: variableName, pathParts: bracketPathParts } = + splitLeadingBracketPath(rawVariableName) + const pathParts = [...bracketPathParts, ...rawPathParts] const normalizedRefName = normalizeName(variableName) const workflowVars = context.executionContext.workflowVariables || this.workflowVariables @@ -45,25 +56,85 @@ export class WorkflowResolver implements Resolver { if (normalizedVarName === normalizedRefName || v.id === variableName) { const normalizedType = (v.type === 'string' ? 'plain' : v.type) || 'plain' let value: any - try { - value = VariableManager.resolveForExecution(v.value, normalizedType) - } catch (error) { - logger.warn('Failed to resolve workflow variable, returning raw value', { - variableName, - error: (error as Error).message, + value = this.resolveVariableValue(v.value, normalizedType, variableName) + + if (pathParts.length > 0) { + return navigatePath(value, pathParts, { + allowLargeValueRefs: context.allowLargeValueRefs, + executionContext: context.executionContext, }) - value = v.value } - // If there are additional path parts, navigate deeper + if (!context.allowLargeValueRefs) { + assertNoLargeValueRefs(value) + } + return value + } + } + + return undefined + } + + async resolveAsync(reference: string, context: ResolutionContext): Promise { + const parts = parseReferencePath(reference) + if (parts.length < 2) { + logger.warn('Invalid variable reference - missing variable name', { reference }) + return undefined + } + + const [_, rawVariableName, ...rawPathParts] = parts + const { property: variableName, pathParts: bracketPathParts } = + splitLeadingBracketPath(rawVariableName) + const pathParts = [...bracketPathParts, ...rawPathParts] + const normalizedRefName = normalizeName(variableName) + const workflowVars = context.executionContext.workflowVariables || this.workflowVariables + + for (const varObj of Object.values(workflowVars)) { + const v = varObj as any + if (!v) continue + + const normalizedVarName = v.name ? normalizeName(v.name) : '' + if (normalizedVarName === normalizedRefName || v.id === variableName) { + const normalizedType = (v.type === 'string' ? 'plain' : v.type) || 'plain' + let value: any + value = this.resolveVariableValue(v.value, normalizedType, variableName) + if (pathParts.length > 0) { - return navigatePath(value, pathParts, { executionContext: context.executionContext }) + return this.navigatePathAsync + ? this.navigatePathAsync(value, pathParts, context) + : navigatePath(value, pathParts, { + allowLargeValueRefs: context.allowLargeValueRefs, + executionContext: context.executionContext, + }) } + if (!context.allowLargeValueRefs) { + assertNoLargeValueRefs(value) + } return value } } return undefined } + + private resolveVariableValue( + value: any, + normalizedType: VariableType, + variableName: string + ): any { + if (isLargeValueRef(value) || isLargeArrayManifest(value)) { + return value + } + + try { + return VariableManager.resolveForExecution(value, normalizedType) + } catch (error) { + logger.warn('Failed to resolve workflow variable, returning raw value', { + variableName, + error: (error as Error).message, + }) + return value + } + } } diff --git a/apps/sim/lib/api/contracts/hotspots.ts b/apps/sim/lib/api/contracts/hotspots.ts index 4a3b92d371d..7ea571b23d7 100644 --- a/apps/sim/lib/api/contracts/hotspots.ts +++ b/apps/sim/lib/api/contracts/hotspots.ts @@ -104,6 +104,8 @@ export const functionExecuteContract = defineRouteContract({ workflowId: z.string().optional(), executionId: z.string().optional(), largeValueExecutionIds: z.array(z.string()).optional(), + largeValueKeys: z.array(z.string()).optional(), + fileKeys: z.array(z.string()).optional(), allowLargeValueWorkflowScope: z.boolean().optional(), workspaceId: z.string().optional(), userId: z.string().optional(), diff --git a/apps/sim/lib/copilot/tools/handlers/workflow/mutations.test.ts b/apps/sim/lib/copilot/tools/handlers/workflow/mutations.test.ts index 2a4cc44772a..c02c93c834e 100644 --- a/apps/sim/lib/copilot/tools/handlers/workflow/mutations.test.ts +++ b/apps/sim/lib/copilot/tools/handlers/workflow/mutations.test.ts @@ -3,10 +3,20 @@ */ import { beforeEach, describe, expect, it, vi } from 'vitest' -const { ensureWorkflowAccessMock, setWorkflowVariablesMock, recordAuditMock } = vi.hoisted(() => ({ +const { + ensureWorkflowAccessMock, + setWorkflowVariablesMock, + recordAuditMock, + executeWorkflowMock, + getExecutionStateForWorkflowMock, + getLatestExecutionStateWithExecutionIdMock, +} = vi.hoisted(() => ({ ensureWorkflowAccessMock: vi.fn(), setWorkflowVariablesMock: vi.fn(), recordAuditMock: vi.fn(), + executeWorkflowMock: vi.fn(), + getExecutionStateForWorkflowMock: vi.fn(), + getLatestExecutionStateWithExecutionIdMock: vi.fn(), })) vi.mock('@sim/audit', () => ({ @@ -37,12 +47,12 @@ vi.mock('@/lib/core/utils/urls', () => ({ })) vi.mock('@/lib/workflows/executor/execute-workflow', () => ({ - executeWorkflow: vi.fn(), + executeWorkflow: executeWorkflowMock, })) vi.mock('@/lib/workflows/executor/execution-state', () => ({ - getExecutionState: vi.fn(), - getLatestExecutionState: vi.fn(), + getExecutionStateForWorkflow: getExecutionStateForWorkflowMock, + getLatestExecutionStateWithExecutionId: getLatestExecutionStateWithExecutionIdMock, })) vi.mock('@/lib/workflows/orchestration', () => ({ @@ -79,7 +89,7 @@ vi.mock('../access', () => ({ getDefaultWorkspaceId: vi.fn(), })) -import { executeSetGlobalWorkflowVariables } from './mutations' +import { executeRunFromBlock, executeSetGlobalWorkflowVariables } from './mutations' describe('executeSetGlobalWorkflowVariables', () => { beforeEach(() => { @@ -124,3 +134,71 @@ describe('executeSetGlobalWorkflowVariables', () => { expect(recordAuditMock).toHaveBeenCalled() }) }) + +describe('executeRunFromBlock', () => { + beforeEach(() => { + vi.clearAllMocks() + ensureWorkflowAccessMock.mockResolvedValue({ + workflow: { + id: 'workflow-1', + userId: 'owner-1', + workspaceId: 'workspace-1', + variables: {}, + }, + }) + executeWorkflowMock.mockResolvedValue({ + success: true, + output: {}, + logs: [], + metadata: { executionId: 'new-execution-1' }, + }) + }) + + it('passes source execution lineage for stored run-from-block snapshots', async () => { + const sourceSnapshot = { + blockStates: { + upstream: { + output: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'object', + size: 10, + key: 'execution/workspace-1/workflow-1/source-execution-1/large-value-lv_ABCDEFGHIJKL.json', + executionId: 'source-execution-1', + }, + }, + }, + executedBlocks: [], + blockLogs: [], + decisions: {}, + completedLoops: [], + activeExecutionPath: [], + } + getExecutionStateForWorkflowMock.mockResolvedValue(sourceSnapshot) + + const result = await executeRunFromBlock( + { + workflowId: 'workflow-1', + startBlockId: 'agent-1', + executionId: 'source-execution-1', + }, + { userId: 'user-1' } as any + ) + + expect(result.success).toBe(true) + expect(executeWorkflowMock).toHaveBeenCalledWith( + expect.any(Object), + 'request-1', + undefined, + 'user-1', + expect.objectContaining({ + runFromBlock: { + startBlockId: 'agent-1', + sourceSnapshot, + sourceExecutionId: 'source-execution-1', + }, + }) + ) + }) +}) diff --git a/apps/sim/lib/copilot/tools/handlers/workflow/mutations.ts b/apps/sim/lib/copilot/tools/handlers/workflow/mutations.ts index e2e1b5752be..9c450f56268 100644 --- a/apps/sim/lib/copilot/tools/handlers/workflow/mutations.ts +++ b/apps/sim/lib/copilot/tools/handlers/workflow/mutations.ts @@ -11,8 +11,8 @@ import { generateRequestId } from '@/lib/core/utils/request' import { getSocketServerUrl } from '@/lib/core/utils/urls' import { executeWorkflow } from '@/lib/workflows/executor/execute-workflow' import { - getExecutionState, - getLatestExecutionState, + getExecutionStateForWorkflow, + getLatestExecutionStateWithExecutionId, } from '@/lib/workflows/executor/execution-state' import { performCreateFolder, @@ -28,6 +28,7 @@ import { } from '@/lib/workflows/persistence/utils' import { sanitizeForCopilot } from '@/lib/workflows/sanitization/json-sanitizer' import { listFolders, setWorkflowVariables, verifyFolderWorkspace } from '@/lib/workflows/utils' +import type { SerializableExecutionState } from '@/executor/execution/types' import { hasExecutionResult } from '@/executor/utils/errors' import type { BlockState, WorkflowState } from '@/stores/workflows/workflow/types' import { ensureWorkflowAccess, ensureWorkspaceAccess, getDefaultWorkspaceId } from '../access' @@ -79,6 +80,33 @@ function buildExecutionError(error: unknown): ToolCallResult { return { success: false, error: message } } +async function resolveRunFromBlockSnapshot( + workflowId: string, + executionId?: string +): Promise< + | { + executionId: string + snapshot: SerializableExecutionState + } + | undefined +> { + const sourceExecution = executionId + ? { + executionId, + state: await getExecutionStateForWorkflow(executionId, workflowId), + } + : await getLatestExecutionStateWithExecutionId(workflowId) + + if (!sourceExecution?.state) { + return undefined + } + + return { + executionId: sourceExecution.executionId, + snapshot: sourceExecution.state, + } +} + function resolveRunWorkflowInput(params: { workflow_input?: unknown; input?: unknown }): unknown { if (Object.hasOwn(params, 'workflow_input')) { return params.workflow_input @@ -710,11 +738,9 @@ export async function executeRunFromBlock( return { success: false, error: 'startBlockId is required' } } - const snapshot = params.executionId - ? await getExecutionState(params.executionId) - : await getLatestExecutionState(workflowId) + const sourceSnapshot = await resolveRunFromBlockSnapshot(workflowId, params.executionId) - if (!snapshot) { + if (!sourceSnapshot) { return { success: false, error: params.executionId @@ -744,7 +770,11 @@ export async function executeRunFromBlock( enabled: true, useDraftState, workflowTriggerType: 'copilot', - runFromBlock: { startBlockId: params.startBlockId, sourceSnapshot: snapshot }, + runFromBlock: { + startBlockId: params.startBlockId, + sourceSnapshot: sourceSnapshot.snapshot, + sourceExecutionId: sourceSnapshot.executionId, + }, } ) @@ -1084,11 +1114,9 @@ export async function executeRunBlock( return { success: false, error: 'blockId is required' } } - const snapshot = params.executionId - ? await getExecutionState(params.executionId) - : await getLatestExecutionState(workflowId) + const sourceSnapshot = await resolveRunFromBlockSnapshot(workflowId, params.executionId) - if (!snapshot) { + if (!sourceSnapshot) { return { success: false, error: params.executionId @@ -1118,7 +1146,11 @@ export async function executeRunBlock( enabled: true, useDraftState, workflowTriggerType: 'copilot', - runFromBlock: { startBlockId: params.blockId, sourceSnapshot: snapshot }, + runFromBlock: { + startBlockId: params.blockId, + sourceSnapshot: sourceSnapshot.snapshot, + sourceExecutionId: sourceSnapshot.executionId, + }, stopAfterBlockId: params.blockId, } ) diff --git a/apps/sim/lib/core/utils/response-format.test.ts b/apps/sim/lib/core/utils/response-format.test.ts new file mode 100644 index 00000000000..7a8189aed4d --- /dev/null +++ b/apps/sim/lib/core/utils/response-format.test.ts @@ -0,0 +1,58 @@ +/** + * @vitest-environment node + */ +import { describe, expect, it } from 'vitest' +import { extractFieldValues, traverseObjectPath } from '@/lib/core/utils/response-format' +import { + LARGE_ARRAY_MANIFEST_VERSION, + type LargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest-metadata' + +function createManifest(totalCount = 100_000): LargeArrayManifest { + return { + __simLargeArrayManifest: true, + version: LARGE_ARRAY_MANIFEST_VERSION, + kind: 'array', + totalCount, + chunkCount: 1, + byteSize: 12 * 1024 * 1024, + chunks: [ + { + count: totalCount, + byteSize: 12 * 1024 * 1024, + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 12 * 1024 * 1024, + executionId: 'execution-1', + }, + }, + ], + preview: [{ key: 'SIM-0' }], + } +} + +describe('response format traversal', () => { + it('returns whole large array manifest metadata without materializing chunks', () => { + const manifest = createManifest() + + expect(traverseObjectPath({ output: { rows: manifest } }, 'output.rows')).toEqual(manifest) + }) + + it('returns manifest totalCount for length selections', () => { + const manifest = createManifest() + + expect(traverseObjectPath({ output: { rows: manifest } }, 'output.rows.length')).toBe(100_000) + expect( + extractFieldValues({ output: { rows: manifest } }, ['block-1_output.rows.length'], 'block-1') + ).toEqual({ 'output.rows.length': 100_000 }) + }) + + it('does not perform indexed manifest reads in sync traversal', () => { + const manifest = createManifest() + + expect(traverseObjectPath({ output: { rows: manifest } }, 'output.rows.0.key')).toBeUndefined() + }) +}) diff --git a/apps/sim/lib/core/utils/response-format.ts b/apps/sim/lib/core/utils/response-format.ts index 7512cc50b59..97a57d0e72c 100644 --- a/apps/sim/lib/core/utils/response-format.ts +++ b/apps/sim/lib/core/utils/response-format.ts @@ -1,5 +1,6 @@ import { createLogger } from '@sim/logger' import { materializeLargeValueRefSyncOrThrow } from '@/lib/execution/payloads/cache' +import { isLargeArrayManifest } from '@/lib/execution/payloads/large-array-manifest-metadata' import { isLargeValueRef } from '@/lib/execution/payloads/large-value-ref' const logger = createLogger('ResponseFormatUtils') @@ -202,6 +203,18 @@ function traverseObjectPathInternal(obj: any, path: string): any { current = materializeLargeValueRefSyncOrThrow(current) } + if (isLargeArrayManifest(current)) { + if (part === 'length' || part === 'totalCount') { + current = current.totalCount + continue + } + if (part === 'chunkCount' || part === 'byteSize' || part === 'preview') { + current = current[part] + continue + } + return undefined + } + if (current?.[part] !== undefined) { current = current[part] } else { diff --git a/apps/sim/lib/core/utils/user-file.ts b/apps/sim/lib/core/utils/user-file.ts index deee12cbf04..abcac62da98 100644 --- a/apps/sim/lib/core/utils/user-file.ts +++ b/apps/sim/lib/core/utils/user-file.ts @@ -42,6 +42,42 @@ export function isUserFileWithMetadata(value: unknown): value is UserFile { return typeof candidate.size === 'number' && typeof candidate.type === 'string' } +/** + * Finds storage keys for UserFile objects embedded in a value. + */ +export function collectUserFileKeys(value: unknown): string[] { + const keys = new Set() + collectUserFileKeysInto(value, keys, new WeakSet()) + return Array.from(keys) +} + +function collectUserFileKeysInto(value: unknown, keys: Set, seen: WeakSet): void { + if (!value || typeof value !== 'object') { + return + } + + if (seen.has(value)) { + return + } + seen.add(value) + + if (isUserFileWithMetadata(value)) { + keys.add(value.key) + return + } + + if (Array.isArray(value)) { + for (const item of value) { + collectUserFileKeysInto(item, keys, seen) + } + return + } + + for (const item of Object.values(value)) { + collectUserFileKeysInto(item, keys, seen) + } +} + /** * Checks if a value matches the display-safe UserFile metadata shape after internal fields are stripped. */ diff --git a/apps/sim/lib/execution/isolated-vm-worker.cjs b/apps/sim/lib/execution/isolated-vm-worker.cjs index a924beb8dfe..e3accb99efd 100644 --- a/apps/sim/lib/execution/isolated-vm-worker.cjs +++ b/apps/sim/lib/execution/isolated-vm-worker.cjs @@ -384,6 +384,7 @@ async function executeCode(request, executionId) { }), values: Object.freeze({ read: (ref, options) => callSimBroker('sim.values.read', { ref, options }), + readArray: (ref, options) => callSimBroker('sim.values.readArray', { ref, options }), }), }); })(); diff --git a/apps/sim/lib/execution/payloads/access-keys.ts b/apps/sim/lib/execution/payloads/access-keys.ts new file mode 100644 index 00000000000..23fce0d1a82 --- /dev/null +++ b/apps/sim/lib/execution/payloads/access-keys.ts @@ -0,0 +1,41 @@ +import { collectUserFileKeys } from '@/lib/core/utils/user-file' +import { collectLargeValueKeys } from '@/lib/execution/payloads/large-execution-value' + +export interface ExactAccessKeyContext { + largeValueKeys?: string[] + fileKeys?: string[] +} + +export function mergeUniqueKeys(target: string[], source: readonly string[]): void { + if (source.length === 0) { + return + } + const existingKeys = new Set(target) + for (const key of source) { + if (!existingKeys.has(key)) { + existingKeys.add(key) + target.push(key) + } + } +} + +export function mergeLargeValueKeys(context: ExactAccessKeyContext, keys: readonly string[]): void { + if (keys.length === 0) { + return + } + context.largeValueKeys ??= [] + mergeUniqueKeys(context.largeValueKeys, keys) +} + +export function mergeFileKeys(context: ExactAccessKeyContext, keys: readonly string[]): void { + if (keys.length === 0) { + return + } + context.fileKeys ??= [] + mergeUniqueKeys(context.fileKeys, keys) +} + +export function recordMaterializedAccessKeys(context: ExactAccessKeyContext, value: unknown): void { + mergeLargeValueKeys(context, collectLargeValueKeys(value)) + mergeFileKeys(context, collectUserFileKeys(value)) +} diff --git a/apps/sim/lib/execution/payloads/cache.ts b/apps/sim/lib/execution/payloads/cache.ts index 507a8dd4ccc..523da8282da 100644 --- a/apps/sim/lib/execution/payloads/cache.ts +++ b/apps/sim/lib/execution/payloads/cache.ts @@ -12,6 +12,7 @@ interface LargeValueCacheScope { workflowId?: string executionId?: string largeValueExecutionIds?: string[] + largeValueKeys?: string[] allowLargeValueWorkflowScope?: boolean } @@ -108,6 +109,9 @@ function scopeMatchesRef( callerScope.executionId, ...(callerScope.largeValueExecutionIds ?? []), ]) + if (ref.key && callerScope.largeValueKeys?.includes(ref.key)) { + return true + } const workflowScopeAllowed = callerScope.allowLargeValueWorkflowScope && callerScope.workspaceId === cachedScope.workspaceId && diff --git a/apps/sim/lib/execution/payloads/hydration.test.ts b/apps/sim/lib/execution/payloads/hydration.test.ts new file mode 100644 index 00000000000..cc8fdf0423a --- /dev/null +++ b/apps/sim/lib/execution/payloads/hydration.test.ts @@ -0,0 +1,144 @@ +/** + * @vitest-environment node + */ +import { beforeEach, describe, expect, it, vi } from 'vitest' + +const { mockMaterializeLargeValueRef } = vi.hoisted(() => ({ + mockMaterializeLargeValueRef: vi.fn(), +})) + +vi.mock('@/lib/execution/payloads/store', () => ({ + materializeLargeValueRef: mockMaterializeLargeValueRef, +})) + +import { warmLargeValueRefs } from '@/lib/execution/payloads/hydration' + +describe('warmLargeValueRefs', () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + it('does not warm manifest chunks before explicit navigation', async () => { + const chunkRef = { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 16, + executionId: 'execution-1', + } + const manifest = { + __simLargeArrayManifest: true, + version: 2, + kind: 'array', + totalCount: 1, + chunkCount: 1, + byteSize: 16, + chunks: [ + { + ref: chunkRef, + count: 1, + byteSize: 16, + }, + ], + preview: [], + } + + await warmLargeValueRefs({ issues: manifest }, { executionId: 'execution-1' }) + + expect(mockMaterializeLargeValueRef).not.toHaveBeenCalled() + }) + + it('records exact keys discovered while warming manifest preview refs', async () => { + const previewRef = { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'object', + size: 16, + key: 'execution/workspace-1/workflow-1/source-execution/large-value-lv_ABCDEFGHIJKL.json', + executionId: 'source-execution', + } + const nestedRef = { + __simLargeValueRef: true, + version: 1, + id: 'lv_MNOPQRSTUVWX', + kind: 'object', + size: 16, + key: 'execution/workspace-1/workflow-1/source-execution/large-value-lv_MNOPQRSTUVWX.json', + executionId: 'source-execution', + } + const file = { + id: 'file-1', + name: 'nested.txt', + key: 'execution/workspace-1/workflow-1/source-execution/nested.txt', + url: '/api/files/serve/execution/workspace-1/workflow-1/source-execution/nested.txt?context=execution', + size: 5, + type: 'text/plain', + context: 'execution', + } + const manifest = { + __simLargeArrayManifest: true, + version: 2, + kind: 'array', + totalCount: 1, + chunkCount: 1, + byteSize: 16, + chunks: [ + { + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_CHUNKREF0001', + kind: 'array', + size: 16, + executionId: 'source-execution', + }, + count: 1, + byteSize: 16, + }, + ], + preview: [previewRef], + } + const context = { + executionId: 'execution-1', + largeValueKeys: [] as string[], + fileKeys: [] as string[], + } + mockMaterializeLargeValueRef.mockResolvedValueOnce([{ nestedRef, file }]) + + await warmLargeValueRefs({ issues: manifest }, context) + + expect(mockMaterializeLargeValueRef).toHaveBeenCalledWith(previewRef, context) + expect(context.largeValueKeys).toEqual([nestedRef.key]) + expect(context.fileKeys).toEqual([file.key]) + }) + + it('warms manifest preview refs without exposing chunk internals as navigable metadata', async () => { + const previewRef = { + __simLargeValueRef: true, + version: 1, + id: 'lv_PREVIEWREF01', + kind: 'object', + size: 16, + executionId: 'execution-1', + } + const manifest = { + __simLargeArrayManifest: true, + version: 2, + kind: 'array', + totalCount: 0, + chunkCount: 0, + byteSize: 0, + chunks: [], + preview: [previewRef], + } + mockMaterializeLargeValueRef.mockResolvedValueOnce({ key: 'SIM-1' }) + + await warmLargeValueRefs({ issues: manifest }, { executionId: 'execution-1' }) + + expect(mockMaterializeLargeValueRef).toHaveBeenCalledWith(previewRef, { + executionId: 'execution-1', + }) + }) +}) diff --git a/apps/sim/lib/execution/payloads/hydration.ts b/apps/sim/lib/execution/payloads/hydration.ts index bfc825280ae..4ba2553e5bc 100644 --- a/apps/sim/lib/execution/payloads/hydration.ts +++ b/apps/sim/lib/execution/payloads/hydration.ts @@ -1,9 +1,23 @@ +import { recordMaterializedAccessKeys } from '@/lib/execution/payloads/access-keys' +import { isLargeArrayManifest } from '@/lib/execution/payloads/large-array-manifest-metadata' import { isLargeValueRef } from '@/lib/execution/payloads/large-value-ref' import { type LargeValueStoreContext, materializeLargeValueRef, } from '@/lib/execution/payloads/store' +function withLocalMaterializedKeys( + context: LargeValueStoreContext, + materializedValue: unknown +): LargeValueStoreContext { + recordMaterializedAccessKeys(context, materializedValue) + return { + ...context, + largeValueKeys: context.largeValueKeys, + fileKeys: context.fileKeys, + } +} + export async function warmLargeValueRefs( value: unknown, context: LargeValueStoreContext = {}, @@ -15,7 +29,7 @@ export async function warmLargeValueRefs( if (isLargeValueRef(value)) { const materialized = await materializeLargeValueRef(value, context) - await warmLargeValueRefs(materialized, context, seen) + await warmLargeValueRefs(materialized, withLocalMaterializedKeys(context, materialized), seen) return } @@ -24,12 +38,19 @@ export async function warmLargeValueRefs( } seen.add(value) + if (isLargeArrayManifest(value)) { + await warmLargeValueRefs(value.preview, context, seen) + return + } + if (Array.isArray(value)) { - await Promise.all(value.map((item) => warmLargeValueRefs(item, context, seen))) + for (const item of value) { + await warmLargeValueRefs(item, context, seen) + } return } - await Promise.all( - Object.values(value).map((entryValue) => warmLargeValueRefs(entryValue, context, seen)) - ) + for (const entryValue of Object.values(value)) { + await warmLargeValueRefs(entryValue, context, seen) + } } diff --git a/apps/sim/lib/execution/payloads/inline-materialization.server.ts b/apps/sim/lib/execution/payloads/inline-materialization.server.ts new file mode 100644 index 00000000000..3cd56f010fb --- /dev/null +++ b/apps/sim/lib/execution/payloads/inline-materialization.server.ts @@ -0,0 +1,167 @@ +import { recordMaterializedAccessKeys } from '@/lib/execution/payloads/access-keys' +import { + isLargeArrayManifest, + materializeLargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest' +import { + getLargeValueMaterializationError, + isLargeValueRef, +} from '@/lib/execution/payloads/large-value-ref' +import { + assertInlineMaterializationSize, + type ExecutionMaterializationContext, + MAX_INLINE_MATERIALIZATION_BYTES, +} from '@/lib/execution/payloads/materialization.server' +import { materializeLargeValueRef } from '@/lib/execution/payloads/store' + +interface InlineMaterializationOptions { + maxBytes?: number +} + +type InlineMaterializationMemo = WeakMap> + +interface MaterializedInlineValue { + value: unknown + byteLength: number | undefined +} + +export function getInlineJsonByteLength(value: unknown): number | undefined { + const json = JSON.stringify(value) + return json === undefined ? undefined : Buffer.byteLength(json, 'utf8') +} + +function getArrayItemByteLength(value: MaterializedInlineValue): number { + return value.byteLength ?? Buffer.byteLength('null', 'utf8') +} + +function getObjectEntryByteLength(key: string, value: MaterializedInlineValue): number | undefined { + if (value.byteLength === undefined) { + return undefined + } + return Buffer.byteLength(JSON.stringify(key), 'utf8') + 1 + value.byteLength +} + +function withMaterializedAccessKeys( + context: ExecutionMaterializationContext | undefined, + materializedValue: unknown +): ExecutionMaterializationContext | undefined { + if (!context) { + return context + } + recordMaterializedAccessKeys(context, materializedValue) + return { + ...context, + largeValueKeys: context.largeValueKeys, + fileKeys: context.fileKeys, + } +} + +export async function materializeInlineExecutionValue( + value: unknown, + context: ExecutionMaterializationContext | undefined, + options: InlineMaterializationOptions = {} +): Promise { + const materialized = await materializeInlineExecutionValueWithinBudget( + value, + context, + options.maxBytes ?? MAX_INLINE_MATERIALIZATION_BYTES, + new WeakMap>() + ) + return materialized.value +} + +async function materializeInlineExecutionValueWithinBudget( + value: unknown, + context: ExecutionMaterializationContext | undefined, + maxBytes: number, + memo: InlineMaterializationMemo +): Promise { + if (isLargeArrayManifest(value)) { + assertInlineMaterializationSize(value.byteSize, maxBytes) + const materialized = await materializeLargeArrayManifest(value, { + ...context, + maxBytes, + }) + return materializeInlineExecutionValueWithinBudget( + materialized, + withMaterializedAccessKeys(context, materialized), + maxBytes, + memo + ) + } + + if (isLargeValueRef(value)) { + assertInlineMaterializationSize(value.size, maxBytes) + const materialized = await materializeLargeValueRef(value, { + ...context, + maxBytes, + }) + if (materialized === undefined) { + throw getLargeValueMaterializationError(value) + } + return materializeInlineExecutionValueWithinBudget( + materialized, + withMaterializedAccessKeys(context, materialized), + maxBytes, + memo + ) + } + + if (!value || typeof value !== 'object') { + const valueBytes = getInlineJsonByteLength(value) + if (valueBytes !== undefined) { + assertInlineMaterializationSize(valueBytes, maxBytes) + } + return { value, byteLength: valueBytes } + } + + const cached = memo.get(value) + if (cached) { + return { value: await cached, byteLength: 0 } + } + + if (Array.isArray(value)) { + const result: unknown[] = [] + memo.set(value, Promise.resolve(result)) + let usedBytes = Buffer.byteLength('[]', 'utf8') + for (const item of value) { + const commaBytes = result.length > 0 ? 1 : 0 + const remainingBytes = maxBytes - usedBytes - commaBytes + assertInlineMaterializationSize(0, remainingBytes) + const materializedItem = await materializeInlineExecutionValueWithinBudget( + item, + context, + remainingBytes, + memo + ) + const itemBytes = getArrayItemByteLength(materializedItem) + usedBytes += commaBytes + itemBytes + assertInlineMaterializationSize(usedBytes, maxBytes) + result.push(materializedItem.value) + } + return { value: result, byteLength: usedBytes } + } + + const result: Record = {} + memo.set(value, Promise.resolve(result)) + let usedBytes = Buffer.byteLength('{}', 'utf8') + for (const [key, entryValue] of Object.entries(value as Record)) { + const keyBytes = Buffer.byteLength(JSON.stringify(key), 'utf8') + 1 + const commaBytes = Object.keys(result).length > 0 ? 1 : 0 + const remainingBytes = maxBytes - usedBytes - commaBytes - keyBytes + assertInlineMaterializationSize(0, remainingBytes) + const materializedEntryValue = await materializeInlineExecutionValueWithinBudget( + entryValue, + context, + remainingBytes, + memo + ) + const entryBytes = getObjectEntryByteLength(key, materializedEntryValue) + if (entryBytes !== undefined) { + usedBytes += commaBytes + entryBytes + assertInlineMaterializationSize(usedBytes, maxBytes) + } + result[key] = materializedEntryValue.value + } + return { value: result, byteLength: usedBytes } +} diff --git a/apps/sim/lib/execution/payloads/large-array-manifest-metadata.ts b/apps/sim/lib/execution/payloads/large-array-manifest-metadata.ts new file mode 100644 index 00000000000..f7c23408925 --- /dev/null +++ b/apps/sim/lib/execution/payloads/large-array-manifest-metadata.ts @@ -0,0 +1,80 @@ +import { isLargeValueRef, type LargeValueRef } from '@/lib/execution/payloads/large-value-ref' + +export const LARGE_ARRAY_MANIFEST_MARKER = '__simLargeArrayManifest' +export const LARGE_ARRAY_MANIFEST_VERSION = 2 +export const LARGE_ARRAY_MANIFEST_PREVIEW_MAX_BYTES = 16 * 1024 + +export interface LargeArrayManifest { + [LARGE_ARRAY_MANIFEST_MARKER]: true + version: typeof LARGE_ARRAY_MANIFEST_VERSION + kind: 'array' + totalCount: number + chunkCount: number + byteSize: number + chunks: LargeArrayManifestChunk[] + preview: unknown[] +} + +export interface LargeArrayManifestChunk { + ref: LargeValueRef + count: number + byteSize: number +} + +function isValidCount(value: unknown): value is number { + return typeof value === 'number' && Number.isInteger(value) && value >= 0 +} + +function isValidByteSize(value: unknown): value is number { + return typeof value === 'number' && Number.isFinite(value) && value >= 0 +} + +function isValidPreview(value: unknown): value is unknown[] { + return Array.isArray(value) && value.length <= 3 +} + +export function isLargeArrayManifest(value: unknown): value is LargeArrayManifest { + if (!value || typeof value !== 'object') { + return false + } + + const candidate = value as Record + if ( + candidate[LARGE_ARRAY_MANIFEST_MARKER] !== true || + candidate.version !== LARGE_ARRAY_MANIFEST_VERSION || + candidate.kind !== 'array' || + !isValidCount(candidate.totalCount) || + !isValidCount(candidate.chunkCount) || + !isValidByteSize(candidate.byteSize) || + !Array.isArray(candidate.chunks) || + !isValidPreview(candidate.preview) || + candidate.chunkCount !== candidate.chunks.length + ) { + return false + } + + let totalCount = 0 + let byteSize = 0 + for (const chunk of candidate.chunks) { + if (!chunk || typeof chunk !== 'object') { + return false + } + + const chunkRecord = chunk as Record + if ( + !isLargeValueRef(chunkRecord.ref) || + !isValidCount(chunkRecord.count) || + chunkRecord.count <= 0 || + !isValidByteSize(chunkRecord.byteSize) || + chunkRecord.byteSize <= 0 || + chunkRecord.byteSize !== chunkRecord.ref.size + ) { + return false + } + + totalCount += chunkRecord.count + byteSize += chunkRecord.ref.size + } + + return candidate.totalCount === totalCount && candidate.byteSize === byteSize +} diff --git a/apps/sim/lib/execution/payloads/large-array-manifest.test.ts b/apps/sim/lib/execution/payloads/large-array-manifest.test.ts new file mode 100644 index 00000000000..f0ef0e3468c --- /dev/null +++ b/apps/sim/lib/execution/payloads/large-array-manifest.test.ts @@ -0,0 +1,183 @@ +/** + * @vitest-environment node + */ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { clearLargeValueCacheForTests } from '@/lib/execution/payloads/cache' +import { + appendLargeArrayManifest, + createLargeArrayManifest, + isLargeArrayManifest, + materializeLargeArrayManifest, + readLargeArrayManifestSlice, +} from '@/lib/execution/payloads/large-array-manifest' +import { EXECUTION_RESOURCE_LIMIT_CODE } from '@/lib/execution/resource-errors' + +const { mockDownloadFile, mockUploadFile } = vi.hoisted(() => ({ + mockDownloadFile: vi.fn(), + mockUploadFile: vi.fn(), +})) + +vi.mock('@/lib/uploads', () => ({ + StorageService: { + downloadFile: mockDownloadFile, + uploadFile: mockUploadFile, + }, +})) + +const TEST_CONTEXT = { + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + executionId: 'execution-1', + userId: 'user-1', +} + +describe('large array manifests', () => { + beforeEach(() => { + vi.clearAllMocks() + clearLargeValueCacheForTests() + mockDownloadFile.mockReset() + mockUploadFile.mockImplementation(async ({ customKey }) => ({ key: customKey })) + }) + + it('creates a manifest with one chunk for the first page', async () => { + const manifest = await createLargeArrayManifest([{ id: 1 }, { id: 2 }], TEST_CONTEXT) + + expect(isLargeArrayManifest(manifest)).toBe(true) + expect(manifest).toMatchObject({ + __simLargeArrayManifest: true, + kind: 'array', + totalCount: 2, + chunkCount: 1, + preview: [{ id: 1 }, { id: 2 }], + }) + expect(manifest.chunks).toEqual([ + expect.objectContaining({ count: 2, byteSize: expect.any(Number) }), + ]) + expect(mockUploadFile).toHaveBeenCalledTimes(1) + }) + + it('appends pages without materializing previous chunks', async () => { + const firstPage = await createLargeArrayManifest([{ id: 1 }], TEST_CONTEXT) + clearLargeValueCacheForTests() + + const manifest = await appendLargeArrayManifest(firstPage, [{ id: 2 }, { id: 3 }], TEST_CONTEXT) + + expect(manifest.totalCount).toBe(3) + expect(manifest.chunkCount).toBe(2) + expect(manifest.chunks).toHaveLength(2) + expect(mockUploadFile).toHaveBeenCalledTimes(2) + }) + + it('reads a bounded slice from only requested positions', async () => { + let manifest = await createLargeArrayManifest([{ id: 1 }, { id: 2 }], TEST_CONTEXT) + manifest = await appendLargeArrayManifest(manifest, [{ id: 3 }, { id: 4 }], TEST_CONTEXT) + + await expect(readLargeArrayManifestSlice(manifest, 1, 2, TEST_CONTEXT)).resolves.toEqual([ + { id: 2 }, + { id: 3 }, + ]) + }) + + it('splits oversized pages into bounded chunks', async () => { + const manifest = await createLargeArrayManifest( + [ + { id: 1, payload: 'x'.repeat(80) }, + { id: 2, payload: 'y'.repeat(80) }, + { id: 3, payload: 'z'.repeat(80) }, + ], + { ...TEST_CONTEXT, chunkTargetBytes: 128 } + ) + + expect(manifest.totalCount).toBe(3) + expect(manifest.chunkCount).toBe(3) + expect(manifest.chunks.map((chunk) => chunk.count)).toEqual([1, 1, 1]) + expect(mockUploadFile).toHaveBeenCalledTimes(3) + }) + + it('chunks arrays with undefined entries using JSON array semantics', async () => { + const manifest = await createLargeArrayManifest([{ id: 1 }, undefined, { id: 3 }], { + ...TEST_CONTEXT, + chunkTargetBytes: 16, + }) + + expect(manifest.totalCount).toBe(3) + await expect(readLargeArrayManifestSlice(manifest, 1, 1, TEST_CONTEXT)).resolves.toEqual([ + undefined, + ]) + }) + + it('reports non-serializable chunk values with a manifest-specific error', async () => { + const circular: Record = { id: 1 } + circular.self = circular + + await expect(createLargeArrayManifest([circular], TEST_CONTEXT)).rejects.toThrow( + 'Large array manifest chunks must be JSON-serializable.' + ) + await expect(createLargeArrayManifest([{ id: 1n }], TEST_CONTEXT)).rejects.toThrow( + 'Large array manifest chunks must be JSON-serializable.' + ) + }) + + it('skips preceding chunks without materializing them for bounded reads', async () => { + let manifest = await createLargeArrayManifest([{ id: 1 }, { id: 2 }], TEST_CONTEXT) + manifest = await appendLargeArrayManifest(manifest, [{ id: 3 }, { id: 4 }], TEST_CONTEXT) + clearLargeValueCacheForTests() + mockDownloadFile.mockImplementation(async ({ key }) => { + expect(key).toBe(manifest.chunks[1].ref.key) + return Buffer.from(JSON.stringify([{ id: 3 }, { id: 4 }])) + }) + + await expect(readLargeArrayManifestSlice(manifest, 2, 1, TEST_CONTEXT)).resolves.toEqual([ + { id: 3 }, + ]) + expect(mockDownloadFile).toHaveBeenCalledTimes(1) + }) + + it('bounds full materialization by byte size', async () => { + const manifest = await createLargeArrayManifest([{ id: 1, payload: 'x'.repeat(2048) }], { + ...TEST_CONTEXT, + }) + + await expect( + materializeLargeArrayManifest(manifest, { ...TEST_CONTEXT, maxBytes: 256 }) + ).rejects.toMatchObject({ code: EXECUTION_RESOURCE_LIMIT_CODE }) + }) + + it('rejects manifests with understated aggregate byte size', async () => { + const manifest = await createLargeArrayManifest([{ id: 1, payload: 'x'.repeat(2048) }], { + ...TEST_CONTEXT, + }) + + await expect( + materializeLargeArrayManifest({ ...manifest, byteSize: 1 }, { ...TEST_CONTEXT }) + ).rejects.toThrow('Invalid large array manifest') + }) + + it('rejects manifests whose chunk count does not match materialized data', async () => { + const manifest = await createLargeArrayManifest([{ id: 1 }], TEST_CONTEXT) + const forgedManifest = { + ...manifest, + totalCount: 2, + chunks: [{ ...manifest.chunks[0], count: 2 }], + } + + expect(isLargeArrayManifest(forgedManifest)).toBe(true) + await expect(readLargeArrayManifestSlice(forgedManifest, 1, 1, TEST_CONTEXT)).rejects.toThrow( + 'Large array manifest chunk count does not match materialized data' + ) + }) + + it('does not serialize preview metadata during hot type-guard checks', async () => { + const manifest = await createLargeArrayManifest([{ id: 1 }], TEST_CONTEXT) + const stringifySpy = vi.spyOn(JSON, 'stringify') + + expect( + isLargeArrayManifest({ + ...manifest, + preview: [{ payload: 'x'.repeat(20 * 1024) }], + }) + ).toBe(true) + expect(stringifySpy).not.toHaveBeenCalled() + stringifySpy.mockRestore() + }) +}) diff --git a/apps/sim/lib/execution/payloads/large-array-manifest.ts b/apps/sim/lib/execution/payloads/large-array-manifest.ts new file mode 100644 index 00000000000..62bcd856eba --- /dev/null +++ b/apps/sim/lib/execution/payloads/large-array-manifest.ts @@ -0,0 +1,250 @@ +import { + isLargeArrayManifest, + LARGE_ARRAY_MANIFEST_PREVIEW_MAX_BYTES, + LARGE_ARRAY_MANIFEST_VERSION, + type LargeArrayManifest, + type LargeArrayManifestChunk, +} from '@/lib/execution/payloads/large-array-manifest-metadata' +import { + assertInlineMaterializationSize, + MAX_INLINE_MATERIALIZATION_BYTES, +} from '@/lib/execution/payloads/materialization.server' +import type { LargeValueStoreContext } from '@/lib/execution/payloads/store' +import { materializeLargeValueRef, storeLargeValue } from '@/lib/execution/payloads/store' + +export { + isLargeArrayManifest, + LARGE_ARRAY_MANIFEST_MARKER, + LARGE_ARRAY_MANIFEST_PREVIEW_MAX_BYTES, + LARGE_ARRAY_MANIFEST_VERSION, + type LargeArrayManifest, + type LargeArrayManifestChunk, +} from '@/lib/execution/payloads/large-array-manifest-metadata' + +export const LARGE_ARRAY_MANIFEST_CHUNK_TARGET_BYTES = Math.floor( + MAX_INLINE_MATERIALIZATION_BYTES / 2 +) +const LARGE_ARRAY_MANIFEST_JSON_SERIALIZATION_ERROR = + 'Large array manifest chunks must be JSON-serializable.' + +export interface LargeArrayManifestReadOptions extends LargeValueStoreContext { + maxBytes?: number +} + +export interface LargeArrayManifestWriteOptions extends LargeValueStoreContext { + chunkTargetBytes?: number +} + +function measureJson(value: unknown): { json: string; size: number } { + let json: string | undefined + try { + json = JSON.stringify(value) + } catch { + throw new Error(LARGE_ARRAY_MANIFEST_JSON_SERIALIZATION_ERROR) + } + if (json === undefined) { + throw new Error(LARGE_ARRAY_MANIFEST_JSON_SERIALIZATION_ERROR) + } + return { json, size: Buffer.byteLength(json, 'utf8') } +} + +function assertArray(value: unknown): asserts value is unknown[] { + if (!Array.isArray(value)) { + throw new Error('Large array manifest chunks must materialize to arrays.') + } +} + +function assertChunkCount(chunk: unknown[], expectedCount: number): void { + if (chunk.length !== expectedCount) { + throw new Error('Large array manifest chunk count does not match materialized data.') + } +} + +function getPreview(items: unknown[]): unknown[] { + const preview: unknown[] = [] + for (const item of items.slice(0, 3)) { + const candidate = [...preview, item] + try { + if (measureJson(candidate).size > LARGE_ARRAY_MANIFEST_PREVIEW_MAX_BYTES) { + break + } + } catch { + break + } + preview.push(item) + } + return preview +} + +function measureArrayElementJsonSize(item: unknown): number { + const measured = measureJson([item]) + return Math.max(0, measured.size - 2) +} + +async function storeArrayChunk( + items: unknown[], + context: LargeArrayManifestWriteOptions +): Promise { + const measured = measureJson(items) + const ref = await storeLargeValue(items, measured.json, measured.size, { + ...context, + requireDurable: true, + }) + return { ref, count: items.length, byteSize: measured.size } +} + +function chunkArrayItems(items: unknown[], targetBytes: number): unknown[][] { + const chunks: unknown[][] = [] + let current: unknown[] = [] + let currentBytes = 2 + + for (const item of items) { + const itemBytes = measureArrayElementJsonSize(item) + const separatorBytes = current.length > 0 ? 1 : 0 + if (current.length > 0 && currentBytes + separatorBytes + itemBytes > targetBytes) { + chunks.push(current) + current = [] + currentBytes = 2 + } + + current.push(item) + currentBytes += (current.length > 1 ? 1 : 0) + itemBytes + } + + if (current.length > 0) { + chunks.push(current) + } + + return chunks +} + +async function storeArrayChunks( + items: unknown[], + context: LargeArrayManifestWriteOptions +): Promise { + const targetBytes = Math.max( + 2, + Math.min( + context.chunkTargetBytes ?? LARGE_ARRAY_MANIFEST_CHUNK_TARGET_BYTES, + MAX_INLINE_MATERIALIZATION_BYTES + ) + ) + const chunks = chunkArrayItems(items, targetBytes) + const storedChunks: LargeArrayManifestChunk[] = [] + for (const chunk of chunks) { + storedChunks.push(await storeArrayChunk(chunk, context)) + } + return storedChunks +} + +function assertLargeArrayManifest(value: LargeArrayManifest): void { + if (!isLargeArrayManifest(value)) { + throw new Error('Invalid large array manifest.') + } +} + +export async function createLargeArrayManifest( + items: unknown[], + context: LargeArrayManifestWriteOptions +): Promise { + if (items.length === 0) { + return { + __simLargeArrayManifest: true, + version: LARGE_ARRAY_MANIFEST_VERSION, + kind: 'array', + totalCount: 0, + chunkCount: 0, + byteSize: 0, + chunks: [], + preview: [], + } + } + + const chunks = await storeArrayChunks(items, context) + const byteSize = chunks.reduce((sum, chunk) => sum + chunk.byteSize, 0) + return { + __simLargeArrayManifest: true, + version: LARGE_ARRAY_MANIFEST_VERSION, + kind: 'array', + totalCount: items.length, + chunkCount: chunks.length, + byteSize, + chunks, + preview: getPreview(items), + } +} + +export async function appendLargeArrayManifest( + manifest: LargeArrayManifest, + items: unknown[], + context: LargeArrayManifestWriteOptions +): Promise { + if (items.length === 0) { + return manifest + } + + const chunks = await storeArrayChunks(items, context) + const byteSize = chunks.reduce((sum, chunk) => sum + chunk.byteSize, 0) + return { + ...manifest, + totalCount: manifest.totalCount + items.length, + chunkCount: manifest.chunkCount + chunks.length, + byteSize: manifest.byteSize + byteSize, + chunks: [...manifest.chunks, ...chunks], + preview: manifest.preview.length > 0 ? manifest.preview : getPreview(items), + } +} + +export async function readLargeArrayManifestSlice( + manifest: LargeArrayManifest, + start: number, + limit: number, + context: LargeArrayManifestReadOptions +): Promise { + assertLargeArrayManifest(manifest) + const normalizedStart = Math.max(0, Math.floor(start)) + const normalizedLimit = Math.max(0, Math.floor(limit)) + if (normalizedLimit === 0 || normalizedStart >= manifest.totalCount) { + return [] + } + + const end = Math.min(manifest.totalCount, normalizedStart + normalizedLimit) + const results: unknown[] = [] + let cursor = 0 + + for (const chunkEntry of manifest.chunks) { + const chunkStart = cursor + const chunkEnd = cursor + chunkEntry.count + if (chunkEnd <= normalizedStart || chunkStart >= end) { + cursor = chunkEnd + continue + } + + const chunk = await materializeLargeValueRef(chunkEntry.ref, context) + if (chunk === undefined) { + throw new Error('Large array manifest chunk is unavailable.') + } + assertArray(chunk) + assertChunkCount(chunk, chunkEntry.count) + + const from = Math.max(0, normalizedStart - chunkStart) + const to = Math.min(chunk.length, end - chunkStart) + results.push(...chunk.slice(from, to)) + + cursor = chunkEnd + if (cursor >= end) { + break + } + } + + return results +} + +export async function materializeLargeArrayManifest( + manifest: LargeArrayManifest, + context: LargeArrayManifestReadOptions +): Promise { + assertLargeArrayManifest(manifest) + assertInlineMaterializationSize(manifest.byteSize, context.maxBytes) + return readLargeArrayManifestSlice(manifest, 0, manifest.totalCount, context) +} diff --git a/apps/sim/lib/execution/payloads/large-execution-value.test.ts b/apps/sim/lib/execution/payloads/large-execution-value.test.ts new file mode 100644 index 00000000000..6b7559cc45b --- /dev/null +++ b/apps/sim/lib/execution/payloads/large-execution-value.test.ts @@ -0,0 +1,72 @@ +import { describe, expect, it } from 'vitest' +import { + LARGE_ARRAY_MANIFEST_MARKER, + LARGE_ARRAY_MANIFEST_VERSION, + type LargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest-metadata' +import { + collectLargeValueExecutionIds, + collectLargeValueKeys, +} from '@/lib/execution/payloads/large-execution-value' +import { + LARGE_VALUE_REF_MARKER, + LARGE_VALUE_REF_VERSION, + type LargeValueRef, +} from '@/lib/execution/payloads/large-value-ref' + +function largeValueRef(id: string, executionId: string): LargeValueRef { + return { + [LARGE_VALUE_REF_MARKER]: true, + version: LARGE_VALUE_REF_VERSION, + id, + kind: 'object', + size: 10, + key: `execution/workspace-1/workflow-1/${executionId}/large-value-${id}.json`, + executionId, + } +} + +function largeArrayManifest(executionId: string): LargeArrayManifest { + const ref = largeValueRef('lv_MNOPQRSTUVWX', executionId) + + return { + [LARGE_ARRAY_MANIFEST_MARKER]: true, + version: LARGE_ARRAY_MANIFEST_VERSION, + kind: 'array', + totalCount: 1, + chunkCount: 1, + byteSize: ref.size, + chunks: [{ ref, count: 1, byteSize: ref.size }], + preview: [], + } +} + +describe('collectLargeValueExecutionIds', () => { + it('collects deduplicated execution IDs from nested refs and manifests', () => { + const executionIds = collectLargeValueExecutionIds({ + blockStates: { + upstream: { + output: { + directRef: largeValueRef('lv_ABCDEFGHIJKL', 'execution-a'), + inheritedManifest: largeArrayManifest('execution-b'), + duplicateRef: largeValueRef('lv_NOPQRSTUVWXY', 'execution-a'), + }, + }, + }, + }) + + expect(executionIds).toEqual(['execution-a', 'execution-b']) + }) + + it('collects deduplicated storage keys from nested refs and manifests', () => { + const keys = collectLargeValueKeys({ + directRef: largeValueRef('lv_ABCDEFGHIJKL', 'execution-a'), + manifest: largeArrayManifest('execution-b'), + }) + + expect(keys).toEqual([ + 'execution/workspace-1/workflow-1/execution-a/large-value-lv_ABCDEFGHIJKL.json', + 'execution/workspace-1/workflow-1/execution-b/large-value-lv_MNOPQRSTUVWX.json', + ]) + }) +}) diff --git a/apps/sim/lib/execution/payloads/large-execution-value.ts b/apps/sim/lib/execution/payloads/large-execution-value.ts new file mode 100644 index 00000000000..e3b0ad1adf0 --- /dev/null +++ b/apps/sim/lib/execution/payloads/large-execution-value.ts @@ -0,0 +1,130 @@ +import { + isLargeArrayManifest, + type LargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest-metadata' +import { isLargeValueRef, type LargeValueRef } from '@/lib/execution/payloads/large-value-ref' + +export type LargeExecutionValue = LargeValueRef | LargeArrayManifest + +/** + * Parses execution values that must survive type coercion as refs. + */ +export function parseLargeExecutionValue(value: unknown): LargeExecutionValue | undefined { + if (isLargeValueRef(value) || isLargeArrayManifest(value)) { + return value + } + + if (typeof value !== 'string' || !value.trim()) { + return undefined + } + + try { + const parsed = JSON.parse(value) + return isLargeValueRef(parsed) || isLargeArrayManifest(parsed) ? parsed : undefined + } catch { + return undefined + } +} + +/** + * Finds execution IDs referenced by large values embedded in persisted execution state. + */ +export function collectLargeValueExecutionIds(value: unknown): string[] { + const executionIds = new Set() + collectLargeValueExecutionIdsInto(value, executionIds, new WeakSet()) + return Array.from(executionIds) +} + +export function collectLargeValueKeys(value: unknown): string[] { + const keys = new Set() + collectLargeValueKeysInto(value, keys, new WeakSet()) + return Array.from(keys) +} + +function collectLargeValueExecutionIdsInto( + value: unknown, + executionIds: Set, + seen: WeakSet +): void { + if (!value || typeof value !== 'object') { + return + } + + if (seen.has(value)) { + return + } + seen.add(value) + + if (isLargeValueRef(value)) { + addExecutionId(value, executionIds) + collectLargeValueExecutionIdsInto(value.preview, executionIds, seen) + return + } + + if (isLargeArrayManifest(value)) { + for (const chunk of value.chunks) { + addExecutionId(chunk.ref, executionIds) + } + collectLargeValueExecutionIdsInto(value.preview, executionIds, seen) + return + } + + if (Array.isArray(value)) { + for (const item of value) { + collectLargeValueExecutionIdsInto(item, executionIds, seen) + } + return + } + + for (const item of Object.values(value)) { + collectLargeValueExecutionIdsInto(item, executionIds, seen) + } +} + +function addExecutionId(ref: LargeValueRef, executionIds: Set): void { + if (ref.executionId) { + executionIds.add(ref.executionId) + } +} + +function collectLargeValueKeysInto(value: unknown, keys: Set, seen: WeakSet): void { + if (!value || typeof value !== 'object') { + return + } + + if (seen.has(value)) { + return + } + seen.add(value) + + if (isLargeValueRef(value)) { + addKey(value, keys) + collectLargeValueKeysInto(value.preview, keys, seen) + return + } + + if (isLargeArrayManifest(value)) { + for (const chunk of value.chunks) { + addKey(chunk.ref, keys) + } + collectLargeValueKeysInto(value.preview, keys, seen) + return + } + + if (Array.isArray(value)) { + for (const item of value) { + collectLargeValueKeysInto(item, keys, seen) + } + return + } + + for (const item of Object.values(value)) { + collectLargeValueKeysInto(item, keys, seen) + } +} + +function addKey(ref: LargeValueRef, keys: Set): void { + if (ref.key) { + keys.add(ref.key) + } +} diff --git a/apps/sim/lib/execution/payloads/materialization.server.ts b/apps/sim/lib/execution/payloads/materialization.server.ts index 5e337e35914..0a7a8e38572 100644 --- a/apps/sim/lib/execution/payloads/materialization.server.ts +++ b/apps/sim/lib/execution/payloads/materialization.server.ts @@ -25,6 +25,8 @@ export interface ExecutionMaterializationContext { workspaceId?: string executionId?: string largeValueExecutionIds?: string[] + largeValueKeys?: string[] + fileKeys?: string[] allowLargeValueWorkflowScope?: boolean userId?: string requestId?: string @@ -84,6 +86,7 @@ export function assertLargeValueRefAccess( context.executionId, ...(context.largeValueExecutionIds ?? []), ]) + const allowedKeys = new Set(context.largeValueKeys ?? []) const parts = ref.key?.split('/') ?? [] const [, workspaceId, workflowId, executionId] = parts @@ -101,16 +104,19 @@ export function assertLargeValueRefAccess( context.allowLargeValueWorkflowScope && context.workspaceId === workspaceId && context.workflowId === workflowId - if (ref.executionId && !allowedExecutionIds.has(ref.executionId) && !workflowScopeAllowed) { + if (context.workspaceId && workspaceId !== context.workspaceId) { throw new Error('Large execution value is not available in this execution.') } - if (!allowedExecutionIds.has(executionId) && !workflowScopeAllowed) { + if (context.workflowId && workflowId !== context.workflowId) { throw new Error('Large execution value is not available in this execution.') } - if (context.workspaceId && workspaceId !== context.workspaceId) { + if (allowedKeys.has(ref.key)) { + return + } + if (ref.executionId && !allowedExecutionIds.has(ref.executionId) && !workflowScopeAllowed) { throw new Error('Large execution value is not available in this execution.') } - if (context.workflowId && workflowId !== context.workflowId) { + if (!allowedExecutionIds.has(executionId) && !workflowScopeAllowed) { throw new Error('Large execution value is not available in this execution.') } } @@ -191,16 +197,11 @@ function assertExecutionFileScope(key: string, options: ExecutionMaterialization options.executionId, ...(options.largeValueExecutionIds ?? []), ]) + const allowedFileKeys = new Set(options.fileKeys ?? []) const workflowScopeAllowed = options.allowLargeValueWorkflowScope && options.workspaceId === parts.workspaceId && options.workflowId === parts.workflowId - if ( - !options.executionId || - (!allowedExecutionIds.has(parts.executionId) && !workflowScopeAllowed) - ) { - throw new Error('File is not available in this execution.') - } if (options.workspaceId && parts.workspaceId !== options.workspaceId) { throw new Error('File is not available in this execution.') @@ -209,6 +210,17 @@ function assertExecutionFileScope(key: string, options: ExecutionMaterialization if (options.workflowId && parts.workflowId !== options.workflowId) { throw new Error('File is not available in this execution.') } + + if (allowedFileKeys.has(key)) { + return + } + + if ( + !options.executionId || + (!allowedExecutionIds.has(parts.executionId) && !workflowScopeAllowed) + ) { + throw new Error('File is not available in this execution.') + } } function getVerifiedStorageContext(file: UserFile): StorageContext { diff --git a/apps/sim/lib/execution/payloads/serializer.test.ts b/apps/sim/lib/execution/payloads/serializer.test.ts index 453c1637ece..e76f500b4a1 100644 --- a/apps/sim/lib/execution/payloads/serializer.test.ts +++ b/apps/sim/lib/execution/payloads/serializer.test.ts @@ -2,18 +2,23 @@ * @vitest-environment node */ import { describe, expect, it } from 'vitest' +import { + isLargeArrayManifest, + LARGE_ARRAY_MANIFEST_VERSION, + readLargeArrayManifestSlice, +} from '@/lib/execution/payloads/large-array-manifest' import { getLargeValueMaterializationError, isLargeValueRef, } from '@/lib/execution/payloads/large-value-ref' -import { compactExecutionPayload } from '@/lib/execution/payloads/serializer' +import { compactExecutionPayload, compactSubflowResults } from '@/lib/execution/payloads/serializer' import type { UserFile } from '@/executor/types' -import { navigatePath } from '@/executor/variables/resolvers/reference' const TEST_EXECUTION_CONTEXT = { workspaceId: 'workspace-1', workflowId: 'workflow-1', executionId: 'execution-1', + userId: 'user-1', } describe('compactExecutionPayload', () => { @@ -57,19 +62,33 @@ describe('compactExecutionPayload', () => { }) }) - it('stores oversized arrays as refs and allows nested path navigation in-process', async () => { + it('stores oversized arrays as manifests and allows bounded slice reads', async () => { const results = Array.from({ length: 100 }, (_, index) => [{ event: { id: `event-${index}` } }]) const compacted = await compactExecutionPayload( { results }, - { thresholdBytes: 256, ...TEST_EXECUTION_CONTEXT } + { thresholdBytes: 1024, ...TEST_EXECUTION_CONTEXT } ) - expect(isLargeValueRef(compacted.results)).toBe(true) - expect( - navigatePath(compacted, ['results', '1', '0', 'event', 'id'], { - executionContext: TEST_EXECUTION_CONTEXT, - }) - ).toBe('event-1') + expect(isLargeArrayManifest(compacted.results)).toBe(true) + expect(compacted.results.totalCount).toBe(100) + await expect( + readLargeArrayManifestSlice(compacted.results, 1, 1, TEST_EXECUTION_CONTEXT) + ).resolves.toEqual([[{ event: { id: 'event-1' } }]]) + }) + + it('keeps oversized strings and objects as large value refs', async () => { + const compacted = await compactExecutionPayload( + { + text: 'x'.repeat(2048), + metadata: Object.fromEntries( + Array.from({ length: 100 }, (_, index) => [`key-${index}`, `value-${index}`]) + ), + }, + { thresholdBytes: 1024, ...TEST_EXECUTION_CONTEXT } + ) + + expect(isLargeValueRef(compacted.text)).toBe(true) + expect(isLargeValueRef(compacted.metadata)).toBe(true) }) it('does not double-spill existing refs', async () => { @@ -83,6 +102,125 @@ describe('compactExecutionPayload', () => { expect(compactedAgain).toEqual(compacted) }) + it('bounds user-supplied manifest-shaped metadata during compaction', async () => { + const forgedManifest = { + __simLargeArrayManifest: true, + version: LARGE_ARRAY_MANIFEST_VERSION, + kind: 'array', + totalCount: 2, + chunkCount: 2, + byteSize: 2, + chunks: [ + { + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 1, + executionId: TEST_EXECUTION_CONTEXT.executionId, + }, + count: 1, + byteSize: 1, + }, + { + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_MNOPQRSTUVWX', + kind: 'array', + size: 1, + executionId: TEST_EXECUTION_CONTEXT.executionId, + }, + count: 1, + byteSize: 1, + }, + ], + preview: [], + } + + expect(isLargeArrayManifest(forgedManifest)).toBe(true) + + const compacted = await compactExecutionPayload(forgedManifest, { + thresholdBytes: 128, + preserveRoot: true, + ...TEST_EXECUTION_CONTEXT, + }) + + expect(isLargeValueRef(compacted)).toBe(true) + }) + + it('bounds oversized manifest preview metadata during compaction', async () => { + const forgedManifest = { + __simLargeArrayManifest: true, + version: LARGE_ARRAY_MANIFEST_VERSION, + kind: 'array', + totalCount: 1, + chunkCount: 1, + byteSize: 1, + chunks: [ + { + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 1, + executionId: TEST_EXECUTION_CONTEXT.executionId, + }, + count: 1, + byteSize: 1, + }, + ], + preview: [{ payload: 'x'.repeat(20 * 1024) }], + } + + expect(isLargeArrayManifest(forgedManifest)).toBe(true) + + const compacted = await compactExecutionPayload(forgedManifest, { + thresholdBytes: 128, + preserveRoot: true, + ...TEST_EXECUTION_CONTEXT, + }) + + expect(isLargeValueRef(compacted)).toBe(true) + }) + + it('does not re-wrap manifests when forcing oversized subflow result entries', async () => { + const manifest = { + __simLargeArrayManifest: true, + version: LARGE_ARRAY_MANIFEST_VERSION, + kind: 'array', + totalCount: 1, + chunkCount: 1, + byteSize: 1, + chunks: [ + { + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 1, + executionId: TEST_EXECUTION_CONTEXT.executionId, + }, + count: 1, + byteSize: 1, + }, + ], + preview: [], + } + const thresholdBytes = Buffer.byteLength(JSON.stringify(manifest), 'utf8') + 8 + + const compacted = await compactSubflowResults([manifest, manifest], { + thresholdBytes, + ...TEST_EXECUTION_CONTEXT, + }) + + expect(compacted).toEqual([manifest, manifest]) + expect(compacted.every(isLargeArrayManifest)).toBe(true) + }) + it('rejects durable compaction when storage context is incomplete', async () => { await expect( compactExecutionPayload( diff --git a/apps/sim/lib/execution/payloads/serializer.ts b/apps/sim/lib/execution/payloads/serializer.ts index d892b2a3226..7698a7c2b5f 100644 --- a/apps/sim/lib/execution/payloads/serializer.ts +++ b/apps/sim/lib/execution/payloads/serializer.ts @@ -1,4 +1,8 @@ import { isUserFileWithMetadata } from '@/lib/core/utils/user-file' +import { + createLargeArrayManifest, + isLargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest' import { isLargeValueRef, LARGE_VALUE_THRESHOLD_BYTES, @@ -36,6 +40,10 @@ function stripUserFileBase64(value: T): Omit (options.thresholdBytes ?? LARGE_VALUE_THRESHOLD_BYTES)) { + return storeLargeValue(value, measured.json, measured.size, options) + } + return value + } + if (isUserFileWithMetadata(value) && !options.preserveUserFileBase64) { return stripUserFileBase64(value) } @@ -80,9 +96,15 @@ async function compactValue( const measured = getJsonAndSize(compacted) if (measured && measured.size > (options.thresholdBytes ?? LARGE_VALUE_THRESHOLD_BYTES)) { - return options.preserveRoot && depth === 0 - ? compacted - : storeLargeValue(compacted, measured.json, measured.size, options) + if (Array.isArray(compacted) && (canPersistDurably(options) || options.requireDurable)) { + return createLargeArrayManifest(compacted, { ...options, requireDurable: true }) + } + + if (options.preserveRoot && depth === 0) { + return compacted + } + + return storeLargeValue(compacted, measured.json, measured.size, options) } return compacted @@ -92,7 +114,7 @@ async function forceStoreValue( value: unknown, options: CompactExecutionPayloadOptions ): Promise { - if (isLargeValueRef(value)) { + if (isLargeValueRef(value) || isLargeArrayManifest(value)) { return value } const measured = getJsonAndSize(value) @@ -109,6 +131,13 @@ export async function compactExecutionPayload( return (await compactValue(value, options, { seen: new WeakSet() })) as T } +export async function compactWorkflowVariableValue( + value: T, + options: CompactExecutionPayloadOptions = {} +): Promise { + return compactExecutionPayload(value, { ...options, requireDurable: true }) +} + /** * Compacts subflow result aggregates while preserving indexable `results`. */ diff --git a/apps/sim/lib/execution/payloads/store.ts b/apps/sim/lib/execution/payloads/store.ts index 8f61961e48c..4b175131761 100644 --- a/apps/sim/lib/execution/payloads/store.ts +++ b/apps/sim/lib/execution/payloads/store.ts @@ -24,6 +24,8 @@ export interface LargeValueStoreContext { workflowId?: string executionId?: string largeValueExecutionIds?: string[] + largeValueKeys?: string[] + fileKeys?: string[] allowLargeValueWorkflowScope?: boolean userId?: string requireDurable?: boolean @@ -152,6 +154,7 @@ export async function materializeLargeValueRef( workflowId: context.workflowId, executionId: context.executionId, largeValueExecutionIds: context.largeValueExecutionIds, + largeValueKeys: context.largeValueKeys, allowLargeValueWorkflowScope: context.allowLargeValueWorkflowScope, userId: context.userId, maxBytes: context.maxBytes ?? ref.size, diff --git a/apps/sim/lib/execution/sandbox/bundles/docx.cjs b/apps/sim/lib/execution/sandbox/bundles/docx.cjs deleted file mode 100644 index f94ae48b832..00000000000 --- a/apps/sim/lib/execution/sandbox/bundles/docx.cjs +++ /dev/null @@ -1,27 +0,0 @@ -// sandbox bundle: docx -// generated by apps/sim/lib/execution/sandbox/bundles/build.ts -// do not edit by hand. run `bun run build:sandbox-bundles` to regenerate. -(()=>{var F7=Object.create;var{getPrototypeOf:N7,defineProperty:F8,getOwnPropertyNames:R7}=Object;var D7=Object.prototype.hasOwnProperty;function A7($){return this[$]}var P7,T7,C7=($,U,Y)=>{var Z=$!=null&&typeof $==="object";if(Z){var J=U?P7??=new WeakMap:T7??=new WeakMap,G=J.get($);if(G)return G}Y=$!=null?F7(N7($)):{};let X=U||!$||!$.__esModule?F8(Y,"default",{value:$,enumerable:!0}):Y;for(let Q of R7($))if(!D7.call(X,Q))F8(X,Q,{get:A7.bind($,Q),enumerable:!0});if(Z)J.set($,X);return X};var O7=($,U)=>()=>(U||$((U={exports:{}}).exports,U),U.exports);var k7=($)=>$;function E7($,U){this[$]=k7.bind(null,U)}var S7=($,U)=>{for(var Y in U)F8($,Y,{get:U[Y],enumerable:!0,configurable:!0,set:E7.bind(U,Y)})};var iU=O7((hB,pU)=>{var A0=pU.exports={},i0,r0;function S8(){throw Error("setTimeout has not been defined")}function v8(){throw Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function")i0=setTimeout;else i0=S8}catch($){i0=S8}try{if(typeof clearTimeout==="function")r0=clearTimeout;else r0=v8}catch($){r0=v8}})();function mU($){if(i0===setTimeout)return setTimeout($,0);if((i0===S8||!i0)&&setTimeout)return i0=setTimeout,setTimeout($,0);try{return i0($,0)}catch(U){try{return i0.call(null,$,0)}catch(Y){return i0.call(this,$,0)}}}function Xq($){if(r0===clearTimeout)return clearTimeout($);if((r0===v8||!r0)&&clearTimeout)return r0=clearTimeout,clearTimeout($);try{return r0($)}catch(U){try{return r0.call(null,$)}catch(Y){return r0.call(this,$)}}}var X2=[],g2=!1,T2,O1=-1;function Vq(){if(!g2||!T2)return;if(g2=!1,T2.length)X2=T2.concat(X2);else O1=-1;if(X2.length)lU()}function lU(){if(g2)return;var $=mU(Vq);g2=!0;var U=X2.length;while(U){T2=X2,X2=[];while(++O11)for(var Y=1;Y"u")DU.global=globalThis;var a0=[],u0=[],N8="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(A2=0,AU=N8.length;A20)throw Error("Invalid string. Length must be a multiple of 4");var Y=$.indexOf("=");if(Y===-1)Y=U;var Z=Y===U?0:4-Y%4;return[Y,Z]}function _7($,U){return($+U)*3/4-U}function y7($){var U,Y=v7($),Z=Y[0],J=Y[1],G=new Uint8Array(_7(Z,J)),X=0,Q=J>0?Z-4:Z,B;for(B=0;B>16&255,G[X++]=U>>8&255,G[X++]=U&255;if(J===2)U=u0[$.charCodeAt(B)]<<2|u0[$.charCodeAt(B+1)]>>4,G[X++]=U&255;if(J===1)U=u0[$.charCodeAt(B)]<<10|u0[$.charCodeAt(B+1)]<<4|u0[$.charCodeAt(B+2)]>>2,G[X++]=U>>8&255,G[X++]=U&255;return G}function b7($){return a0[$>>18&63]+a0[$>>12&63]+a0[$>>6&63]+a0[$&63]}function g7($,U,Y){var Z,J=[];for(var G=U;GQ?Q:X+G));if(Z===1)U=$[Y-1],J.push(a0[U>>2]+a0[U<<4&63]+"==");else if(Z===2)U=($[Y-2]<<8)+$[Y-1],J.push(a0[U>>10]+a0[U>>4&63]+a0[U<<2&63]+"=");return J.join("")}function T1($,U,Y,Z,J){var G,X,Q=J*8-Z-1,B=(1<>1,z=-7,W=Y?J-1:0,k=Y?-1:1,D=$[U+W];W+=k,G=D&(1<<-z)-1,D>>=-z,z+=Q;for(;z>0;G=G*256+$[U+W],W+=k,z-=8);X=G&(1<<-z)-1,G>>=-z,z+=Z;for(;z>0;X=X*256+$[U+W],W+=k,z-=8);if(G===0)G=1-F;else if(G===B)return X?NaN:(D?-1:1)*(1/0);else X=X+Math.pow(2,Z),G=G-F;return(D?-1:1)*X*Math.pow(2,G-Z)}function EU($,U,Y,Z,J,G){var X,Q,B,F=G*8-J-1,z=(1<>1,k=J===23?Math.pow(2,-24)-Math.pow(2,-77):0,D=Z?0:G-1,C=Z?1:-1,H=U<0||U===0&&1/U<0?1:0;if(U=Math.abs(U),isNaN(U)||U===1/0)Q=isNaN(U)?1:0,X=z;else{if(X=Math.floor(Math.log(U)/Math.LN2),U*(B=Math.pow(2,-X))<1)X--,B*=2;if(X+W>=1)U+=k/B;else U+=k*Math.pow(2,1-W);if(U*B>=2)X++,B/=2;if(X+W>=z)Q=0,X=z;else if(X+W>=1)Q=(U*B-1)*Math.pow(2,J),X=X+W;else Q=U*Math.pow(2,W-1)*Math.pow(2,J),X=0}for(;J>=8;$[Y+D]=Q&255,D+=C,Q/=256,J-=8);X=X<0;$[Y+D]=X&255,D+=C,X/=256,F-=8);$[Y+D-C]|=H*128}var TU=typeof Symbol==="function"&&typeof Symbol.for==="function"?Symbol.for("nodejs.util.inspect.custom"):null,x7=50,R8=2147483647;var{btoa:EB,atob:SB,File:vB,Blob:_B}=globalThis;function q2($){if($>R8)throw RangeError('The value "'+$+'" is invalid for option "size"');let U=new Uint8Array($);return Object.setPrototypeOf(U,G0.prototype),U}function C8($,U,Y){return class extends Y{constructor(){super();Object.defineProperty(this,"message",{value:U.apply(this,arguments),writable:!0,configurable:!0}),this.name=`${this.name} [${$}]`,this.stack,delete this.name}get code(){return $}set code(Z){Object.defineProperty(this,"code",{configurable:!0,enumerable:!0,value:Z,writable:!0})}toString(){return`${this.name} [${$}]: ${this.message}`}}}var f7=C8("ERR_BUFFER_OUT_OF_BOUNDS",function($){if($)return`${$} is outside of buffer bounds`;return"Attempt to access memory outside buffer bounds"},RangeError),h7=C8("ERR_INVALID_ARG_TYPE",function($,U){return`The "${$}" argument must be of type number. Received type ${typeof U}`},TypeError),D8=C8("ERR_OUT_OF_RANGE",function($,U,Y){let Z=`The value of "${$}" is out of range.`,J=Y;if(Number.isInteger(Y)&&Math.abs(Y)>4294967296)J=kU(String(Y));else if(typeof Y==="bigint"){if(J=String(Y),Y>BigInt(2)**BigInt(32)||Y<-(BigInt(2)**BigInt(32)))J=kU(J);J+="n"}return Z+=` It must be ${U}. Received ${J}`,Z},RangeError);function G0($,U,Y){if(typeof $==="number"){if(typeof U==="string")throw TypeError('The "string" argument must be of type string. Received type number');return O8($)}return SU($,U,Y)}Object.defineProperty(G0.prototype,"parent",{enumerable:!0,get:function(){if(!G0.isBuffer(this))return;return this.buffer}});Object.defineProperty(G0.prototype,"offset",{enumerable:!0,get:function(){if(!G0.isBuffer(this))return;return this.byteOffset}});G0.poolSize=8192;function SU($,U,Y){if(typeof $==="string")return d7($,U);if(ArrayBuffer.isView($))return c7($);if($==null)throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof $);if(p0($,ArrayBuffer)||$&&p0($.buffer,ArrayBuffer))return P8($,U,Y);if(typeof SharedArrayBuffer<"u"&&(p0($,SharedArrayBuffer)||$&&p0($.buffer,SharedArrayBuffer)))return P8($,U,Y);if(typeof $==="number")throw TypeError('The "value" argument must not be of type number. Received type number');let Z=$.valueOf&&$.valueOf();if(Z!=null&&Z!==$)return G0.from(Z,U,Y);let J=m7($);if(J)return J;if(typeof Symbol<"u"&&Symbol.toPrimitive!=null&&typeof $[Symbol.toPrimitive]==="function")return G0.from($[Symbol.toPrimitive]("string"),U,Y);throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof $)}G0.from=function($,U,Y){return SU($,U,Y)};Object.setPrototypeOf(G0.prototype,Uint8Array.prototype);Object.setPrototypeOf(G0,Uint8Array);function vU($){if(typeof $!=="number")throw TypeError('"size" argument must be of type number');else if($<0)throw RangeError('The value "'+$+'" is invalid for option "size"')}function u7($,U,Y){if(vU($),$<=0)return q2($);if(U!==void 0)return typeof Y==="string"?q2($).fill(U,Y):q2($).fill(U);return q2($)}G0.alloc=function($,U,Y){return u7($,U,Y)};function O8($){return vU($),q2($<0?0:k8($)|0)}G0.allocUnsafe=function($){return O8($)};G0.allocUnsafeSlow=function($){return O8($)};function d7($,U){if(typeof U!=="string"||U==="")U="utf8";if(!G0.isEncoding(U))throw TypeError("Unknown encoding: "+U);let Y=_U($,U)|0,Z=q2(Y),J=Z.write($,U);if(J!==Y)Z=Z.slice(0,J);return Z}function A8($){let U=$.length<0?0:k8($.length)|0,Y=q2(U);for(let Z=0;Z=R8)throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+R8.toString(16)+" bytes");return $|0}G0.isBuffer=function($){return $!=null&&$._isBuffer===!0&&$!==G0.prototype};G0.compare=function($,U){if(p0($,Uint8Array))$=G0.from($,$.offset,$.byteLength);if(p0(U,Uint8Array))U=G0.from(U,U.offset,U.byteLength);if(!G0.isBuffer($)||!G0.isBuffer(U))throw TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if($===U)return 0;let Y=$.length,Z=U.length;for(let J=0,G=Math.min(Y,Z);JZ.length){if(!G0.isBuffer(G))G=G0.from(G);G.copy(Z,J)}else Uint8Array.prototype.set.call(Z,G,J);else if(!G0.isBuffer(G))throw TypeError('"list" argument must be an Array of Buffers');else G.copy(Z,J);J+=G.length}return Z};function _U($,U){if(G0.isBuffer($))return $.length;if(ArrayBuffer.isView($)||p0($,ArrayBuffer))return $.byteLength;if(typeof $!=="string")throw TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof $);let Y=$.length,Z=arguments.length>2&&arguments[2]===!0;if(!Z&&Y===0)return 0;let J=!1;for(;;)switch(U){case"ascii":case"latin1":case"binary":return Y;case"utf8":case"utf-8":return T8($).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Y*2;case"hex":return Y>>>1;case"base64":return cU($).length;default:if(J)return Z?-1:T8($).length;U=(""+U).toLowerCase(),J=!0}}G0.byteLength=_U;function l7($,U,Y){let Z=!1;if(U===void 0||U<0)U=0;if(U>this.length)return"";if(Y===void 0||Y>this.length)Y=this.length;if(Y<=0)return"";if(Y>>>=0,U>>>=0,Y<=U)return"";if(!$)$="utf8";while(!0)switch($){case"hex":return $q(this,U,Y);case"utf8":case"utf-8":return bU(this,U,Y);case"ascii":return t7(this,U,Y);case"latin1":case"binary":return e7(this,U,Y);case"base64":return n7(this,U,Y);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Uq(this,U,Y);default:if(Z)throw TypeError("Unknown encoding: "+$);$=($+"").toLowerCase(),Z=!0}}G0.prototype._isBuffer=!0;function P2($,U,Y){let Z=$[U];$[U]=$[Y],$[Y]=Z}G0.prototype.swap16=function(){let $=this.length;if($%2!==0)throw RangeError("Buffer size must be a multiple of 16-bits");for(let U=0;U<$;U+=2)P2(this,U,U+1);return this};G0.prototype.swap32=function(){let $=this.length;if($%4!==0)throw RangeError("Buffer size must be a multiple of 32-bits");for(let U=0;U<$;U+=4)P2(this,U,U+3),P2(this,U+1,U+2);return this};G0.prototype.swap64=function(){let $=this.length;if($%8!==0)throw RangeError("Buffer size must be a multiple of 64-bits");for(let U=0;U<$;U+=8)P2(this,U,U+7),P2(this,U+1,U+6),P2(this,U+2,U+5),P2(this,U+3,U+4);return this};G0.prototype.toString=function(){let $=this.length;if($===0)return"";if(arguments.length===0)return bU(this,0,$);return l7.apply(this,arguments)};G0.prototype.toLocaleString=G0.prototype.toString;G0.prototype.equals=function($){if(!G0.isBuffer($))throw TypeError("Argument must be a Buffer");if(this===$)return!0;return G0.compare(this,$)===0};G0.prototype.inspect=function(){let $="",U=x7;if($=this.toString("hex",0,U).replace(/(.{2})/g,"$1 ").trim(),this.length>U)$+=" ... ";return""};if(TU)G0.prototype[TU]=G0.prototype.inspect;G0.prototype.compare=function($,U,Y,Z,J){if(p0($,Uint8Array))$=G0.from($,$.offset,$.byteLength);if(!G0.isBuffer($))throw TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof $);if(U===void 0)U=0;if(Y===void 0)Y=$?$.length:0;if(Z===void 0)Z=0;if(J===void 0)J=this.length;if(U<0||Y>$.length||Z<0||J>this.length)throw RangeError("out of range index");if(Z>=J&&U>=Y)return 0;if(Z>=J)return-1;if(U>=Y)return 1;if(U>>>=0,Y>>>=0,Z>>>=0,J>>>=0,this===$)return 0;let G=J-Z,X=Y-U,Q=Math.min(G,X),B=this.slice(Z,J),F=$.slice(U,Y);for(let z=0;z2147483647)Y=2147483647;else if(Y<-2147483648)Y=-2147483648;if(Y=+Y,Number.isNaN(Y))Y=J?0:$.length-1;if(Y<0)Y=$.length+Y;if(Y>=$.length)if(J)return-1;else Y=$.length-1;else if(Y<0)if(J)Y=0;else return-1;if(typeof U==="string")U=G0.from(U,Z);if(G0.isBuffer(U)){if(U.length===0)return-1;return CU($,U,Y,Z,J)}else if(typeof U==="number"){if(U=U&255,typeof Uint8Array.prototype.indexOf==="function")if(J)return Uint8Array.prototype.indexOf.call($,U,Y);else return Uint8Array.prototype.lastIndexOf.call($,U,Y);return CU($,[U],Y,Z,J)}throw TypeError("val must be string, number or Buffer")}function CU($,U,Y,Z,J){let G=1,X=$.length,Q=U.length;if(Z!==void 0){if(Z=String(Z).toLowerCase(),Z==="ucs2"||Z==="ucs-2"||Z==="utf16le"||Z==="utf-16le"){if($.length<2||U.length<2)return-1;G=2,X/=2,Q/=2,Y/=2}}function B(z,W){if(G===1)return z[W];else return z.readUInt16BE(W*G)}let F;if(J){let z=-1;for(F=Y;FX)Y=X-Q;for(F=Y;F>=0;F--){let z=!0;for(let W=0;WJ)Z=J;let G=U.length;if(Z>G/2)Z=G/2;let X;for(X=0;X>>0,isFinite(Y)){if(Y=Y>>>0,Z===void 0)Z="utf8"}else Z=Y,Y=void 0;else throw Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");let J=this.length-U;if(Y===void 0||Y>J)Y=J;if($.length>0&&(Y<0||U<0)||U>this.length)throw RangeError("Attempt to write outside buffer bounds");if(!Z)Z="utf8";let G=!1;for(;;)switch(Z){case"hex":return a7(this,$,U,Y);case"utf8":case"utf-8":return p7(this,$,U,Y);case"ascii":case"latin1":case"binary":return i7(this,$,U,Y);case"base64":return r7(this,$,U,Y);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return s7(this,$,U,Y);default:if(G)throw TypeError("Unknown encoding: "+Z);Z=(""+Z).toLowerCase(),G=!0}};G0.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function n7($,U,Y){if(U===0&&Y===$.length)return PU($);else return PU($.slice(U,Y))}function bU($,U,Y){Y=Math.min($.length,Y);let Z=[],J=U;while(J239?4:G>223?3:G>191?2:1;if(J+Q<=Y){let B,F,z,W;switch(Q){case 1:if(G<128)X=G;break;case 2:if(B=$[J+1],(B&192)===128){if(W=(G&31)<<6|B&63,W>127)X=W}break;case 3:if(B=$[J+1],F=$[J+2],(B&192)===128&&(F&192)===128){if(W=(G&15)<<12|(B&63)<<6|F&63,W>2047&&(W<55296||W>57343))X=W}break;case 4:if(B=$[J+1],F=$[J+2],z=$[J+3],(B&192)===128&&(F&192)===128&&(z&192)===128){if(W=(G&15)<<18|(B&63)<<12|(F&63)<<6|z&63,W>65535&&W<1114112)X=W}}}if(X===null)X=65533,Q=1;else if(X>65535)X-=65536,Z.push(X>>>10&1023|55296),X=56320|X&1023;Z.push(X),J+=Q}return o7(Z)}var OU=4096;function o7($){let U=$.length;if(U<=OU)return String.fromCharCode.apply(String,$);let Y="",Z=0;while(ZZ)Y=Z;let J="";for(let G=U;GY)$=Y;if(U<0){if(U+=Y,U<0)U=0}else if(U>Y)U=Y;if(U<$)U=$;let Z=this.subarray($,U);return Object.setPrototypeOf(Z,G0.prototype),Z};function E0($,U,Y){if($%1!==0||$<0)throw RangeError("offset is not uint");if($+U>Y)throw RangeError("Trying to access beyond buffer length")}G0.prototype.readUintLE=G0.prototype.readUIntLE=function($,U,Y){if($=$>>>0,U=U>>>0,!Y)E0($,U,this.length);let Z=this[$],J=1,G=0;while(++G>>0,U=U>>>0,!Y)E0($,U,this.length);let Z=this[$+--U],J=1;while(U>0&&(J*=256))Z+=this[$+--U]*J;return Z};G0.prototype.readUint8=G0.prototype.readUInt8=function($,U){if($=$>>>0,!U)E0($,1,this.length);return this[$]};G0.prototype.readUint16LE=G0.prototype.readUInt16LE=function($,U){if($=$>>>0,!U)E0($,2,this.length);return this[$]|this[$+1]<<8};G0.prototype.readUint16BE=G0.prototype.readUInt16BE=function($,U){if($=$>>>0,!U)E0($,2,this.length);return this[$]<<8|this[$+1]};G0.prototype.readUint32LE=G0.prototype.readUInt32LE=function($,U){if($=$>>>0,!U)E0($,4,this.length);return(this[$]|this[$+1]<<8|this[$+2]<<16)+this[$+3]*16777216};G0.prototype.readUint32BE=G0.prototype.readUInt32BE=function($,U){if($=$>>>0,!U)E0($,4,this.length);return this[$]*16777216+(this[$+1]<<16|this[$+2]<<8|this[$+3])};G0.prototype.readBigUInt64LE=z2(function($){$=$>>>0,b2($,"offset");let U=this[$],Y=this[$+7];if(U===void 0||Y===void 0)$1($,this.length-8);let Z=U+this[++$]*256+this[++$]*65536+this[++$]*16777216,J=this[++$]+this[++$]*256+this[++$]*65536+Y*16777216;return BigInt(Z)+(BigInt(J)<>>0,b2($,"offset");let U=this[$],Y=this[$+7];if(U===void 0||Y===void 0)$1($,this.length-8);let Z=U*16777216+this[++$]*65536+this[++$]*256+this[++$],J=this[++$]*16777216+this[++$]*65536+this[++$]*256+Y;return(BigInt(Z)<>>0,U=U>>>0,!Y)E0($,U,this.length);let Z=this[$],J=1,G=0;while(++G=J)Z-=Math.pow(2,8*U);return Z};G0.prototype.readIntBE=function($,U,Y){if($=$>>>0,U=U>>>0,!Y)E0($,U,this.length);let Z=U,J=1,G=this[$+--Z];while(Z>0&&(J*=256))G+=this[$+--Z]*J;if(J*=128,G>=J)G-=Math.pow(2,8*U);return G};G0.prototype.readInt8=function($,U){if($=$>>>0,!U)E0($,1,this.length);if(!(this[$]&128))return this[$];return(255-this[$]+1)*-1};G0.prototype.readInt16LE=function($,U){if($=$>>>0,!U)E0($,2,this.length);let Y=this[$]|this[$+1]<<8;return Y&32768?Y|4294901760:Y};G0.prototype.readInt16BE=function($,U){if($=$>>>0,!U)E0($,2,this.length);let Y=this[$+1]|this[$]<<8;return Y&32768?Y|4294901760:Y};G0.prototype.readInt32LE=function($,U){if($=$>>>0,!U)E0($,4,this.length);return this[$]|this[$+1]<<8|this[$+2]<<16|this[$+3]<<24};G0.prototype.readInt32BE=function($,U){if($=$>>>0,!U)E0($,4,this.length);return this[$]<<24|this[$+1]<<16|this[$+2]<<8|this[$+3]};G0.prototype.readBigInt64LE=z2(function($){$=$>>>0,b2($,"offset");let U=this[$],Y=this[$+7];if(U===void 0||Y===void 0)$1($,this.length-8);let Z=this[$+4]+this[$+5]*256+this[$+6]*65536+(Y<<24);return(BigInt(Z)<>>0,b2($,"offset");let U=this[$],Y=this[$+7];if(U===void 0||Y===void 0)$1($,this.length-8);let Z=(U<<24)+this[++$]*65536+this[++$]*256+this[++$];return(BigInt(Z)<>>0,!U)E0($,4,this.length);return T1(this,$,!0,23,4)};G0.prototype.readFloatBE=function($,U){if($=$>>>0,!U)E0($,4,this.length);return T1(this,$,!1,23,4)};G0.prototype.readDoubleLE=function($,U){if($=$>>>0,!U)E0($,8,this.length);return T1(this,$,!0,52,8)};G0.prototype.readDoubleBE=function($,U){if($=$>>>0,!U)E0($,8,this.length);return T1(this,$,!1,52,8)};function b0($,U,Y,Z,J,G){if(!G0.isBuffer($))throw TypeError('"buffer" argument must be a Buffer instance');if(U>J||U$.length)throw RangeError("Index out of range")}G0.prototype.writeUintLE=G0.prototype.writeUIntLE=function($,U,Y,Z){if($=+$,U=U>>>0,Y=Y>>>0,!Z){let X=Math.pow(2,8*Y)-1;b0(this,$,U,Y,X,0)}let J=1,G=0;this[U]=$&255;while(++G>>0,Y=Y>>>0,!Z){let X=Math.pow(2,8*Y)-1;b0(this,$,U,Y,X,0)}let J=Y-1,G=1;this[U+J]=$&255;while(--J>=0&&(G*=256))this[U+J]=$/G&255;return U+Y};G0.prototype.writeUint8=G0.prototype.writeUInt8=function($,U,Y){if($=+$,U=U>>>0,!Y)b0(this,$,U,1,255,0);return this[U]=$&255,U+1};G0.prototype.writeUint16LE=G0.prototype.writeUInt16LE=function($,U,Y){if($=+$,U=U>>>0,!Y)b0(this,$,U,2,65535,0);return this[U]=$&255,this[U+1]=$>>>8,U+2};G0.prototype.writeUint16BE=G0.prototype.writeUInt16BE=function($,U,Y){if($=+$,U=U>>>0,!Y)b0(this,$,U,2,65535,0);return this[U]=$>>>8,this[U+1]=$&255,U+2};G0.prototype.writeUint32LE=G0.prototype.writeUInt32LE=function($,U,Y){if($=+$,U=U>>>0,!Y)b0(this,$,U,4,4294967295,0);return this[U+3]=$>>>24,this[U+2]=$>>>16,this[U+1]=$>>>8,this[U]=$&255,U+4};G0.prototype.writeUint32BE=G0.prototype.writeUInt32BE=function($,U,Y){if($=+$,U=U>>>0,!Y)b0(this,$,U,4,4294967295,0);return this[U]=$>>>24,this[U+1]=$>>>16,this[U+2]=$>>>8,this[U+3]=$&255,U+4};function gU($,U,Y,Z,J){dU(U,Z,J,$,Y,7);let G=Number(U&BigInt(4294967295));$[Y++]=G,G=G>>8,$[Y++]=G,G=G>>8,$[Y++]=G,G=G>>8,$[Y++]=G;let X=Number(U>>BigInt(32)&BigInt(4294967295));return $[Y++]=X,X=X>>8,$[Y++]=X,X=X>>8,$[Y++]=X,X=X>>8,$[Y++]=X,Y}function xU($,U,Y,Z,J){dU(U,Z,J,$,Y,7);let G=Number(U&BigInt(4294967295));$[Y+7]=G,G=G>>8,$[Y+6]=G,G=G>>8,$[Y+5]=G,G=G>>8,$[Y+4]=G;let X=Number(U>>BigInt(32)&BigInt(4294967295));return $[Y+3]=X,X=X>>8,$[Y+2]=X,X=X>>8,$[Y+1]=X,X=X>>8,$[Y]=X,Y+8}G0.prototype.writeBigUInt64LE=z2(function($,U=0){return gU(this,$,U,BigInt(0),BigInt("0xffffffffffffffff"))});G0.prototype.writeBigUInt64BE=z2(function($,U=0){return xU(this,$,U,BigInt(0),BigInt("0xffffffffffffffff"))});G0.prototype.writeIntLE=function($,U,Y,Z){if($=+$,U=U>>>0,!Z){let Q=Math.pow(2,8*Y-1);b0(this,$,U,Y,Q-1,-Q)}let J=0,G=1,X=0;this[U]=$&255;while(++J>0)-X&255}return U+Y};G0.prototype.writeIntBE=function($,U,Y,Z){if($=+$,U=U>>>0,!Z){let Q=Math.pow(2,8*Y-1);b0(this,$,U,Y,Q-1,-Q)}let J=Y-1,G=1,X=0;this[U+J]=$&255;while(--J>=0&&(G*=256)){if($<0&&X===0&&this[U+J+1]!==0)X=1;this[U+J]=($/G>>0)-X&255}return U+Y};G0.prototype.writeInt8=function($,U,Y){if($=+$,U=U>>>0,!Y)b0(this,$,U,1,127,-128);if($<0)$=255+$+1;return this[U]=$&255,U+1};G0.prototype.writeInt16LE=function($,U,Y){if($=+$,U=U>>>0,!Y)b0(this,$,U,2,32767,-32768);return this[U]=$&255,this[U+1]=$>>>8,U+2};G0.prototype.writeInt16BE=function($,U,Y){if($=+$,U=U>>>0,!Y)b0(this,$,U,2,32767,-32768);return this[U]=$>>>8,this[U+1]=$&255,U+2};G0.prototype.writeInt32LE=function($,U,Y){if($=+$,U=U>>>0,!Y)b0(this,$,U,4,2147483647,-2147483648);return this[U]=$&255,this[U+1]=$>>>8,this[U+2]=$>>>16,this[U+3]=$>>>24,U+4};G0.prototype.writeInt32BE=function($,U,Y){if($=+$,U=U>>>0,!Y)b0(this,$,U,4,2147483647,-2147483648);if($<0)$=4294967295+$+1;return this[U]=$>>>24,this[U+1]=$>>>16,this[U+2]=$>>>8,this[U+3]=$&255,U+4};G0.prototype.writeBigInt64LE=z2(function($,U=0){return gU(this,$,U,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))});G0.prototype.writeBigInt64BE=z2(function($,U=0){return xU(this,$,U,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))});function fU($,U,Y,Z,J,G){if(Y+Z>$.length)throw RangeError("Index out of range");if(Y<0)throw RangeError("Index out of range")}function hU($,U,Y,Z,J){if(U=+U,Y=Y>>>0,!J)fU($,U,Y,4,340282346638528860000000000000000000000,-340282346638528860000000000000000000000);return EU($,U,Y,Z,23,4),Y+4}G0.prototype.writeFloatLE=function($,U,Y){return hU(this,$,U,!0,Y)};G0.prototype.writeFloatBE=function($,U,Y){return hU(this,$,U,!1,Y)};function uU($,U,Y,Z,J){if(U=+U,Y=Y>>>0,!J)fU($,U,Y,8,179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,-179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);return EU($,U,Y,Z,52,8),Y+8}G0.prototype.writeDoubleLE=function($,U,Y){return uU(this,$,U,!0,Y)};G0.prototype.writeDoubleBE=function($,U,Y){return uU(this,$,U,!1,Y)};G0.prototype.copy=function($,U,Y,Z){if(!G0.isBuffer($))throw TypeError("argument should be a Buffer");if(!Y)Y=0;if(!Z&&Z!==0)Z=this.length;if(U>=$.length)U=$.length;if(!U)U=0;if(Z>0&&Z=this.length)throw RangeError("Index out of range");if(Z<0)throw RangeError("sourceEnd out of bounds");if(Z>this.length)Z=this.length;if($.length-U>>0,Y=Y===void 0?this.length:Y>>>0,!$)$=0;let J;if(typeof $==="number")for(J=U;J=Z+4;Y-=3)U=`_${$.slice(Y-3,Y)}${U}`;return`${$.slice(0,Y)}${U}`}function Yq($,U,Y){if(b2(U,"offset"),$[U]===void 0||$[U+Y]===void 0)$1(U,$.length-(Y+1))}function dU($,U,Y,Z,J,G){if($>Y||$3)if(U===0||U===BigInt(0))Q=`>= 0${X} and < 2${X} ** ${(G+1)*8}${X}`;else Q=`>= -(2${X} ** ${(G+1)*8-1}${X}) and < 2 ** ${(G+1)*8-1}${X}`;else Q=`>= ${U}${X} and <= ${Y}${X}`;throw new D8("value",Q,$)}Yq(Z,J,G)}function b2($,U){if(typeof $!=="number")throw new h7(U,"number",$)}function $1($,U,Y){if(Math.floor($)!==$)throw b2($,Y),new D8(Y||"offset","an integer",$);if(U<0)throw new f7;throw new D8(Y||"offset",`>= ${Y?1:0} and <= ${U}`,$)}var Zq=/[^+/0-9A-Za-z-_]/g;function Qq($){if($=$.split("=")[0],$=$.trim().replace(Zq,""),$.length<2)return"";while($.length%4!==0)$=$+"=";return $}function T8($,U){U=U||1/0;let Y,Z=$.length,J=null,G=[];for(let X=0;X55295&&Y<57344){if(!J){if(Y>56319){if((U-=3)>-1)G.push(239,191,189);continue}else if(X+1===Z){if((U-=3)>-1)G.push(239,191,189);continue}J=Y;continue}if(Y<56320){if((U-=3)>-1)G.push(239,191,189);J=Y;continue}Y=(J-55296<<10|Y-56320)+65536}else if(J){if((U-=3)>-1)G.push(239,191,189)}if(J=null,Y<128){if((U-=1)<0)break;G.push(Y)}else if(Y<2048){if((U-=2)<0)break;G.push(Y>>6|192,Y&63|128)}else if(Y<65536){if((U-=3)<0)break;G.push(Y>>12|224,Y>>6&63|128,Y&63|128)}else if(Y<1114112){if((U-=4)<0)break;G.push(Y>>18|240,Y>>12&63|128,Y>>6&63|128,Y&63|128)}else throw Error("Invalid code point")}return G}function Jq($){let U=[];for(let Y=0;Y<$.length;++Y)U.push($.charCodeAt(Y)&255);return U}function Gq($,U){let Y,Z,J,G=[];for(let X=0;X<$.length;++X){if((U-=2)<0)break;Y=$.charCodeAt(X),Z=Y>>8,J=Y%256,G.push(J),G.push(Z)}return G}function cU($){return y7(Qq($))}function C1($,U,Y,Z){let J;for(J=0;J=U.length||J>=$.length)break;U[J+Y]=$[J]}return J}function p0($,U){return $ instanceof U||$!=null&&$.constructor!=null&&$.constructor.name!=null&&$.constructor.name===U.name}var Kq=function(){let $=Array(256);for(let U=0;U<16;++U){let Y=U*16;for(let Z=0;Z<16;++Z)$[Y+Z]="0123456789abcdef"[U]+"0123456789abcdef"[Z]}return $}();function z2($){return typeof BigInt>"u"?qq:$}function qq(){throw Error("BigInt not supported")}function E8($){return()=>{throw Error($+" is not implemented for node:buffer browser polyfill")}}var yB=E8("resolveObjectURL"),bB=E8("isUtf8");var gB=E8("transcode");var OB=C7(iU(),1);var FU={};S7(FU,{unsignedDecimalNumber:()=>W1,universalMeasureValue:()=>H1,uniqueUuid:()=>tQ,uniqueNumericIdCreator:()=>N1,uniqueId:()=>R1,uCharHexNumber:()=>D9,twipsMeasureValue:()=>T0,standardizeData:()=>mJ,signedTwipsMeasureValue:()=>e0,signedHpsMeasureValue:()=>LX,shortHexNumber:()=>DQ,sectionPageSizeDefaults:()=>h1,sectionMarginDefaults:()=>F2,positiveUniversalMeasureValue:()=>r9,pointMeasureValue:()=>CQ,percentageValue:()=>PQ,patchDocument:()=>AB,patchDetector:()=>TB,measurementOrPercentValue:()=>s9,longHexNumber:()=>BX,hpsMeasureValue:()=>AQ,hexColorValue:()=>S2,hashedId:()=>A9,encodeUtf8:()=>X1,eighthPointMeasureValue:()=>TQ,docPropertiesUniqueNumericIdGen:()=>nQ,decimalNumber:()=>S0,dateTimeValue:()=>OQ,createWrapTopAndBottom:()=>bJ,createWrapTight:()=>yJ,createWrapSquare:()=>_J,createWrapNone:()=>C9,createVerticalPosition:()=>JJ,createVerticalAlign:()=>f$,createUnderline:()=>mQ,createTransformation:()=>B$,createTableWidthElement:()=>M1,createTableRowHeight:()=>EK,createTableLook:()=>CK,createTableLayout:()=>PK,createTableFloatProperties:()=>AK,createTabStopItem:()=>PG,createTabStop:()=>TG,createStringElement:()=>u2,createSpacing:()=>AG,createSimplePos:()=>UJ,createShading:()=>j1,createSectionType:()=>nK,createRunFonts:()=>g1,createParagraphStyle:()=>K1,createPageSize:()=>rK,createPageNumberType:()=>iK,createPageMargin:()=>pK,createOutlineLevel:()=>yG,createMathSuperScriptProperties:()=>iG,createMathSuperScriptElement:()=>n2,createMathSubSuperScriptProperties:()=>oG,createMathSubScriptProperties:()=>sG,createMathSubScriptElement:()=>s2,createMathPreSubSuperScriptProperties:()=>eG,createMathNAryProperties:()=>T$,createMathLimitLocation:()=>cG,createMathBase:()=>y0,createMathAccentCharacter:()=>dG,createLineNumberType:()=>aK,createIndent:()=>EQ,createHorizontalPosition:()=>QJ,createHeaderFooterReference:()=>f1,createFrameProperties:()=>xG,createEmphasisMark:()=>Y$,createDotEmphasisMark:()=>HX,createDocumentGrid:()=>lK,createColumns:()=>mK,createBorderElement:()=>N0,createBodyProperties:()=>KJ,createAlignment:()=>n9,convertToXmlComponent:()=>U8,convertMillimetersToTwip:()=>bX,convertInchesToTwip:()=>d0,concreteNumUniqueNumericIdGen:()=>sQ,bookmarkUniqueNumericIdGen:()=>oQ,abstractNumUniqueNumericIdGen:()=>rQ,YearShort:()=>qG,YearLong:()=>BG,XmlComponent:()=>o,XmlAttributeComponent:()=>I0,WpsShapeRun:()=>aJ,WpgGroupRun:()=>pJ,WidthType:()=>l1,WORKAROUND4:()=>HV,WORKAROUND3:()=>VX,WORKAROUND2:()=>lV,VerticalPositionRelativeFrom:()=>$J,VerticalPositionAlign:()=>IX,VerticalMergeType:()=>d$,VerticalMergeRevisionType:()=>NV,VerticalMerge:()=>a1,VerticalAnchor:()=>GJ,VerticalAlignTable:()=>HK,VerticalAlignSection:()=>jK,VerticalAlign:()=>RV,UnderlineType:()=>Z$,ThematicBreak:()=>t9,Textbox:()=>G7,TextWrappingType:()=>G1,TextWrappingSide:()=>vJ,TextRun:()=>p2,TextEffect:()=>NX,TextDirection:()=>PV,TableRowPropertiesChange:()=>l$,TableRowProperties:()=>M8,TableRow:()=>SK,TableProperties:()=>L8,TableOfContents:()=>e5,TableLayoutType:()=>SV,TableCellBorders:()=>h$,TableCell:()=>V8,TableBorders:()=>B8,TableAnchorType:()=>TV,Table:()=>kK,TabStopType:()=>O9,TabStopPosition:()=>ZV,Tab:()=>w$,TDirection:()=>c$,SymbolRun:()=>G$,Styles:()=>B1,StyleLevel:()=>$7,StyleForParagraph:()=>y2,StyleForCharacter:()=>D2,StringValueElement:()=>Y2,StringEnumValueElement:()=>kQ,StringContainer:()=>L2,SpaceType:()=>g0,SoftHyphen:()=>JG,SimpleMailMergeField:()=>nJ,SimpleField:()=>J8,ShadingType:()=>WX,SequentialIdentifier:()=>rJ,Separator:()=>IG,SectionType:()=>dV,SectionPropertiesChange:()=>i$,SectionProperties:()=>I8,RunPropertiesDefaults:()=>XU,RunPropertiesChange:()=>J$,RunProperties:()=>J2,Run:()=>C0,RelativeVerticalPosition:()=>OV,RelativeHorizontalPosition:()=>CV,PrettifyType:()=>X7,PositionalTabRelativeTo:()=>eX,PositionalTabLeader:()=>$V,PositionalTabAlignment:()=>tX,PositionalTab:()=>FG,PatchType:()=>y9,ParagraphRunProperties:()=>Q$,ParagraphPropertiesDefaults:()=>qU,ParagraphPropertiesChange:()=>D$,ParagraphProperties:()=>Z2,Paragraph:()=>h0,PageTextDirectionType:()=>uV,PageTextDirection:()=>p$,PageReference:()=>gG,PageOrientation:()=>i1,PageNumberSeparator:()=>hV,PageNumberElement:()=>WG,PageNumber:()=>N2,PageBreakBefore:()=>H$,PageBreak:()=>RG,PageBorders:()=>a$,PageBorderZOrder:()=>fV,PageBorderOffsetFrom:()=>xV,PageBorderDisplay:()=>gV,Packer:()=>qB,OverlapType:()=>kV,OnOffElement:()=>X0,Numbering:()=>JU,NumberedItemReferenceFormat:()=>vG,NumberedItemReference:()=>_G,NumberValueElement:()=>k2,NumberProperties:()=>V1,NumberFormat:()=>wX,NoBreakHyphen:()=>QG,NextAttributeComponent:()=>n1,MonthShort:()=>KG,MonthLong:()=>VG,Media:()=>w8,MathSuperScript:()=>rG,MathSum:()=>mG,MathSubSuperScript:()=>tG,MathSubScript:()=>nG,MathSquareBrackets:()=>GK,MathRun:()=>hG,MathRoundBrackets:()=>JK,MathRadicalProperties:()=>O$,MathRadical:()=>ZK,MathPreSubSuperScript:()=>$K,MathNumerator:()=>P$,MathLimitUpper:()=>aG,MathLimitLower:()=>pG,MathLimit:()=>q8,MathIntegral:()=>lG,MathFunctionProperties:()=>E$,MathFunctionName:()=>k$,MathFunction:()=>QK,MathFraction:()=>uG,MathDenominator:()=>A$,MathDegree:()=>C$,MathCurlyBrackets:()=>KK,MathAngledBrackets:()=>qK,Math:()=>IV,LineRuleType:()=>v2,LineNumberRestartFormat:()=>bV,LevelSuffix:()=>aV,LevelOverride:()=>QU,LevelFormat:()=>n0,LevelForOverride:()=>F5,LevelBase:()=>W8,Level:()=>ZU,LeaderType:()=>YV,LastRenderedPageBreak:()=>jG,InternalHyperlink:()=>j$,InsertedTextRun:()=>BK,InsertedTableRow:()=>v$,InsertedTableCell:()=>y$,InitializableXmlComponent:()=>Y8,ImportedXmlComponent:()=>p9,ImportedRootElementAttributes:()=>i9,ImageRun:()=>lJ,IgnoreIfEmptyXmlComponent:()=>Q2,HyperlinkType:()=>QV,HpsMeasureElement:()=>q1,HorizontalPositionRelativeFrom:()=>eQ,HorizontalPositionAlign:()=>MX,HighlightColor:()=>RX,HeightRule:()=>_V,HeadingLevel:()=>UV,HeaderWrapper:()=>YU,HeaderFooterType:()=>S9,HeaderFooterReferenceType:()=>E2,Header:()=>U7,GridSpan:()=>u$,FrameWrap:()=>MV,FrameAnchorType:()=>LV,FootnoteReferenceRun:()=>Z7,FootnoteReferenceElement:()=>MG,FootnoteReference:()=>IU,FooterWrapper:()=>$U,Footer:()=>Y7,FootNotes:()=>UU,FootNoteReferenceRunAttributes:()=>MU,FileChild:()=>r2,File:()=>o5,ExternalHyperlink:()=>K8,Endnotes:()=>e$,EndnoteReferenceRunAttributes:()=>wU,EndnoteReferenceRun:()=>Q7,EndnoteReference:()=>I$,EndnoteIdReference:()=>WU,EmptyElement:()=>k0,EmphasisMarkType:()=>U$,EMPTY_OBJECT:()=>tZ,DropCapType:()=>BV,Drawing:()=>D1,DocumentGridType:()=>yV,DocumentDefaults:()=>VU,DocumentBackgroundAttributes:()=>s$,DocumentBackground:()=>n$,DocumentAttributes:()=>o2,DocumentAttributeNamespaces:()=>p1,Document:()=>o5,DeletedTextRun:()=>wK,DeletedTableRow:()=>_$,DeletedTableCell:()=>b$,DayShort:()=>GG,DayLong:()=>XG,ContinuationSeparator:()=>wG,ConcreteNumbering:()=>s1,ConcreteHyperlink:()=>_2,Comments:()=>M$,CommentReference:()=>ZG,CommentRangeStart:()=>UG,CommentRangeEnd:()=>YG,Comment:()=>L$,ColumnBreak:()=>DG,Column:()=>tK,CheckBoxUtil:()=>HU,CheckBoxSymbolElement:()=>L1,CheckBox:()=>J7,CharacterSet:()=>GV,CellMergeAttributes:()=>g$,CellMerge:()=>x$,CarriageReturn:()=>HG,BuilderElement:()=>B0,BorderStyle:()=>Q8,Border:()=>o9,BookmarkStart:()=>F$,BookmarkEnd:()=>N$,Bookmark:()=>z$,Body:()=>r$,BaseXmlComponent:()=>m2,Attributes:()=>O0,AnnotationReference:()=>LG,AlignmentType:()=>m0,AbstractNumbering:()=>r1});var{defineProperty:Bq,defineProperties:Lq,getOwnPropertyDescriptors:Mq,getOwnPropertySymbols:m1}=Object,sZ=Object.prototype.hasOwnProperty,nZ=Object.prototype.propertyIsEnumerable,z9=($,U,Y)=>(U in $)?Bq($,U,{enumerable:!0,configurable:!0,writable:!0,value:Y}):$[U]=Y,W0=($,U)=>{for(var Y in U||(U={}))if(sZ.call(U,Y))z9($,Y,U[Y]);if(m1){for(var Y of m1(U))if(nZ.call(U,Y))z9($,Y,U[Y])}return $},R0=($,U)=>Lq($,Mq(U)),oZ=($,U)=>{var Y={};for(var Z in $)if(sZ.call($,Z)&&U.indexOf(Z)<0)Y[Z]=$[Z];if($!=null&&m1){for(var Z of m1($))if(U.indexOf(Z)<0&&nZ.call($,Z))Y[Z]=$[Z]}return Y},Y0=($,U,Y)=>z9($,typeof U!=="symbol"?U+"":U,Y),b9=($,U,Y)=>{return new Promise((Z,J)=>{var G=(B)=>{try{Q(Y.next(B))}catch(F){J(F)}},X=(B)=>{try{Q(Y.throw(B))}catch(F){J(F)}},Q=(B)=>B.done?Z(B.value):Promise.resolve(B.value).then(G,X);Q((Y=Y.apply($,U)).next())})};class m2{constructor($){Y0(this,"rootKey"),this.rootKey=$}}var tZ=Object.seal({});class o extends m2{constructor($){super($);Y0(this,"root"),this.root=[]}prepForXml($){var U;$.stack.push(this);let Y=this.root.map((Z)=>{if(Z instanceof m2)return Z.prepForXml($);return Z}).filter((Z)=>Z!==void 0);return $.stack.pop(),{[this.rootKey]:Y.length?Y.length===1&&((U=Y[0])==null?void 0:U._attr)?Y[0]:Y:tZ}}addChildElement($){return this.root.push($),this}}class Q2 extends o{constructor($,U){super($);Y0(this,"includeIfEmpty"),this.includeIfEmpty=U}prepForXml($){let U=super.prepForXml($);if(this.includeIfEmpty)return U;if(U&&(typeof U[this.rootKey]!=="object"||Object.keys(U[this.rootKey]).length))return U;return}}class I0 extends m2{constructor($){super("_attr");Y0(this,"xmlKeys"),this.root=$}prepForXml($){let U={};return Object.entries(this.root).forEach(([Y,Z])=>{if(Z!==void 0){let J=this.xmlKeys&&this.xmlKeys[Y]||Y;U[J]=Z}}),{_attr:U}}}class n1 extends m2{constructor($){super("_attr");this.root=$}prepForXml($){return{_attr:Object.values(this.root).filter(({value:Y})=>Y!==void 0).reduce((Y,{key:Z,value:J})=>R0(W0({},Y),{[Z]:J}),{})}}}class O0 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{val:"w:val",color:"w:color",fill:"w:fill",space:"w:space",sz:"w:sz",type:"w:type",rsidR:"w:rsidR",rsidRPr:"w:rsidRPr",rsidSect:"w:rsidSect",w:"w:w",h:"w:h",top:"w:top",right:"w:right",bottom:"w:bottom",left:"w:left",header:"w:header",footer:"w:footer",gutter:"w:gutter",linePitch:"w:linePitch",pos:"w:pos"})}}var c0=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function g9($){return $&&$.__esModule&&Object.prototype.hasOwnProperty.call($,"default")?$.default:$}var _8={},k1={exports:{}},rU;function x9(){if(rU)return k1.exports;rU=1;var $=typeof Reflect==="object"?Reflect:null,U=$&&typeof $.apply==="function"?$.apply:function(A,y,g){return Function.prototype.apply.call(A,y,g)},Y;if($&&typeof $.ownKeys==="function")Y=$.ownKeys;else if(Object.getOwnPropertySymbols)Y=function(A){return Object.getOwnPropertyNames(A).concat(Object.getOwnPropertySymbols(A))};else Y=function(A){return Object.getOwnPropertyNames(A)};function Z(L){if(console&&console.warn)console.warn(L)}var J=Number.isNaN||function(A){return A!==A};function G(){G.init.call(this)}k1.exports=G,k1.exports.once=V,G.EventEmitter=G,G.prototype._events=void 0,G.prototype._eventsCount=0,G.prototype._maxListeners=void 0;var X=10;function Q(L){if(typeof L!=="function")throw TypeError('The "listener" argument must be of type Function. Received type '+typeof L)}Object.defineProperty(G,"defaultMaxListeners",{enumerable:!0,get:function(){return X},set:function(L){if(typeof L!=="number"||L<0||J(L))throw RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+L+".");X=L}}),G.init=function(){if(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)this._events=Object.create(null),this._eventsCount=0;this._maxListeners=this._maxListeners||void 0},G.prototype.setMaxListeners=function(A){if(typeof A!=="number"||A<0||J(A))throw RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+A+".");return this._maxListeners=A,this};function B(L){if(L._maxListeners===void 0)return G.defaultMaxListeners;return L._maxListeners}G.prototype.getMaxListeners=function(){return B(this)},G.prototype.emit=function(A){var y=[];for(var g=1;g0)s=y[0];if(s instanceof Error)throw s;var V0=Error("Unhandled error."+(s?" ("+s.message+")":""));throw V0.context=s,V0}var S=E[A];if(S===void 0)return!1;if(typeof S==="function")U(S,this,y);else{var h=S.length,N=C(S,h);for(var g=0;g0&&s.length>d&&!s.warned){s.warned=!0;var V0=Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(A)+" listeners added. Use emitter.setMaxListeners() to increase limit");V0.name="MaxListenersExceededWarning",V0.emitter=L,V0.type=A,V0.count=s.length,Z(V0)}}return L}G.prototype.addListener=function(A,y){return F(this,A,y,!1)},G.prototype.on=G.prototype.addListener,G.prototype.prependListener=function(A,y){return F(this,A,y,!0)};function z(){if(!this.fired){if(this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0)return this.listener.call(this.target);return this.listener.apply(this.target,arguments)}}function W(L,A,y){var g={fired:!1,wrapFn:void 0,target:L,type:A,listener:y},d=z.bind(g);return d.listener=y,g.wrapFn=d,d}G.prototype.once=function(A,y){return Q(y),this.on(A,W(this,A,y)),this},G.prototype.prependOnceListener=function(A,y){return Q(y),this.prependListener(A,W(this,A,y)),this},G.prototype.removeListener=function(A,y){var g,d,E,s,V0;if(Q(y),d=this._events,d===void 0)return this;if(g=d[A],g===void 0)return this;if(g===y||g.listener===y){if(--this._eventsCount===0)this._events=Object.create(null);else if(delete d[A],d.removeListener)this.emit("removeListener",A,g.listener||y)}else if(typeof g!=="function"){E=-1;for(s=g.length-1;s>=0;s--)if(g[s]===y||g[s].listener===y){V0=g[s].listener,E=s;break}if(E<0)return this;if(E===0)g.shift();else H(g,E);if(g.length===1)d[A]=g[0];if(d.removeListener!==void 0)this.emit("removeListener",A,V0||y)}return this},G.prototype.off=G.prototype.removeListener,G.prototype.removeAllListeners=function(A){var y,g,d;if(g=this._events,g===void 0)return this;if(g.removeListener===void 0){if(arguments.length===0)this._events=Object.create(null),this._eventsCount=0;else if(g[A]!==void 0)if(--this._eventsCount===0)this._events=Object.create(null);else delete g[A];return this}if(arguments.length===0){var E=Object.keys(g),s;for(d=0;d=0;d--)this.removeListener(A,y[d]);return this};function k(L,A,y){var g=L._events;if(g===void 0)return[];var d=g[A];if(d===void 0)return[];if(typeof d==="function")return y?[d.listener||d]:[d];return y?O(d):C(d,d.length)}G.prototype.listeners=function(A){return k(this,A,!0)},G.prototype.rawListeners=function(A){return k(this,A,!1)},G.listenerCount=function(L,A){if(typeof L.listenerCount==="function")return L.listenerCount(A);else return D.call(L,A)},G.prototype.listenerCount=D;function D(L){var A=this._events;if(A!==void 0){var y=A[L];if(typeof y==="function")return 1;else if(y!==void 0)return y.length}return 0}G.prototype.eventNames=function(){return this._eventsCount>0?Y(this._events):[]};function C(L,A){var y=Array(A);for(var g=0;g1)for(var Y=1;Y0)throw Error("Invalid string. Length must be a multiple of 4");var H=D.indexOf("=");if(H===-1)H=C;var O=H===C?0:4-H%4;return[H,O]}function Q(D){var C=X(D),H=C[0],O=C[1];return(H+O)*3/4-O}function B(D,C,H){return(C+H)*3/4-H}function F(D){var C,H=X(D),O=H[0],V=H[1],j=new Y(B(D,O,V)),M=0,L=V>0?O-4:O,A;for(A=0;A>16&255,j[M++]=C>>8&255,j[M++]=C&255;if(V===2)C=U[D.charCodeAt(A)]<<2|U[D.charCodeAt(A+1)]>>4,j[M++]=C&255;if(V===1)C=U[D.charCodeAt(A)]<<10|U[D.charCodeAt(A+1)]<<4|U[D.charCodeAt(A+2)]>>2,j[M++]=C>>8&255,j[M++]=C&255;return j}function z(D){return $[D>>18&63]+$[D>>12&63]+$[D>>6&63]+$[D&63]}function W(D,C,H){var O,V=[];for(var j=C;jL?L:M+j));if(O===1)C=D[H-1],V.push($[C>>2]+$[C<<4&63]+"==");else if(O===2)C=(D[H-2]<<8)+D[H-1],V.push($[C>>10]+$[C>>4&63]+$[C<<2&63]+"=");return V.join("")}return U1}var S1={},tU;function zq(){if(tU)return S1;return tU=1,S1.read=function($,U,Y,Z,J){var G,X,Q=J*8-Z-1,B=(1<>1,z=-7,W=Y?J-1:0,k=Y?-1:1,D=$[U+W];W+=k,G=D&(1<<-z)-1,D>>=-z,z+=Q;for(;z>0;G=G*256+$[U+W],W+=k,z-=8);X=G&(1<<-z)-1,G>>=-z,z+=Z;for(;z>0;X=X*256+$[U+W],W+=k,z-=8);if(G===0)G=1-F;else if(G===B)return X?NaN:(D?-1:1)*(1/0);else X=X+Math.pow(2,Z),G=G-F;return(D?-1:1)*X*Math.pow(2,G-Z)},S1.write=function($,U,Y,Z,J,G){var X,Q,B,F=G*8-J-1,z=(1<>1,k=J===23?Math.pow(2,-24)-Math.pow(2,-77):0,D=Z?0:G-1,C=Z?1:-1,H=U<0||U===0&&1/U<0?1:0;if(U=Math.abs(U),isNaN(U)||U===1/0)Q=isNaN(U)?1:0,X=z;else{if(X=Math.floor(Math.log(U)/Math.LN2),U*(B=Math.pow(2,-X))<1)X--,B*=2;if(X+W>=1)U+=k/B;else U+=k*Math.pow(2,1-W);if(U*B>=2)X++,B/=2;if(X+W>=z)Q=0,X=z;else if(X+W>=1)Q=(U*B-1)*Math.pow(2,J),X=X+W;else Q=U*Math.pow(2,W-1)*Math.pow(2,J),X=0}for(;J>=8;$[Y+D]=Q&255,D+=C,Q/=256,J-=8);X=X<0;$[Y+D]=X&255,D+=C,X/=256,F-=8);$[Y+D-C]|=H*128},S1}var eU;function o1(){if(eU)return b8;return eU=1,function($){var U=jq(),Y=zq(),Z=typeof Symbol==="function"&&typeof Symbol.for==="function"?Symbol.for("nodejs.util.inspect.custom"):null;$.Buffer=Q,$.SlowBuffer=j,$.INSPECT_MAX_BYTES=50;var J=2147483647;if($.kMaxLength=J,Q.TYPED_ARRAY_SUPPORT=G(),!Q.TYPED_ARRAY_SUPPORT&&typeof console<"u"&&typeof console.error==="function")console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support.");function G(){try{var T=new Uint8Array(1),K={foo:function(){return 42}};return Object.setPrototypeOf(K,Uint8Array.prototype),Object.setPrototypeOf(T,K),T.foo()===42}catch(q){return!1}}Object.defineProperty(Q.prototype,"parent",{enumerable:!0,get:function(){if(!Q.isBuffer(this))return;return this.buffer}}),Object.defineProperty(Q.prototype,"offset",{enumerable:!0,get:function(){if(!Q.isBuffer(this))return;return this.byteOffset}});function X(T){if(T>J)throw RangeError('The value "'+T+'" is invalid for option "size"');var K=new Uint8Array(T);return Object.setPrototypeOf(K,Q.prototype),K}function Q(T,K,q){if(typeof T==="number"){if(typeof K==="string")throw TypeError('The "string" argument must be of type string. Received type number');return W(T)}return B(T,K,q)}Q.poolSize=8192;function B(T,K,q){if(typeof T==="string")return k(T,K);if(ArrayBuffer.isView(T))return C(T);if(T==null)throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof T);if(e(T,ArrayBuffer)||T&&e(T.buffer,ArrayBuffer))return H(T,K,q);if(typeof SharedArrayBuffer<"u"&&(e(T,SharedArrayBuffer)||T&&e(T.buffer,SharedArrayBuffer)))return H(T,K,q);if(typeof T==="number")throw TypeError('The "value" argument must not be of type number. Received type number');var w=T.valueOf&&T.valueOf();if(w!=null&&w!==T)return Q.from(w,K,q);var x=O(T);if(x)return x;if(typeof Symbol<"u"&&Symbol.toPrimitive!=null&&typeof T[Symbol.toPrimitive]==="function")return Q.from(T[Symbol.toPrimitive]("string"),K,q);throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof T)}Q.from=function(T,K,q){return B(T,K,q)},Object.setPrototypeOf(Q.prototype,Uint8Array.prototype),Object.setPrototypeOf(Q,Uint8Array);function F(T){if(typeof T!=="number")throw TypeError('"size" argument must be of type number');else if(T<0)throw RangeError('The value "'+T+'" is invalid for option "size"')}function z(T,K,q){if(F(T),T<=0)return X(T);if(K!==void 0)return typeof q==="string"?X(T).fill(K,q):X(T).fill(K);return X(T)}Q.alloc=function(T,K,q){return z(T,K,q)};function W(T){return F(T),X(T<0?0:V(T)|0)}Q.allocUnsafe=function(T){return W(T)},Q.allocUnsafeSlow=function(T){return W(T)};function k(T,K){if(typeof K!=="string"||K==="")K="utf8";if(!Q.isEncoding(K))throw TypeError("Unknown encoding: "+K);var q=M(T,K)|0,w=X(q),x=w.write(T,K);if(x!==q)w=w.slice(0,x);return w}function D(T){var K=T.length<0?0:V(T.length)|0,q=X(K);for(var w=0;w=J)throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+J.toString(16)+" bytes");return T|0}function j(T){if(+T!=T)T=0;return Q.alloc(+T)}Q.isBuffer=function(K){return K!=null&&K._isBuffer===!0&&K!==Q.prototype},Q.compare=function(K,q){if(e(K,Uint8Array))K=Q.from(K,K.offset,K.byteLength);if(e(q,Uint8Array))q=Q.from(q,q.offset,q.byteLength);if(!Q.isBuffer(K)||!Q.isBuffer(q))throw TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(K===q)return 0;var w=K.length,x=q.length;for(var l=0,u=Math.min(w,x);lx.length)Q.from(u).copy(x,l);else Uint8Array.prototype.set.call(x,u,l);else if(!Q.isBuffer(u))throw TypeError('"list" argument must be an Array of Buffers');else u.copy(x,l);l+=u.length}return x};function M(T,K){if(Q.isBuffer(T))return T.length;if(ArrayBuffer.isView(T)||e(T,ArrayBuffer))return T.byteLength;if(typeof T!=="string")throw TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof T);var q=T.length,w=arguments.length>2&&arguments[2]===!0;if(!w&&q===0)return 0;var x=!1;for(;;)switch(K){case"ascii":case"latin1":case"binary":return q;case"utf8":case"utf-8":return R(T).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return q*2;case"hex":return q>>>1;case"base64":return v(T).length;default:if(x)return w?-1:R(T).length;K=(""+K).toLowerCase(),x=!0}}Q.byteLength=M;function L(T,K,q){var w=!1;if(K===void 0||K<0)K=0;if(K>this.length)return"";if(q===void 0||q>this.length)q=this.length;if(q<=0)return"";if(q>>>=0,K>>>=0,q<=K)return"";if(!T)T="utf8";while(!0)switch(T){case"hex":return U0(this,K,q);case"utf8":case"utf-8":return N(this,K,q);case"ascii":return m(this,K,q);case"latin1":case"binary":return J0(this,K,q);case"base64":return h(this,K,q);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return L0(this,K,q);default:if(w)throw TypeError("Unknown encoding: "+T);T=(T+"").toLowerCase(),w=!0}}Q.prototype._isBuffer=!0;function A(T,K,q){var w=T[K];T[K]=T[q],T[q]=w}if(Q.prototype.swap16=function(){var K=this.length;if(K%2!==0)throw RangeError("Buffer size must be a multiple of 16-bits");for(var q=0;qq)K+=" ... ";return""},Z)Q.prototype[Z]=Q.prototype.inspect;Q.prototype.compare=function(K,q,w,x,l){if(e(K,Uint8Array))K=Q.from(K,K.offset,K.byteLength);if(!Q.isBuffer(K))throw TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof K);if(q===void 0)q=0;if(w===void 0)w=K?K.length:0;if(x===void 0)x=0;if(l===void 0)l=this.length;if(q<0||w>K.length||x<0||l>this.length)throw RangeError("out of range index");if(x>=l&&q>=w)return 0;if(x>=l)return-1;if(q>=w)return 1;if(q>>>=0,w>>>=0,x>>>=0,l>>>=0,this===K)return 0;var u=l-x,Q0=w-q,q0=Math.min(u,Q0),K0=this.slice(x,l),M0=K.slice(q,w);for(var w0=0;w02147483647)q=2147483647;else if(q<-2147483648)q=-2147483648;if(q=+q,I(q))q=x?0:T.length-1;if(q<0)q=T.length+q;if(q>=T.length)if(x)return-1;else q=T.length-1;else if(q<0)if(x)q=0;else return-1;if(typeof K==="string")K=Q.from(K,w);if(Q.isBuffer(K)){if(K.length===0)return-1;return g(T,K,q,w,x)}else if(typeof K==="number"){if(K=K&255,typeof Uint8Array.prototype.indexOf==="function")if(x)return Uint8Array.prototype.indexOf.call(T,K,q);else return Uint8Array.prototype.lastIndexOf.call(T,K,q);return g(T,[K],q,w,x)}throw TypeError("val must be string, number or Buffer")}function g(T,K,q,w,x){var l=1,u=T.length,Q0=K.length;if(w!==void 0){if(w=String(w).toLowerCase(),w==="ucs2"||w==="ucs-2"||w==="utf16le"||w==="utf-16le"){if(T.length<2||K.length<2)return-1;l=2,u/=2,Q0/=2,q/=2}}function q0(v0,j2){if(l===1)return v0[j2];else return v0.readUInt16BE(j2*l)}var K0;if(x){var M0=-1;for(K0=q;K0u)q=u-Q0;for(K0=q;K0>=0;K0--){var w0=!0;for(var H0=0;H0x)w=x;var l=K.length;if(w>l/2)w=l/2;for(var u=0;u>>0,isFinite(w)){if(w=w>>>0,x===void 0)x="utf8"}else x=w,w=void 0;else throw Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");var l=this.length-q;if(w===void 0||w>l)w=l;if(K.length>0&&(w<0||q<0)||q>this.length)throw RangeError("Attempt to write outside buffer bounds");if(!x)x="utf8";var u=!1;for(;;)switch(x){case"hex":return d(this,K,q,w);case"utf8":case"utf-8":return E(this,K,q,w);case"ascii":case"latin1":case"binary":return s(this,K,q,w);case"base64":return V0(this,K,q,w);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,K,q,w);default:if(u)throw TypeError("Unknown encoding: "+x);x=(""+x).toLowerCase(),u=!0}},Q.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function h(T,K,q){if(K===0&&q===T.length)return U.fromByteArray(T);else return U.fromByteArray(T.slice(K,q))}function N(T,K,q){q=Math.min(T.length,q);var w=[],x=K;while(x239?4:l>223?3:l>191?2:1;if(x+Q0<=q){var q0,K0,M0,w0;switch(Q0){case 1:if(l<128)u=l;break;case 2:if(q0=T[x+1],(q0&192)===128){if(w0=(l&31)<<6|q0&63,w0>127)u=w0}break;case 3:if(q0=T[x+1],K0=T[x+2],(q0&192)===128&&(K0&192)===128){if(w0=(l&15)<<12|(q0&63)<<6|K0&63,w0>2047&&(w0<55296||w0>57343))u=w0}break;case 4:if(q0=T[x+1],K0=T[x+2],M0=T[x+3],(q0&192)===128&&(K0&192)===128&&(M0&192)===128){if(w0=(l&15)<<18|(q0&63)<<12|(K0&63)<<6|M0&63,w0>65535&&w0<1114112)u=w0}}}if(u===null)u=65533,Q0=1;else if(u>65535)u-=65536,w.push(u>>>10&1023|55296),u=56320|u&1023;w.push(u),x+=Q0}return $0(w)}var a=4096;function $0(T){var K=T.length;if(K<=a)return String.fromCharCode.apply(String,T);var q="",w=0;while(ww)q=w;var x="";for(var l=K;lw)K=w;if(q<0){if(q+=w,q<0)q=0}else if(q>w)q=w;if(qq)throw RangeError("Trying to access beyond buffer length")}Q.prototype.readUintLE=Q.prototype.readUIntLE=function(K,q,w){if(K=K>>>0,q=q>>>0,!w)i(K,q,this.length);var x=this[K],l=1,u=0;while(++u>>0,q=q>>>0,!w)i(K,q,this.length);var x=this[K+--q],l=1;while(q>0&&(l*=256))x+=this[K+--q]*l;return x},Q.prototype.readUint8=Q.prototype.readUInt8=function(K,q){if(K=K>>>0,!q)i(K,1,this.length);return this[K]},Q.prototype.readUint16LE=Q.prototype.readUInt16LE=function(K,q){if(K=K>>>0,!q)i(K,2,this.length);return this[K]|this[K+1]<<8},Q.prototype.readUint16BE=Q.prototype.readUInt16BE=function(K,q){if(K=K>>>0,!q)i(K,2,this.length);return this[K]<<8|this[K+1]},Q.prototype.readUint32LE=Q.prototype.readUInt32LE=function(K,q){if(K=K>>>0,!q)i(K,4,this.length);return(this[K]|this[K+1]<<8|this[K+2]<<16)+this[K+3]*16777216},Q.prototype.readUint32BE=Q.prototype.readUInt32BE=function(K,q){if(K=K>>>0,!q)i(K,4,this.length);return this[K]*16777216+(this[K+1]<<16|this[K+2]<<8|this[K+3])},Q.prototype.readIntLE=function(K,q,w){if(K=K>>>0,q=q>>>0,!w)i(K,q,this.length);var x=this[K],l=1,u=0;while(++u=l)x-=Math.pow(2,8*q);return x},Q.prototype.readIntBE=function(K,q,w){if(K=K>>>0,q=q>>>0,!w)i(K,q,this.length);var x=q,l=1,u=this[K+--x];while(x>0&&(l*=256))u+=this[K+--x]*l;if(l*=128,u>=l)u-=Math.pow(2,8*q);return u},Q.prototype.readInt8=function(K,q){if(K=K>>>0,!q)i(K,1,this.length);if(!(this[K]&128))return this[K];return(255-this[K]+1)*-1},Q.prototype.readInt16LE=function(K,q){if(K=K>>>0,!q)i(K,2,this.length);var w=this[K]|this[K+1]<<8;return w&32768?w|4294901760:w},Q.prototype.readInt16BE=function(K,q){if(K=K>>>0,!q)i(K,2,this.length);var w=this[K+1]|this[K]<<8;return w&32768?w|4294901760:w},Q.prototype.readInt32LE=function(K,q){if(K=K>>>0,!q)i(K,4,this.length);return this[K]|this[K+1]<<8|this[K+2]<<16|this[K+3]<<24},Q.prototype.readInt32BE=function(K,q){if(K=K>>>0,!q)i(K,4,this.length);return this[K]<<24|this[K+1]<<16|this[K+2]<<8|this[K+3]},Q.prototype.readFloatLE=function(K,q){if(K=K>>>0,!q)i(K,4,this.length);return Y.read(this,K,!0,23,4)},Q.prototype.readFloatBE=function(K,q){if(K=K>>>0,!q)i(K,4,this.length);return Y.read(this,K,!1,23,4)},Q.prototype.readDoubleLE=function(K,q){if(K=K>>>0,!q)i(K,8,this.length);return Y.read(this,K,!0,52,8)},Q.prototype.readDoubleBE=function(K,q){if(K=K>>>0,!q)i(K,8,this.length);return Y.read(this,K,!1,52,8)};function _(T,K,q,w,x,l){if(!Q.isBuffer(T))throw TypeError('"buffer" argument must be a Buffer instance');if(K>x||KT.length)throw RangeError("Index out of range")}Q.prototype.writeUintLE=Q.prototype.writeUIntLE=function(K,q,w,x){if(K=+K,q=q>>>0,w=w>>>0,!x){var l=Math.pow(2,8*w)-1;_(this,K,q,w,l,0)}var u=1,Q0=0;this[q]=K&255;while(++Q0>>0,w=w>>>0,!x){var l=Math.pow(2,8*w)-1;_(this,K,q,w,l,0)}var u=w-1,Q0=1;this[q+u]=K&255;while(--u>=0&&(Q0*=256))this[q+u]=K/Q0&255;return q+w},Q.prototype.writeUint8=Q.prototype.writeUInt8=function(K,q,w){if(K=+K,q=q>>>0,!w)_(this,K,q,1,255,0);return this[q]=K&255,q+1},Q.prototype.writeUint16LE=Q.prototype.writeUInt16LE=function(K,q,w){if(K=+K,q=q>>>0,!w)_(this,K,q,2,65535,0);return this[q]=K&255,this[q+1]=K>>>8,q+2},Q.prototype.writeUint16BE=Q.prototype.writeUInt16BE=function(K,q,w){if(K=+K,q=q>>>0,!w)_(this,K,q,2,65535,0);return this[q]=K>>>8,this[q+1]=K&255,q+2},Q.prototype.writeUint32LE=Q.prototype.writeUInt32LE=function(K,q,w){if(K=+K,q=q>>>0,!w)_(this,K,q,4,4294967295,0);return this[q+3]=K>>>24,this[q+2]=K>>>16,this[q+1]=K>>>8,this[q]=K&255,q+4},Q.prototype.writeUint32BE=Q.prototype.writeUInt32BE=function(K,q,w){if(K=+K,q=q>>>0,!w)_(this,K,q,4,4294967295,0);return this[q]=K>>>24,this[q+1]=K>>>16,this[q+2]=K>>>8,this[q+3]=K&255,q+4},Q.prototype.writeIntLE=function(K,q,w,x){if(K=+K,q=q>>>0,!x){var l=Math.pow(2,8*w-1);_(this,K,q,w,l-1,-l)}var u=0,Q0=1,q0=0;this[q]=K&255;while(++u>0)-q0&255}return q+w},Q.prototype.writeIntBE=function(K,q,w,x){if(K=+K,q=q>>>0,!x){var l=Math.pow(2,8*w-1);_(this,K,q,w,l-1,-l)}var u=w-1,Q0=1,q0=0;this[q+u]=K&255;while(--u>=0&&(Q0*=256)){if(K<0&&q0===0&&this[q+u+1]!==0)q0=1;this[q+u]=(K/Q0>>0)-q0&255}return q+w},Q.prototype.writeInt8=function(K,q,w){if(K=+K,q=q>>>0,!w)_(this,K,q,1,127,-128);if(K<0)K=255+K+1;return this[q]=K&255,q+1},Q.prototype.writeInt16LE=function(K,q,w){if(K=+K,q=q>>>0,!w)_(this,K,q,2,32767,-32768);return this[q]=K&255,this[q+1]=K>>>8,q+2},Q.prototype.writeInt16BE=function(K,q,w){if(K=+K,q=q>>>0,!w)_(this,K,q,2,32767,-32768);return this[q]=K>>>8,this[q+1]=K&255,q+2},Q.prototype.writeInt32LE=function(K,q,w){if(K=+K,q=q>>>0,!w)_(this,K,q,4,2147483647,-2147483648);return this[q]=K&255,this[q+1]=K>>>8,this[q+2]=K>>>16,this[q+3]=K>>>24,q+4},Q.prototype.writeInt32BE=function(K,q,w){if(K=+K,q=q>>>0,!w)_(this,K,q,4,2147483647,-2147483648);if(K<0)K=4294967295+K+1;return this[q]=K>>>24,this[q+1]=K>>>16,this[q+2]=K>>>8,this[q+3]=K&255,q+4};function r(T,K,q,w,x,l){if(q+w>T.length)throw RangeError("Index out of range");if(q<0)throw RangeError("Index out of range")}function n(T,K,q,w,x){if(K=+K,q=q>>>0,!x)r(T,K,q,4);return Y.write(T,K,q,w,23,4),q+4}Q.prototype.writeFloatLE=function(K,q,w){return n(this,K,q,!0,w)},Q.prototype.writeFloatBE=function(K,q,w){return n(this,K,q,!1,w)};function Z0(T,K,q,w,x){if(K=+K,q=q>>>0,!x)r(T,K,q,8);return Y.write(T,K,q,w,52,8),q+8}Q.prototype.writeDoubleLE=function(K,q,w){return Z0(this,K,q,!0,w)},Q.prototype.writeDoubleBE=function(K,q,w){return Z0(this,K,q,!1,w)},Q.prototype.copy=function(K,q,w,x){if(!Q.isBuffer(K))throw TypeError("argument should be a Buffer");if(!w)w=0;if(!x&&x!==0)x=this.length;if(q>=K.length)q=K.length;if(!q)q=0;if(x>0&&x=this.length)throw RangeError("Index out of range");if(x<0)throw RangeError("sourceEnd out of bounds");if(x>this.length)x=this.length;if(K.length-q>>0,w=w===void 0?this.length:w>>>0,!K)K=0;var u;if(typeof K==="number")for(u=q;u55295&&q<57344){if(!x){if(q>56319){if((K-=3)>-1)l.push(239,191,189);continue}else if(u+1===w){if((K-=3)>-1)l.push(239,191,189);continue}x=q;continue}if(q<56320){if((K-=3)>-1)l.push(239,191,189);x=q;continue}q=(x-55296<<10|q-56320)+65536}else if(x){if((K-=3)>-1)l.push(239,191,189)}if(x=null,q<128){if((K-=1)<0)break;l.push(q)}else if(q<2048){if((K-=2)<0)break;l.push(q>>6|192,q&63|128)}else if(q<65536){if((K-=3)<0)break;l.push(q>>12|224,q>>6&63|128,q&63|128)}else if(q<1114112){if((K-=4)<0)break;l.push(q>>18|240,q>>12&63|128,q>>6&63|128,q&63|128)}else throw Error("Invalid code point")}return l}function c(T){var K=[];for(var q=0;q>8,x=q%256,l.push(x),l.push(w)}return l}function v(T){return U.toByteArray(P(T))}function b(T,K,q,w){for(var x=0;x=K.length||x>=T.length)break;K[x+q]=T[x]}return x}function e(T,K){return T instanceof K||T!=null&&T.constructor!=null&&T.constructor.name!=null&&T.constructor.name===K.name}function I(T){return T!==T}var t=function(){var T="0123456789abcdef",K=Array(256);for(var q=0;q<16;++q){var w=q*16;for(var x=0;x<16;++x)K[w+x]=T[q]+T[x]}return K}()}(b8),b8}var g8={},x8={},f8,$Y;function QQ(){if($Y)return f8;return $Y=1,f8=function(){if(typeof Symbol!=="function"||typeof Object.getOwnPropertySymbols!=="function")return!1;if(typeof Symbol.iterator==="symbol")return!0;var U={},Y=Symbol("test"),Z=Object(Y);if(typeof Y==="string")return!1;if(Object.prototype.toString.call(Y)!=="[object Symbol]")return!1;if(Object.prototype.toString.call(Z)!=="[object Symbol]")return!1;var J=42;U[Y]=J;for(var G in U)return!1;if(typeof Object.keys==="function"&&Object.keys(U).length!==0)return!1;if(typeof Object.getOwnPropertyNames==="function"&&Object.getOwnPropertyNames(U).length!==0)return!1;var X=Object.getOwnPropertySymbols(U);if(X.length!==1||X[0]!==Y)return!1;if(!Object.prototype.propertyIsEnumerable.call(U,Y))return!1;if(typeof Object.getOwnPropertyDescriptor==="function"){var Q=Object.getOwnPropertyDescriptor(U,Y);if(Q.value!==J||Q.enumerable!==!0)return!1}return!0},f8}var h8,UY;function f9(){if(UY)return h8;UY=1;var $=QQ();return h8=function(){return $()&&!!Symbol.toStringTag},h8}var u8,YY;function JQ(){if(YY)return u8;return YY=1,u8=Object,u8}var d8,ZY;function Fq(){if(ZY)return d8;return ZY=1,d8=Error,d8}var c8,QY;function Nq(){if(QY)return c8;return QY=1,c8=EvalError,c8}var m8,JY;function Rq(){if(JY)return m8;return JY=1,m8=RangeError,m8}var l8,GY;function Dq(){if(GY)return l8;return GY=1,l8=ReferenceError,l8}var a8,KY;function GQ(){if(KY)return a8;return KY=1,a8=SyntaxError,a8}var p8,qY;function t1(){if(qY)return p8;return qY=1,p8=TypeError,p8}var i8,XY;function Aq(){if(XY)return i8;return XY=1,i8=URIError,i8}var r8,VY;function Pq(){if(VY)return r8;return VY=1,r8=Math.abs,r8}var s8,BY;function Tq(){if(BY)return s8;return BY=1,s8=Math.floor,s8}var n8,LY;function Cq(){if(LY)return n8;return LY=1,n8=Math.max,n8}var o8,MY;function Oq(){if(MY)return o8;return MY=1,o8=Math.min,o8}var t8,IY;function kq(){if(IY)return t8;return IY=1,t8=Math.pow,t8}var e8,wY;function Eq(){if(wY)return e8;return wY=1,e8=Math.round,e8}var $6,WY;function Sq(){if(WY)return $6;return WY=1,$6=Number.isNaN||function(U){return U!==U},$6}var U6,HY;function vq(){if(HY)return U6;HY=1;var $=Sq();return U6=function(Y){if($(Y)||Y===0)return Y;return Y<0?-1:1},U6}var Y6,jY;function _q(){if(jY)return Y6;return jY=1,Y6=Object.getOwnPropertyDescriptor,Y6}var Z6,zY;function I1(){if(zY)return Z6;zY=1;var $=_q();if($)try{$([],"length")}catch(U){$=null}return Z6=$,Z6}var Q6,FY;function e1(){if(FY)return Q6;FY=1;var $=Object.defineProperty||!1;if($)try{$({},"a",{value:1})}catch(U){$=!1}return Q6=$,Q6}var J6,NY;function yq(){if(NY)return J6;NY=1;var $=typeof Symbol<"u"&&Symbol,U=QQ();return J6=function(){if(typeof $!=="function")return!1;if(typeof Symbol!=="function")return!1;if(typeof $("foo")!=="symbol")return!1;if(typeof Symbol("bar")!=="symbol")return!1;return U()},J6}var G6,RY;function KQ(){if(RY)return G6;return RY=1,G6=typeof Reflect<"u"&&Reflect.getPrototypeOf||null,G6}var K6,DY;function qQ(){if(DY)return K6;DY=1;var $=JQ();return K6=$.getPrototypeOf||null,K6}var q6,AY;function bq(){if(AY)return q6;AY=1;var $="Function.prototype.bind called on incompatible ",U=Object.prototype.toString,Y=Math.max,Z="[object Function]",J=function(B,F){var z=[];for(var W=0;W"u"||!g?$:g(Uint8Array),N={__proto__:null,"%AggregateError%":typeof AggregateError>"u"?$:AggregateError,"%Array%":Array,"%ArrayBuffer%":typeof ArrayBuffer>"u"?$:ArrayBuffer,"%ArrayIteratorPrototype%":y&&g?g([][Symbol.iterator]()):$,"%AsyncFromSyncIteratorPrototype%":$,"%AsyncFunction%":S,"%AsyncGenerator%":S,"%AsyncGeneratorFunction%":S,"%AsyncIteratorPrototype%":S,"%Atomics%":typeof Atomics>"u"?$:Atomics,"%BigInt%":typeof BigInt>"u"?$:BigInt,"%BigInt64Array%":typeof BigInt64Array>"u"?$:BigInt64Array,"%BigUint64Array%":typeof BigUint64Array>"u"?$:BigUint64Array,"%Boolean%":Boolean,"%DataView%":typeof DataView>"u"?$:DataView,"%Date%":Date,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":Y,"%eval%":eval,"%EvalError%":Z,"%Float16Array%":typeof Float16Array>"u"?$:Float16Array,"%Float32Array%":typeof Float32Array>"u"?$:Float32Array,"%Float64Array%":typeof Float64Array>"u"?$:Float64Array,"%FinalizationRegistry%":typeof FinalizationRegistry>"u"?$:FinalizationRegistry,"%Function%":O,"%GeneratorFunction%":S,"%Int8Array%":typeof Int8Array>"u"?$:Int8Array,"%Int16Array%":typeof Int16Array>"u"?$:Int16Array,"%Int32Array%":typeof Int32Array>"u"?$:Int32Array,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":y&&g?g(g([][Symbol.iterator]())):$,"%JSON%":typeof JSON==="object"?JSON:$,"%Map%":typeof Map>"u"?$:Map,"%MapIteratorPrototype%":typeof Map>"u"||!y||!g?$:g(new Map()[Symbol.iterator]()),"%Math%":Math,"%Number%":Number,"%Object%":U,"%Object.getOwnPropertyDescriptor%":j,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":typeof Promise>"u"?$:Promise,"%Proxy%":typeof Proxy>"u"?$:Proxy,"%RangeError%":J,"%ReferenceError%":G,"%Reflect%":typeof Reflect>"u"?$:Reflect,"%RegExp%":RegExp,"%Set%":typeof Set>"u"?$:Set,"%SetIteratorPrototype%":typeof Set>"u"||!y||!g?$:g(new Set()[Symbol.iterator]()),"%SharedArrayBuffer%":typeof SharedArrayBuffer>"u"?$:SharedArrayBuffer,"%String%":String,"%StringIteratorPrototype%":y&&g?g(""[Symbol.iterator]()):$,"%Symbol%":y?Symbol:$,"%SyntaxError%":X,"%ThrowTypeError%":A,"%TypedArray%":h,"%TypeError%":Q,"%Uint8Array%":typeof Uint8Array>"u"?$:Uint8Array,"%Uint8ClampedArray%":typeof Uint8ClampedArray>"u"?$:Uint8ClampedArray,"%Uint16Array%":typeof Uint16Array>"u"?$:Uint16Array,"%Uint32Array%":typeof Uint32Array>"u"?$:Uint32Array,"%URIError%":B,"%WeakMap%":typeof WeakMap>"u"?$:WeakMap,"%WeakRef%":typeof WeakRef>"u"?$:WeakRef,"%WeakSet%":typeof WeakSet>"u"?$:WeakSet,"%Function.prototype.call%":V0,"%Function.prototype.apply%":s,"%Object.defineProperty%":M,"%Object.getPrototypeOf%":d,"%Math.abs%":F,"%Math.floor%":z,"%Math.max%":W,"%Math.min%":k,"%Math.pow%":D,"%Math.round%":C,"%Math.sign%":H,"%Reflect.getPrototypeOf%":E};if(g)try{null.error}catch(c){var a=g(g(c));N["%Error.prototype%"]=a}var $0=function c(f){var v;if(f==="%AsyncFunction%")v=V("async function () {}");else if(f==="%GeneratorFunction%")v=V("function* () {}");else if(f==="%AsyncGeneratorFunction%")v=V("async function* () {}");else if(f==="%AsyncGenerator%"){var b=c("%AsyncGeneratorFunction%");if(b)v=b.prototype}else if(f==="%AsyncIteratorPrototype%"){var e=c("%AsyncGenerator%");if(e&&g)v=g(e.prototype)}return N[f]=v,v},m={__proto__:null,"%ArrayBufferPrototype%":["ArrayBuffer","prototype"],"%ArrayPrototype%":["Array","prototype"],"%ArrayProto_entries%":["Array","prototype","entries"],"%ArrayProto_forEach%":["Array","prototype","forEach"],"%ArrayProto_keys%":["Array","prototype","keys"],"%ArrayProto_values%":["Array","prototype","values"],"%AsyncFunctionPrototype%":["AsyncFunction","prototype"],"%AsyncGenerator%":["AsyncGeneratorFunction","prototype"],"%AsyncGeneratorPrototype%":["AsyncGeneratorFunction","prototype","prototype"],"%BooleanPrototype%":["Boolean","prototype"],"%DataViewPrototype%":["DataView","prototype"],"%DatePrototype%":["Date","prototype"],"%ErrorPrototype%":["Error","prototype"],"%EvalErrorPrototype%":["EvalError","prototype"],"%Float32ArrayPrototype%":["Float32Array","prototype"],"%Float64ArrayPrototype%":["Float64Array","prototype"],"%FunctionPrototype%":["Function","prototype"],"%Generator%":["GeneratorFunction","prototype"],"%GeneratorPrototype%":["GeneratorFunction","prototype","prototype"],"%Int8ArrayPrototype%":["Int8Array","prototype"],"%Int16ArrayPrototype%":["Int16Array","prototype"],"%Int32ArrayPrototype%":["Int32Array","prototype"],"%JSONParse%":["JSON","parse"],"%JSONStringify%":["JSON","stringify"],"%MapPrototype%":["Map","prototype"],"%NumberPrototype%":["Number","prototype"],"%ObjectPrototype%":["Object","prototype"],"%ObjProto_toString%":["Object","prototype","toString"],"%ObjProto_valueOf%":["Object","prototype","valueOf"],"%PromisePrototype%":["Promise","prototype"],"%PromiseProto_then%":["Promise","prototype","then"],"%Promise_all%":["Promise","all"],"%Promise_reject%":["Promise","reject"],"%Promise_resolve%":["Promise","resolve"],"%RangeErrorPrototype%":["RangeError","prototype"],"%ReferenceErrorPrototype%":["ReferenceError","prototype"],"%RegExpPrototype%":["RegExp","prototype"],"%SetPrototype%":["Set","prototype"],"%SharedArrayBufferPrototype%":["SharedArrayBuffer","prototype"],"%StringPrototype%":["String","prototype"],"%SymbolPrototype%":["Symbol","prototype"],"%SyntaxErrorPrototype%":["SyntaxError","prototype"],"%TypedArrayPrototype%":["TypedArray","prototype"],"%TypeErrorPrototype%":["TypeError","prototype"],"%Uint8ArrayPrototype%":["Uint8Array","prototype"],"%Uint8ClampedArrayPrototype%":["Uint8ClampedArray","prototype"],"%Uint16ArrayPrototype%":["Uint16Array","prototype"],"%Uint32ArrayPrototype%":["Uint32Array","prototype"],"%URIErrorPrototype%":["URIError","prototype"],"%WeakMapPrototype%":["WeakMap","prototype"],"%WeakSetPrototype%":["WeakSet","prototype"]},J0=w1(),U0=fq(),L0=J0.call(V0,Array.prototype.concat),i=J0.call(s,Array.prototype.splice),_=J0.call(V0,String.prototype.replace),r=J0.call(V0,String.prototype.slice),n=J0.call(V0,RegExp.prototype.exec),Z0=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,p=/\\(\\)?/g,P=function(f){var v=r(f,0,1),b=r(f,-1);if(v==="%"&&b!=="%")throw new X("invalid intrinsic syntax, expected closing `%`");else if(b==="%"&&v!=="%")throw new X("invalid intrinsic syntax, expected opening `%`");var e=[];return _(f,Z0,function(I,t,T,K){e[e.length]=T?_(K,p,"$1"):t||I}),e},R=function(f,v){var b=f,e;if(U0(m,b))e=m[b],b="%"+e[0]+"%";if(U0(N,b)){var I=N[b];if(I===S)I=$0(b);if(typeof I>"u"&&!v)throw new Q("intrinsic "+f+" exists, but is not available. Please file an issue!");return{alias:e,name:b,value:I}}throw new X("intrinsic "+f+" does not exist!")};return j6=function(f,v){if(typeof f!=="string"||f.length===0)throw new Q("intrinsic name must be a non-empty string");if(arguments.length>1&&typeof v!=="boolean")throw new Q('"allowMissing" argument must be a boolean');if(n(/^%?[^%]*%?$/,f)===null)throw new X("`%` may not be present anywhere but at the beginning and end of the intrinsic name");var b=P(f),e=b.length>0?b[0]:"",I=R("%"+e+"%",v),t=I.name,T=I.value,K=!1,q=I.alias;if(q)e=q[0],i(b,L0([0,1],q));for(var w=1,x=!0;w=b.length){var q0=j(T,l);if(x=!!q0,x&&"get"in q0&&!("originalValue"in q0.get))T=q0.get;else T=T[l]}else x=U0(T,l),T=T[l];if(x&&!K)N[t]=T}}return T},j6}var z6,bY;function LQ(){if(bY)return z6;bY=1;var $=BQ(),U=d9(),Y=U([$("%String.prototype.indexOf%")]);return z6=function(J,G){var X=$(J,!!G);if(typeof X==="function"&&Y(J,".prototype.")>-1)return U([X]);return X},z6}var F6,gY;function hq(){if(gY)return F6;gY=1;var $=f9()(),U=LQ(),Y=U("Object.prototype.toString"),Z=function(Q){if($&&Q&&typeof Q==="object"&&Symbol.toStringTag in Q)return!1;return Y(Q)==="[object Arguments]"},J=function(Q){if(Z(Q))return!0;return Q!==null&&typeof Q==="object"&&"length"in Q&&typeof Q.length==="number"&&Q.length>=0&&Y(Q)!=="[object Array]"&&"callee"in Q&&Y(Q.callee)==="[object Function]"},G=function(){return Z(arguments)}();return Z.isLegacyArguments=J,F6=G?Z:J,F6}var N6,xY;function uq(){if(xY)return N6;xY=1;var $=Object.prototype.toString,U=Function.prototype.toString,Y=/^\s*(?:function)?\*/,Z=f9()(),J=Object.getPrototypeOf,G=function(){if(!Z)return!1;try{return Function("return function*() {}")()}catch(Q){}},X;return N6=function(B){if(typeof B!=="function")return!1;if(Y.test(U.call(B)))return!0;if(!Z){var F=$.call(B);return F==="[object GeneratorFunction]"}if(!J)return!1;if(typeof X>"u"){var z=G();X=z?J(z):!1}return J(B)===X},N6}var R6,fY;function dq(){if(fY)return R6;fY=1;var $=Function.prototype.toString,U=typeof Reflect==="object"&&Reflect!==null&&Reflect.apply,Y,Z;if(typeof U==="function"&&typeof Object.defineProperty==="function")try{Y=Object.defineProperty({},"length",{get:function(){throw Z}}),Z={},U(function(){throw 42},null,Y)}catch(j){if(j!==Z)U=null}else U=null;var J=/^\s*class\b/,G=function(M){try{var L=$.call(M);return J.test(L)}catch(A){return!1}},X=function(M){try{if(G(M))return!1;return $.call(M),!0}catch(L){return!1}},Q=Object.prototype.toString,B="[object Object]",F="[object Function]",z="[object GeneratorFunction]",W="[object HTMLAllCollection]",k="[object HTML document.all class]",D="[object HTMLCollection]",C=typeof Symbol==="function"&&!!Symbol.toStringTag,H=!(0 in[,]),O=function(){return!1};if(typeof document==="object"){var V=document.all;if(Q.call(V)===Q.call(document.all))O=function(M){if((H||!M)&&(typeof M>"u"||typeof M==="object"))try{var L=Q.call(M);return(L===W||L===k||L===D||L===B)&&M("")==null}catch(A){}return!1}}return R6=U?function(M){if(O(M))return!0;if(!M)return!1;if(typeof M!=="function"&&typeof M!=="object")return!1;try{U(M,null,Y)}catch(L){if(L!==Z)return!1}return!G(M)&&X(M)}:function(M){if(O(M))return!0;if(!M)return!1;if(typeof M!=="function"&&typeof M!=="object")return!1;if(C)return X(M);if(G(M))return!1;var L=Q.call(M);if(L!==F&&L!==z&&!/^\[object HTML/.test(L))return!1;return X(M)},R6}var D6,hY;function cq(){if(hY)return D6;hY=1;var $=dq(),U=Object.prototype.toString,Y=Object.prototype.hasOwnProperty,Z=function(B,F,z){for(var W=0,k=B.length;W=3)W=z;if(X(B))Z(B,F,W);else if(typeof B==="string")J(B,F,W);else G(B,F,W)},D6}var A6,uY;function mq(){if(uY)return A6;return uY=1,A6=["Float32Array","Float64Array","Int8Array","Int16Array","Int32Array","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array"],A6}var P6,dY;function lq(){if(dY)return P6;dY=1;var $=mq(),U=typeof globalThis>"u"?c0:globalThis;return P6=function(){var Z=[];for(var J=0;J<$.length;J++)if(typeof U[$[J]]==="function")Z[Z.length]=$[J];return Z},P6}var T6={exports:{}},C6,cY;function aq(){if(cY)return C6;cY=1;var $=e1(),U=GQ(),Y=t1(),Z=I1();return C6=function(G,X,Q){if(!G||typeof G!=="object"&&typeof G!=="function")throw new Y("`obj` must be an object or a function`");if(typeof X!=="string"&&typeof X!=="symbol")throw new Y("`property` must be a string or a symbol`");if(arguments.length>3&&typeof arguments[3]!=="boolean"&&arguments[3]!==null)throw new Y("`nonEnumerable`, if provided, must be a boolean or null");if(arguments.length>4&&typeof arguments[4]!=="boolean"&&arguments[4]!==null)throw new Y("`nonWritable`, if provided, must be a boolean or null");if(arguments.length>5&&typeof arguments[5]!=="boolean"&&arguments[5]!==null)throw new Y("`nonConfigurable`, if provided, must be a boolean or null");if(arguments.length>6&&typeof arguments[6]!=="boolean")throw new Y("`loose`, if provided, must be a boolean");var B=arguments.length>3?arguments[3]:null,F=arguments.length>4?arguments[4]:null,z=arguments.length>5?arguments[5]:null,W=arguments.length>6?arguments[6]:!1,k=!!Z&&Z(G,X);if($)$(G,X,{configurable:z===null&&k?k.configurable:!z,enumerable:B===null&&k?k.enumerable:!B,value:Q,writable:F===null&&k?k.writable:!F});else if(W||!B&&!F&&!z)G[X]=Q;else throw new U("This environment does not support defining a property as non-configurable, non-writable, or non-enumerable.")},C6}var O6,mY;function pq(){if(mY)return O6;mY=1;var $=e1(),U=function(){return!!$};return U.hasArrayLengthDefineBug=function(){if(!$)return null;try{return $([],"length",{value:1}).length!==1}catch(Z){return!0}},O6=U,O6}var k6,lY;function iq(){if(lY)return k6;lY=1;var $=BQ(),U=aq(),Y=pq()(),Z=I1(),J=t1(),G=$("%Math.floor%");return k6=function(Q,B){if(typeof Q!=="function")throw new J("`fn` is not a function");if(typeof B!=="number"||B<0||B>4294967295||G(B)!==B)throw new J("`length` must be a positive 32-bit integer");var F=arguments.length>2&&!!arguments[2],z=!0,W=!0;if("length"in Q&&Z){var k=Z(Q,"length");if(k&&!k.configurable)z=!1;if(k&&!k.writable)W=!1}if(z||W||!F)if(Y)U(Q,"length",B,!0,!0);else U(Q,"length",B);return Q},k6}var E6,aY;function rq(){if(aY)return E6;aY=1;var $=w1(),U=u9(),Y=XQ();return E6=function(){return Y($,U,arguments)},E6}var pY;function sq(){if(pY)return T6.exports;return pY=1,function($){var U=iq(),Y=e1(),Z=d9(),J=rq();if($.exports=function(X){var Q=Z(arguments),B=X.length-(arguments.length-1);return U(Q,1+(B>0?B:0),!0)},Y)Y($.exports,"apply",{value:J});else $.exports.apply=J}(T6),T6.exports}var S6,iY;function MQ(){if(iY)return S6;iY=1;var $=cq(),U=lq(),Y=sq(),Z=LQ(),J=I1(),G=VQ(),X=Z("Object.prototype.toString"),Q=f9()(),B=typeof globalThis>"u"?c0:globalThis,F=U(),z=Z("String.prototype.slice"),W=Z("Array.prototype.indexOf",!0)||function(O,V){for(var j=0;j-1)return V;if(V!=="Object")return!1;return C(O)}if(!J)return null;return D(O)},S6}var v6,rY;function nq(){if(rY)return v6;rY=1;var $=MQ();return v6=function(Y){return!!$(Y)},v6}var sY;function oq(){if(sY)return x8;return sY=1,function($){var U=hq(),Y=uq(),Z=MQ(),J=nq();function G(w){return w.call.bind(w)}var X=typeof BigInt<"u",Q=typeof Symbol<"u",B=G(Object.prototype.toString),F=G(Number.prototype.valueOf),z=G(String.prototype.valueOf),W=G(Boolean.prototype.valueOf);if(X)var k=G(BigInt.prototype.valueOf);if(Q)var D=G(Symbol.prototype.valueOf);function C(w,x){if(typeof w!=="object")return!1;try{return x(w),!0}catch(l){return!1}}$.isArgumentsObject=U,$.isGeneratorFunction=Y,$.isTypedArray=J;function H(w){return typeof Promise<"u"&&w instanceof Promise||w!==null&&typeof w==="object"&&typeof w.then==="function"&&typeof w.catch==="function"}$.isPromise=H;function O(w){if(typeof ArrayBuffer<"u"&&ArrayBuffer.isView)return ArrayBuffer.isView(w);return J(w)||r(w)}$.isArrayBufferView=O;function V(w){return Z(w)==="Uint8Array"}$.isUint8Array=V;function j(w){return Z(w)==="Uint8ClampedArray"}$.isUint8ClampedArray=j;function M(w){return Z(w)==="Uint16Array"}$.isUint16Array=M;function L(w){return Z(w)==="Uint32Array"}$.isUint32Array=L;function A(w){return Z(w)==="Int8Array"}$.isInt8Array=A;function y(w){return Z(w)==="Int16Array"}$.isInt16Array=y;function g(w){return Z(w)==="Int32Array"}$.isInt32Array=g;function d(w){return Z(w)==="Float32Array"}$.isFloat32Array=d;function E(w){return Z(w)==="Float64Array"}$.isFloat64Array=E;function s(w){return Z(w)==="BigInt64Array"}$.isBigInt64Array=s;function V0(w){return Z(w)==="BigUint64Array"}$.isBigUint64Array=V0;function S(w){return B(w)==="[object Map]"}S.working=typeof Map<"u"&&S(new Map);function h(w){if(typeof Map>"u")return!1;return S.working?S(w):w instanceof Map}$.isMap=h;function N(w){return B(w)==="[object Set]"}N.working=typeof Set<"u"&&N(new Set);function a(w){if(typeof Set>"u")return!1;return N.working?N(w):w instanceof Set}$.isSet=a;function $0(w){return B(w)==="[object WeakMap]"}$0.working=typeof WeakMap<"u"&&$0(new WeakMap);function m(w){if(typeof WeakMap>"u")return!1;return $0.working?$0(w):w instanceof WeakMap}$.isWeakMap=m;function J0(w){return B(w)==="[object WeakSet]"}J0.working=typeof WeakSet<"u"&&J0(new WeakSet);function U0(w){return J0(w)}$.isWeakSet=U0;function L0(w){return B(w)==="[object ArrayBuffer]"}L0.working=typeof ArrayBuffer<"u"&&L0(new ArrayBuffer);function i(w){if(typeof ArrayBuffer>"u")return!1;return L0.working?L0(w):w instanceof ArrayBuffer}$.isArrayBuffer=i;function _(w){return B(w)==="[object DataView]"}_.working=typeof ArrayBuffer<"u"&&typeof DataView<"u"&&_(new DataView(new ArrayBuffer(1),0,1));function r(w){if(typeof DataView>"u")return!1;return _.working?_(w):w instanceof DataView}$.isDataView=r;var n=typeof SharedArrayBuffer<"u"?SharedArrayBuffer:void 0;function Z0(w){return B(w)==="[object SharedArrayBuffer]"}function p(w){if(typeof n>"u")return!1;if(typeof Z0.working>"u")Z0.working=Z0(new n);return Z0.working?Z0(w):w instanceof n}$.isSharedArrayBuffer=p;function P(w){return B(w)==="[object AsyncFunction]"}$.isAsyncFunction=P;function R(w){return B(w)==="[object Map Iterator]"}$.isMapIterator=R;function c(w){return B(w)==="[object Set Iterator]"}$.isSetIterator=c;function f(w){return B(w)==="[object Generator]"}$.isGeneratorObject=f;function v(w){return B(w)==="[object WebAssembly.Module]"}$.isWebAssemblyCompiledModule=v;function b(w){return C(w,F)}$.isNumberObject=b;function e(w){return C(w,z)}$.isStringObject=e;function I(w){return C(w,W)}$.isBooleanObject=I;function t(w){return X&&C(w,k)}$.isBigIntObject=t;function T(w){return Q&&C(w,D)}$.isSymbolObject=T;function K(w){return b(w)||e(w)||I(w)||t(w)||T(w)}$.isBoxedPrimitive=K;function q(w){return typeof Uint8Array<"u"&&(i(w)||p(w))}$.isAnyArrayBuffer=q,["isProxy","isExternal","isModuleNamespaceObject"].forEach(function(w){Object.defineProperty($,w,{enumerable:!1,value:function(){throw Error(w+" is not supported in userland")}})})}(x8),x8}var _6,nY;function tq(){if(nY)return _6;return nY=1,_6=function(U){return U&&typeof U==="object"&&typeof U.copy==="function"&&typeof U.fill==="function"&&typeof U.readUInt8==="function"},_6}var oY;function IQ(){if(oY)return g8;return oY=1,function($){var U=Object.getOwnPropertyDescriptors||function(r){var n=Object.keys(r),Z0={};for(var p=0;p=p)return c;switch(c){case"%s":return String(Z0[n++]);case"%d":return Number(Z0[n++]);case"%j":try{return JSON.stringify(Z0[n++])}catch(f){return"[Circular]"}default:return c}});for(var R=Z0[n];n"u")return function(){return $.deprecate(_,r).apply(this,arguments)};var n=!1;function Z0(){if(!n){if(j0.throwDeprecation)throw Error(r);else if(j0.traceDeprecation)console.trace(r);else console.error(r);n=!0}return _.apply(this,arguments)}return Z0};var Z={},J=/^$/;if(j0.env.NODE_DEBUG){var G=j0.env.NODE_DEBUG;G=G.replace(/[|\\{}()[\]^$+?.]/g,"\\$&").replace(/\*/g,".*").replace(/,/g,"$|^").toUpperCase(),J=new RegExp("^"+G+"$","i")}$.debuglog=function(_){if(_=_.toUpperCase(),!Z[_])if(J.test(_)){var r=j0.pid;Z[_]=function(){var n=$.format.apply($,arguments);console.error("%s %d: %s",_,r,n)}}else Z[_]=function(){};return Z[_]};function X(_,r){var n={seen:[],stylize:B};if(arguments.length>=3)n.depth=arguments[2];if(arguments.length>=4)n.colors=arguments[3];if(V(r))n.showHidden=r;else if(r)$._extend(n,r);if(g(n.showHidden))n.showHidden=!1;if(g(n.depth))n.depth=2;if(g(n.colors))n.colors=!1;if(g(n.customInspect))n.customInspect=!0;if(n.colors)n.stylize=Q;return z(n,_,n.depth)}$.inspect=X,X.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},X.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"};function Q(_,r){var n=X.styles[r];if(n)return"\x1B["+X.colors[n][0]+"m"+_+"\x1B["+X.colors[n][1]+"m";else return _}function B(_,r){return _}function F(_){var r={};return _.forEach(function(n,Z0){r[n]=!0}),r}function z(_,r,n){if(_.customInspect&&r&&S(r.inspect)&&r.inspect!==$.inspect&&!(r.constructor&&r.constructor.prototype===r)){var Z0=r.inspect(n,_);if(!A(Z0))Z0=z(_,Z0,n);return Z0}var p=W(_,r);if(p)return p;var P=Object.keys(r),R=F(P);if(_.showHidden)P=Object.getOwnPropertyNames(r);if(V0(r)&&(P.indexOf("message")>=0||P.indexOf("description")>=0))return k(r);if(P.length===0){if(S(r)){var c=r.name?": "+r.name:"";return _.stylize("[Function"+c+"]","special")}if(d(r))return _.stylize(RegExp.prototype.toString.call(r),"regexp");if(s(r))return _.stylize(Date.prototype.toString.call(r),"date");if(V0(r))return k(r)}var f="",v=!1,b=["{","}"];if(O(r))v=!0,b=["[","]"];if(S(r)){var e=r.name?": "+r.name:"";f=" [Function"+e+"]"}if(d(r))f=" "+RegExp.prototype.toString.call(r);if(s(r))f=" "+Date.prototype.toUTCString.call(r);if(V0(r))f=" "+k(r);if(P.length===0&&(!v||r.length==0))return b[0]+f+b[1];if(n<0)if(d(r))return _.stylize(RegExp.prototype.toString.call(r),"regexp");else return _.stylize("[Object]","special");_.seen.push(r);var I;if(v)I=D(_,r,n,R,P);else I=P.map(function(t){return C(_,r,n,R,t,v)});return _.seen.pop(),H(I,f,b)}function W(_,r){if(g(r))return _.stylize("undefined","undefined");if(A(r)){var n="'"+JSON.stringify(r).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return _.stylize(n,"string")}if(L(r))return _.stylize(""+r,"number");if(V(r))return _.stylize(""+r,"boolean");if(j(r))return _.stylize("null","null")}function k(_){return"["+Error.prototype.toString.call(_)+"]"}function D(_,r,n,Z0,p){var P=[];for(var R=0,c=r.length;R-1)if(P)c=c.split(` -`).map(function(v){return" "+v}).join(` -`).slice(2);else c=` -`+c.split(` -`).map(function(v){return" "+v}).join(` -`)}else c=_.stylize("[Circular]","special");if(g(R)){if(P&&p.match(/^\d+$/))return c;if(R=JSON.stringify(""+p),R.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/))R=R.slice(1,-1),R=_.stylize(R,"name");else R=R.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),R=_.stylize(R,"string")}return R+": "+c}function H(_,r,n){var Z0=_.reduce(function(p,P){if(P.indexOf(` -`)>=0);return p+P.replace(/\u001b\[\d\d?m/g,"").length+1},0);if(Z0>60)return n[0]+(r===""?"":r+` - `)+" "+_.join(`, - `)+" "+n[1];return n[0]+r+" "+_.join(", ")+" "+n[1]}$.types=oq();function O(_){return Array.isArray(_)}$.isArray=O;function V(_){return typeof _==="boolean"}$.isBoolean=V;function j(_){return _===null}$.isNull=j;function M(_){return _==null}$.isNullOrUndefined=M;function L(_){return typeof _==="number"}$.isNumber=L;function A(_){return typeof _==="string"}$.isString=A;function y(_){return typeof _==="symbol"}$.isSymbol=y;function g(_){return _===void 0}$.isUndefined=g;function d(_){return E(_)&&N(_)==="[object RegExp]"}$.isRegExp=d,$.types.isRegExp=d;function E(_){return typeof _==="object"&&_!==null}$.isObject=E;function s(_){return E(_)&&N(_)==="[object Date]"}$.isDate=s,$.types.isDate=s;function V0(_){return E(_)&&(N(_)==="[object Error]"||_ instanceof Error)}$.isError=V0,$.types.isNativeError=V0;function S(_){return typeof _==="function"}$.isFunction=S;function h(_){return _===null||typeof _==="boolean"||typeof _==="number"||typeof _==="string"||typeof _==="symbol"||typeof _>"u"}$.isPrimitive=h,$.isBuffer=tq();function N(_){return Object.prototype.toString.call(_)}function a(_){return _<10?"0"+_.toString(10):_.toString(10)}var $0=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function m(){var _=new Date,r=[a(_.getHours()),a(_.getMinutes()),a(_.getSeconds())].join(":");return[_.getDate(),$0[_.getMonth()],r].join(" ")}$.log=function(){console.log("%s - %s",m(),$.format.apply($,arguments))},$.inherits=R2(),$._extend=function(_,r){if(!r||!E(r))return _;var n=Object.keys(r),Z0=n.length;while(Z0--)_[n[Z0]]=r[n[Z0]];return _};function J0(_,r){return Object.prototype.hasOwnProperty.call(_,r)}var U0=typeof Symbol<"u"?Symbol("util.promisify.custom"):void 0;$.promisify=function(r){if(typeof r!=="function")throw TypeError('The "original" argument must be of type Function');if(U0&&r[U0]){var n=r[U0];if(typeof n!=="function")throw TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(n,U0,{value:n,enumerable:!1,writable:!1,configurable:!0}),n}function n(){var Z0,p,P=new Promise(function(f,v){Z0=f,p=v}),R=[];for(var c=0;c0)this.tail.next=V;else this.head=V;this.tail=V,++this.length}},{key:"unshift",value:function(O){var V={data:O,next:this.head};if(this.length===0)this.tail=V;this.head=V,++this.length}},{key:"shift",value:function(){if(this.length===0)return;var O=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;return--this.length,O}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(O){if(this.length===0)return"";var V=this.head,j=""+V.data;while(V=V.next)j+=O+V.data;return j}},{key:"concat",value:function(O){if(this.length===0)return F.alloc(0);var V=F.allocUnsafe(O>>>0),j=this.head,M=0;while(j)D(j.data,V,M),M+=j.data.length,j=j.next;return V}},{key:"consume",value:function(O,V){var j;if(OL.length?L.length:O;if(A===L.length)M+=L;else M+=L.slice(0,O);if(O-=A,O===0){if(A===L.length)if(++j,V.next)this.head=V.next;else this.head=this.tail=null;else this.head=V,V.data=L.slice(A);break}++j}return this.length-=j,M}},{key:"_getBuffer",value:function(O){var V=F.allocUnsafe(O),j=this.head,M=1;j.data.copy(V),O-=j.data.length;while(j=j.next){var L=j.data,A=O>L.length?L.length:O;if(L.copy(V,V.length-O,0,A),O-=A,O===0){if(A===L.length)if(++M,j.next)this.head=j.next;else this.head=this.tail=null;else this.head=j,j.data=L.slice(A);break}++M}return this.length-=M,V}},{key:k,value:function(O,V){return W(this,U(U({},V),{},{depth:0,customInspect:!1}))}}]),C}(),y6}var b6,eY;function wQ(){if(eY)return b6;eY=1;function $(X,Q){var B=this,F=this._readableState&&this._readableState.destroyed,z=this._writableState&&this._writableState.destroyed;if(F||z){if(Q)Q(X);else if(X){if(!this._writableState)j0.nextTick(J,this,X);else if(!this._writableState.errorEmitted)this._writableState.errorEmitted=!0,j0.nextTick(J,this,X)}return this}if(this._readableState)this._readableState.destroyed=!0;if(this._writableState)this._writableState.destroyed=!0;return this._destroy(X||null,function(W){if(!Q&&W)if(!B._writableState)j0.nextTick(U,B,W);else if(!B._writableState.errorEmitted)B._writableState.errorEmitted=!0,j0.nextTick(U,B,W);else j0.nextTick(Y,B);else if(Q)j0.nextTick(Y,B),Q(W);else j0.nextTick(Y,B)}),this}function U(X,Q){J(X,Q),Y(X)}function Y(X){if(X._writableState&&!X._writableState.emitClose)return;if(X._readableState&&!X._readableState.emitClose)return;X.emit("close")}function Z(){if(this._readableState)this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1;if(this._writableState)this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1}function J(X,Q){X.emit("error",Q)}function G(X,Q){var{_readableState:B,_writableState:F}=X;if(B&&B.autoDestroy||F&&F.autoDestroy)X.destroy(Q);else X.emit("error",Q)}return b6={destroy:$,undestroy:Z,errorOrDestroy:G},b6}var g6={},$Z;function i2(){if($Z)return g6;$Z=1;function $(Q,B){Q.prototype=Object.create(B.prototype),Q.prototype.constructor=Q,Q.__proto__=B}var U={};function Y(Q,B,F){if(!F)F=Error;function z(k,D,C){if(typeof B==="string")return B;else return B(k,D,C)}var W=function(k){$(D,k);function D(C,H,O){return k.call(this,z(C,H,O))||this}return D}(F);W.prototype.name=F.name,W.prototype.code=Q,U[Q]=W}function Z(Q,B){if(Array.isArray(Q)){var F=Q.length;if(Q=Q.map(function(z){return String(z)}),F>2)return"one of ".concat(B," ").concat(Q.slice(0,F-1).join(", "),", or ")+Q[F-1];else if(F===2)return"one of ".concat(B," ").concat(Q[0]," or ").concat(Q[1]);else return"of ".concat(B," ").concat(Q[0])}else return"of ".concat(B," ").concat(String(Q))}function J(Q,B,F){return Q.substr(0,B.length)===B}function G(Q,B,F){if(F===void 0||F>Q.length)F=Q.length;return Q.substring(F-B.length,F)===B}function X(Q,B,F){if(typeof F!=="number")F=0;if(F+B.length>Q.length)return!1;else return Q.indexOf(B,F)!==-1}return Y("ERR_INVALID_OPT_VALUE",function(Q,B){return'The value "'+B+'" is invalid for option "'+Q+'"'},TypeError),Y("ERR_INVALID_ARG_TYPE",function(Q,B,F){var z;if(typeof B==="string"&&J(B,"not "))z="must not be",B=B.replace(/^not /,"");else z="must be";var W;if(G(Q," argument"))W="The ".concat(Q," ").concat(z," ").concat(Z(B,"type"));else{var k=X(Q,".")?"property":"argument";W='The "'.concat(Q,'" ').concat(k," ").concat(z," ").concat(Z(B,"type"))}return W+=". Received type ".concat(typeof F),W},TypeError),Y("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF"),Y("ERR_METHOD_NOT_IMPLEMENTED",function(Q){return"The "+Q+" method is not implemented"}),Y("ERR_STREAM_PREMATURE_CLOSE","Premature close"),Y("ERR_STREAM_DESTROYED",function(Q){return"Cannot call "+Q+" after a stream was destroyed"}),Y("ERR_MULTIPLE_CALLBACK","Callback called multiple times"),Y("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable"),Y("ERR_STREAM_WRITE_AFTER_END","write after end"),Y("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),Y("ERR_UNKNOWN_ENCODING",function(Q){return"Unknown encoding: "+Q},TypeError),Y("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event"),g6.codes=U,g6}var x6,UZ;function WQ(){if(UZ)return x6;UZ=1;var $=i2().codes.ERR_INVALID_OPT_VALUE;function U(Z,J,G){return Z.highWaterMark!=null?Z.highWaterMark:J?Z[G]:null}function Y(Z,J,G,X){var Q=U(J,X,G);if(Q!=null){if(!(isFinite(Q)&&Math.floor(Q)===Q)||Q<0){var B=X?G:"highWaterMark";throw new $(B,Q)}return Math.floor(Q)}return Z.objectMode?16:16384}return x6={getHighWaterMark:Y},x6}var f6,YZ;function $X(){if(YZ)return f6;YZ=1,f6=$;function $(Y,Z){if(U("noDeprecation"))return Y;var J=!1;function G(){if(!J){if(U("throwDeprecation"))throw Error(Z);else if(U("traceDeprecation"))console.trace(Z);else console.warn(Z);J=!0}return Y.apply(this,arguments)}return G}function U(Y){try{if(!c0.localStorage)return!1}catch(J){return!1}var Z=c0.localStorage[Y];if(Z==null)return!1;return String(Z).toLowerCase()==="true"}return f6}var h6,ZZ;function HQ(){if(ZZ)return h6;ZZ=1,h6=d;function $(p){var P=this;this.next=null,this.entry=null,this.finish=function(){Z0(P,p)}}var U;d.WritableState=y;var Y={deprecate:$X()},Z=ZQ(),J=o1().Buffer,G=(typeof c0<"u"?c0:typeof window<"u"?window:typeof self<"u"?self:{}).Uint8Array||function(){};function X(p){return J.from(p)}function Q(p){return J.isBuffer(p)||p instanceof G}var B=wQ(),F=WQ(),z=F.getHighWaterMark,W=i2().codes,k=W.ERR_INVALID_ARG_TYPE,D=W.ERR_METHOD_NOT_IMPLEMENTED,C=W.ERR_MULTIPLE_CALLBACK,H=W.ERR_STREAM_CANNOT_PIPE,O=W.ERR_STREAM_DESTROYED,V=W.ERR_STREAM_NULL_VALUES,j=W.ERR_STREAM_WRITE_AFTER_END,M=W.ERR_UNKNOWN_ENCODING,L=B.errorOrDestroy;R2()(d,Z);function A(){}function y(p,P,R){if(U=U||l2(),p=p||{},typeof R!=="boolean")R=P instanceof U;if(this.objectMode=!!p.objectMode,R)this.objectMode=this.objectMode||!!p.writableObjectMode;this.highWaterMark=z(this,p,"writableHighWaterMark",R),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var c=p.decodeStrings===!1;this.decodeStrings=!c,this.defaultEncoding=p.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(f){$0(P,f)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=p.emitClose!==!1,this.autoDestroy=!!p.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new $(this)}y.prototype.getBuffer=function(){var P=this.bufferedRequest,R=[];while(P)R.push(P),P=P.next;return R},function(){try{Object.defineProperty(y.prototype,"buffer",{get:Y.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(p){}}();var g;if(typeof Symbol==="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]==="function")g=Function.prototype[Symbol.hasInstance],Object.defineProperty(d,Symbol.hasInstance,{value:function(P){if(g.call(this,P))return!0;if(this!==d)return!1;return P&&P._writableState instanceof y}});else g=function(P){return P instanceof this};function d(p){U=U||l2();var P=this instanceof U;if(!P&&!g.call(d,this))return new d(p);if(this._writableState=new y(p,this,P),this.writable=!0,p){if(typeof p.write==="function")this._write=p.write;if(typeof p.writev==="function")this._writev=p.writev;if(typeof p.destroy==="function")this._destroy=p.destroy;if(typeof p.final==="function")this._final=p.final}Z.call(this)}d.prototype.pipe=function(){L(this,new H)};function E(p,P){var R=new j;L(p,R),j0.nextTick(P,R)}function s(p,P,R,c){var f;if(R===null)f=new V;else if(typeof R!=="string"&&!P.objectMode)f=new k("chunk",["string","Buffer"],R);if(f)return L(p,f),j0.nextTick(c,f),!1;return!0}d.prototype.write=function(p,P,R){var c=this._writableState,f=!1,v=!c.objectMode&&Q(p);if(v&&!J.isBuffer(p))p=X(p);if(typeof P==="function")R=P,P=null;if(v)P="buffer";else if(!P)P=c.defaultEncoding;if(typeof R!=="function")R=A;if(c.ending)E(this,R);else if(v||s(this,c,p,R))c.pendingcb++,f=S(this,c,v,p,P,R);return f},d.prototype.cork=function(){this._writableState.corked++},d.prototype.uncork=function(){var p=this._writableState;if(p.corked){if(p.corked--,!p.writing&&!p.corked&&!p.bufferProcessing&&p.bufferedRequest)U0(this,p)}},d.prototype.setDefaultEncoding=function(P){if(typeof P==="string")P=P.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((P+"").toLowerCase())>-1))throw new M(P);return this._writableState.defaultEncoding=P,this},Object.defineProperty(d.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});function V0(p,P,R){if(!p.objectMode&&p.decodeStrings!==!1&&typeof P==="string")P=J.from(P,R);return P}Object.defineProperty(d.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});function S(p,P,R,c,f,v){if(!R){var b=V0(P,c,f);if(c!==b)R=!0,f="buffer",c=b}var e=P.objectMode?1:c.length;P.length+=e;var I=P.length>5===6)return 2;else if(V>>4===14)return 3;else if(V>>3===30)return 4;return V>>6===2?-1:-2}function X(V,j,M){var L=j.length-1;if(L=0){if(A>0)V.lastNeed=A-1;return A}if(--L=0){if(A>0)V.lastNeed=A-2;return A}if(--L=0){if(A>0)if(A===2)A=0;else V.lastNeed=A-3;return A}return 0}function Q(V,j,M){if((j[0]&192)!==128)return V.lastNeed=0,"�";if(V.lastNeed>1&&j.length>1){if((j[1]&192)!==128)return V.lastNeed=1,"�";if(V.lastNeed>2&&j.length>2){if((j[2]&192)!==128)return V.lastNeed=2,"�"}}}function B(V){var j=this.lastTotal-this.lastNeed,M=Q(this,V);if(M!==void 0)return M;if(this.lastNeed<=V.length)return V.copy(this.lastChar,j,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);V.copy(this.lastChar,j,0,V.length),this.lastNeed-=V.length}function F(V,j){var M=X(this,V,j);if(!this.lastNeed)return V.toString("utf8",j);this.lastTotal=M;var L=V.length-(M-this.lastNeed);return V.copy(this.lastChar,0,L),V.toString("utf8",j,L)}function z(V){var j=V&&V.length?this.write(V):"";if(this.lastNeed)return j+"�";return j}function W(V,j){if((V.length-j)%2===0){var M=V.toString("utf16le",j);if(M){var L=M.charCodeAt(M.length-1);if(L>=55296&&L<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=V[V.length-2],this.lastChar[1]=V[V.length-1],M.slice(0,-1)}return M}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=V[V.length-1],V.toString("utf16le",j,V.length-1)}function k(V){var j=V&&V.length?this.write(V):"";if(this.lastNeed){var M=this.lastTotal-this.lastNeed;return j+this.lastChar.toString("utf16le",0,M)}return j}function D(V,j){var M=(V.length-j)%3;if(M===0)return V.toString("base64",j);if(this.lastNeed=3-M,this.lastTotal=3,M===1)this.lastChar[0]=V[V.length-1];else this.lastChar[0]=V[V.length-2],this.lastChar[1]=V[V.length-1];return V.toString("base64",j,V.length-M)}function C(V){var j=V&&V.length?this.write(V):"";if(this.lastNeed)return j+this.lastChar.toString("base64",0,3-this.lastNeed);return j}function H(V){return V.toString(this.encoding)}function O(V){return V&&V.length?this.write(V):""}return d6}var c6,KZ;function c9(){if(KZ)return c6;KZ=1;var $=i2().codes.ERR_STREAM_PREMATURE_CLOSE;function U(G){var X=!1;return function(){if(X)return;X=!0;for(var Q=arguments.length,B=Array(Q),F=0;F0){if(typeof b!=="string"&&!T.objectMode&&Object.getPrototypeOf(b)!==Z.prototype)b=G(b);if(I)if(T.endEmitted)A(v,new V);else V0(v,T,b,!0);else if(T.ended)A(v,new H);else if(T.destroyed)return!1;else if(T.reading=!1,T.decoder&&!e)if(b=T.decoder.write(b),T.objectMode||b.length!==0)V0(v,T,b,!1);else U0(v,T);else V0(v,T,b,!1)}else if(!I)T.reading=!1,U0(v,T)}return!T.ended&&(T.length=h)v=h;else v--,v|=v>>>1,v|=v>>>2,v|=v>>>4,v|=v>>>8,v|=v>>>16,v++;return v}function a(v,b){if(v<=0||b.length===0&&b.ended)return 0;if(b.objectMode)return 1;if(v!==v)if(b.flowing&&b.length)return b.buffer.head.data.length;else return b.length;if(v>b.highWaterMark)b.highWaterMark=N(v);if(v<=b.length)return v;if(!b.ended)return b.needReadable=!0,0;return b.length}E.prototype.read=function(v){B("read",v),v=parseInt(v,10);var b=this._readableState,e=v;if(v!==0)b.emittedReadable=!1;if(v===0&&b.needReadable&&((b.highWaterMark!==0?b.length>=b.highWaterMark:b.length>0)||b.ended)){if(B("read: emitReadable",b.length,b.ended),b.length===0&&b.ended)R(this);else m(this);return null}if(v=a(v,b),v===0&&b.ended){if(b.length===0)R(this);return null}var I=b.needReadable;if(B("need readable",I),b.length===0||b.length-v0)t=P(v,b);else t=null;if(t===null)b.needReadable=b.length<=b.highWaterMark,v=0;else b.length-=v,b.awaitDrain=0;if(b.length===0){if(!b.ended)b.needReadable=!0;if(e!==v&&b.ended)R(this)}if(t!==null)this.emit("data",t);return t};function $0(v,b){if(B("onEofChunk"),b.ended)return;if(b.decoder){var e=b.decoder.end();if(e&&e.length)b.buffer.push(e),b.length+=b.objectMode?1:e.length}if(b.ended=!0,b.sync)m(v);else if(b.needReadable=!1,!b.emittedReadable)b.emittedReadable=!0,J0(v)}function m(v){var b=v._readableState;if(B("emitReadable",b.needReadable,b.emittedReadable),b.needReadable=!1,!b.emittedReadable)B("emitReadable",b.flowing),b.emittedReadable=!0,j0.nextTick(J0,v)}function J0(v){var b=v._readableState;if(B("emitReadable_",b.destroyed,b.length,b.ended),!b.destroyed&&(b.length||b.ended))v.emit("readable"),b.emittedReadable=!1;b.needReadable=!b.flowing&&!b.ended&&b.length<=b.highWaterMark,p(v)}function U0(v,b){if(!b.readingMore)b.readingMore=!0,j0.nextTick(L0,v,b)}function L0(v,b){while(!b.reading&&!b.ended&&(b.length1&&f(I.pipes,v)!==-1)&&!x)B("false write response, pause",I.awaitDrain),I.awaitDrain++;e.pause()}}function Q0(w0){if(B("onerror",w0),M0(),v.removeListener("error",Q0),U(v,"error")===0)A(v,w0)}g(v,"error",Q0);function q0(){v.removeListener("finish",K0),M0()}v.once("close",q0);function K0(){B("onfinish"),v.removeListener("close",q0),M0()}v.once("finish",K0);function M0(){B("unpipe"),e.unpipe(v)}if(v.emit("pipe",e),!I.flowing)B("pipe resume"),e.resume();return v};function i(v){return function(){var e=v._readableState;if(B("pipeOnDrain",e.awaitDrain),e.awaitDrain)e.awaitDrain--;if(e.awaitDrain===0&&U(v,"data"))e.flowing=!0,p(v)}}E.prototype.unpipe=function(v){var b=this._readableState,e={hasUnpiped:!1};if(b.pipesCount===0)return this;if(b.pipesCount===1){if(v&&v!==b.pipes)return this;if(!v)v=b.pipes;if(b.pipes=null,b.pipesCount=0,b.flowing=!1,v)v.emit("unpipe",this,e);return this}if(!v){var{pipes:I,pipesCount:t}=b;b.pipes=null,b.pipesCount=0,b.flowing=!1;for(var T=0;T0,I.flowing!==!1)this.resume()}else if(v==="readable"){if(!I.endEmitted&&!I.readableListening){if(I.readableListening=I.needReadable=!0,I.flowing=!1,I.emittedReadable=!1,B("on readable",I.length,I.reading),I.length)m(this);else if(!I.reading)j0.nextTick(r,this)}}return e},E.prototype.addListener=E.prototype.on,E.prototype.removeListener=function(v,b){var e=Y.prototype.removeListener.call(this,v,b);if(v==="readable")j0.nextTick(_,this);return e},E.prototype.removeAllListeners=function(v){var b=Y.prototype.removeAllListeners.apply(this,arguments);if(v==="readable"||v===void 0)j0.nextTick(_,this);return b};function _(v){var b=v._readableState;if(b.readableListening=v.listenerCount("readable")>0,b.resumeScheduled&&!b.paused)b.flowing=!0;else if(v.listenerCount("data")>0)v.resume()}function r(v){B("readable nexttick read 0"),v.read(0)}E.prototype.resume=function(){var v=this._readableState;if(!v.flowing)B("resume"),v.flowing=!v.readableListening,n(this,v);return v.paused=!1,this};function n(v,b){if(!b.resumeScheduled)b.resumeScheduled=!0,j0.nextTick(Z0,v,b)}function Z0(v,b){if(B("resume",b.reading),!b.reading)v.read(0);if(b.resumeScheduled=!1,v.emit("resume"),p(v),b.flowing&&!b.reading)v.read(0)}E.prototype.pause=function(){if(B("call pause flowing=%j",this._readableState.flowing),this._readableState.flowing!==!1)B("pause"),this._readableState.flowing=!1,this.emit("pause");return this._readableState.paused=!0,this};function p(v){var b=v._readableState;B("flow",b.flowing);while(b.flowing&&v.read()!==null);}if(E.prototype.wrap=function(v){var b=this,e=this._readableState,I=!1;v.on("end",function(){if(B("wrapped end"),e.decoder&&!e.ended){var K=e.decoder.end();if(K&&K.length)b.push(K)}b.push(null)}),v.on("data",function(K){if(B("wrapped data"),e.decoder)K=e.decoder.write(K);if(e.objectMode&&(K===null||K===void 0))return;else if(!e.objectMode&&(!K||!K.length))return;var q=b.push(K);if(!q)I=!0,v.pause()});for(var t in v)if(this[t]===void 0&&typeof v[t]==="function")this[t]=function(q){return function(){return v[q].apply(v,arguments)}}(t);for(var T=0;T=b.length){if(b.decoder)e=b.buffer.join("");else if(b.buffer.length===1)e=b.buffer.first();else e=b.buffer.concat(b.length);b.buffer.clear()}else e=b.buffer.consume(v,b.decoder);return e}function R(v){var b=v._readableState;if(B("endReadable",b.endEmitted),!b.endEmitted)b.ended=!0,j0.nextTick(c,b,v)}function c(v,b){if(B("endReadableNT",v.endEmitted,v.length),!v.endEmitted&&v.length===0){if(v.endEmitted=!0,b.readable=!1,b.emit("end"),v.autoDestroy){var e=b._writableState;if(!e||e.autoDestroy&&e.finished)b.destroy()}}}if(typeof Symbol==="function")E.from=function(v,b){if(L===void 0)L=ZX();return L(E,v,b)};function f(v,b){for(var e=0,I=v.length;e0;return Q(j,L,A,function(y){if(!O)O=y;if(y)V.forEach(B);if(L)return;V.forEach(B),H(O)})});return D.reduce(F)}return r6=W,r6}var s6,IZ;function m9(){if(IZ)return s6;IZ=1,s6=Y;var $=x9().EventEmitter,U=R2();U(Y,$),Y.Readable=jQ(),Y.Writable=HQ(),Y.Duplex=l2(),Y.Transform=zQ(),Y.PassThrough=QX(),Y.finished=c9(),Y.pipeline=JX(),Y.Stream=Y;function Y(){$.call(this)}return Y.prototype.pipe=function(Z,J){var G=this;function X(D){if(Z.writable){if(Z.write(D)===!1&&G.pause)G.pause()}}G.on("data",X);function Q(){if(G.readable&&G.resume)G.resume()}if(Z.on("drain",Q),!Z._isStdio&&(!J||J.end!==!1))G.on("end",F),G.on("close",z);var B=!1;function F(){if(B)return;B=!0,Z.end()}function z(){if(B)return;if(B=!0,typeof Z.destroy==="function")Z.destroy()}function W(D){if(k(),$.listenerCount(this,"error")===0)throw D}G.on("error",W),Z.on("error",W);function k(){G.removeListener("data",X),Z.removeListener("drain",Q),G.removeListener("end",F),G.removeListener("close",z),G.removeListener("error",W),Z.removeListener("error",W),G.removeListener("end",k),G.removeListener("close",k),Z.removeListener("close",k)}return G.on("end",k),G.on("close",k),Z.on("close",k),Z.emit("pipe",G),Z},s6}var wZ;function GX(){if(wZ)return _8;return wZ=1,function($){(function(U){U.parser=function(P,R){return new Z(P,R)},U.SAXParser=Z,U.SAXStream=z,U.createStream=F,U.MAX_BUFFER_LENGTH=65536;var Y=["comment","sgmlDecl","textNode","tagName","doctype","procInstName","procInstBody","entity","attribName","attribValue","cdata","script"];U.EVENTS=["text","processinginstruction","sgmldeclaration","doctype","comment","opentagstart","attribute","opentag","closetag","opencdata","cdata","closecdata","error","end","ready","script","opennamespace","closenamespace"];function Z(P,R){if(!(this instanceof Z))return new Z(P,R);var c=this;if(G(c),c.q=c.c="",c.bufferCheckPosition=U.MAX_BUFFER_LENGTH,c.opt=R||{},c.opt.lowercase=c.opt.lowercase||c.opt.lowercasetags,c.looseCase=c.opt.lowercase?"toLowerCase":"toUpperCase",c.tags=[],c.closed=c.closedRoot=c.sawRoot=!1,c.tag=c.error=null,c.strict=!!P,c.noscript=!!(P||c.opt.noscript),c.state=E.BEGIN,c.strictEntities=c.opt.strictEntities,c.ENTITIES=c.strictEntities?Object.create(U.XML_ENTITIES):Object.create(U.ENTITIES),c.attribList=[],c.opt.xmlns)c.ns=Object.create(H);if(c.trackPosition=c.opt.position!==!1,c.trackPosition)c.position=c.line=c.column=0;V0(c,"onready")}if(!Object.create)Object.create=function(P){function R(){}R.prototype=P;var c=new R;return c};if(!Object.keys)Object.keys=function(P){var R=[];for(var c in P)if(P.hasOwnProperty(c))R.push(c);return R};function J(P){var R=Math.max(U.MAX_BUFFER_LENGTH,10),c=0;for(var f=0,v=Y.length;fR)switch(Y[f]){case"textNode":h(P);break;case"cdata":S(P,"oncdata",P.cdata),P.cdata="";break;case"script":S(P,"onscript",P.script),P.script="";break;default:a(P,"Max buffer length exceeded: "+Y[f])}c=Math.max(c,b)}var e=U.MAX_BUFFER_LENGTH-c;P.bufferCheckPosition=e+P.position}function G(P){for(var R=0,c=Y.length;R"||L(P)}function g(P,R){return P.test(R)}function d(P,R){return!g(P,R)}var E=0;U.STATE={BEGIN:E++,BEGIN_WHITESPACE:E++,TEXT:E++,TEXT_ENTITY:E++,OPEN_WAKA:E++,SGML_DECL:E++,SGML_DECL_QUOTED:E++,DOCTYPE:E++,DOCTYPE_QUOTED:E++,DOCTYPE_DTD:E++,DOCTYPE_DTD_QUOTED:E++,COMMENT_STARTING:E++,COMMENT:E++,COMMENT_ENDING:E++,COMMENT_ENDED:E++,CDATA:E++,CDATA_ENDING:E++,CDATA_ENDING_2:E++,PROC_INST:E++,PROC_INST_BODY:E++,PROC_INST_ENDING:E++,OPEN_TAG:E++,OPEN_TAG_SLASH:E++,ATTRIB:E++,ATTRIB_NAME:E++,ATTRIB_NAME_SAW_WHITE:E++,ATTRIB_VALUE:E++,ATTRIB_VALUE_QUOTED:E++,ATTRIB_VALUE_CLOSED:E++,ATTRIB_VALUE_UNQUOTED:E++,ATTRIB_VALUE_ENTITY_Q:E++,ATTRIB_VALUE_ENTITY_U:E++,CLOSE_TAG:E++,CLOSE_TAG_SAW_WHITE:E++,SCRIPT:E++,SCRIPT_ENDING:E++},U.XML_ENTITIES={amp:"&",gt:">",lt:"<",quot:'"',apos:"'"},U.ENTITIES={amp:"&",gt:">",lt:"<",quot:'"',apos:"'",AElig:198,Aacute:193,Acirc:194,Agrave:192,Aring:197,Atilde:195,Auml:196,Ccedil:199,ETH:208,Eacute:201,Ecirc:202,Egrave:200,Euml:203,Iacute:205,Icirc:206,Igrave:204,Iuml:207,Ntilde:209,Oacute:211,Ocirc:212,Ograve:210,Oslash:216,Otilde:213,Ouml:214,THORN:222,Uacute:218,Ucirc:219,Ugrave:217,Uuml:220,Yacute:221,aacute:225,acirc:226,aelig:230,agrave:224,aring:229,atilde:227,auml:228,ccedil:231,eacute:233,ecirc:234,egrave:232,eth:240,euml:235,iacute:237,icirc:238,igrave:236,iuml:239,ntilde:241,oacute:243,ocirc:244,ograve:242,oslash:248,otilde:245,ouml:246,szlig:223,thorn:254,uacute:250,ucirc:251,ugrave:249,uuml:252,yacute:253,yuml:255,copy:169,reg:174,nbsp:160,iexcl:161,cent:162,pound:163,curren:164,yen:165,brvbar:166,sect:167,uml:168,ordf:170,laquo:171,not:172,shy:173,macr:175,deg:176,plusmn:177,sup1:185,sup2:178,sup3:179,acute:180,micro:181,para:182,middot:183,cedil:184,ordm:186,raquo:187,frac14:188,frac12:189,frac34:190,iquest:191,times:215,divide:247,OElig:338,oelig:339,Scaron:352,scaron:353,Yuml:376,fnof:402,circ:710,tilde:732,Alpha:913,Beta:914,Gamma:915,Delta:916,Epsilon:917,Zeta:918,Eta:919,Theta:920,Iota:921,Kappa:922,Lambda:923,Mu:924,Nu:925,Xi:926,Omicron:927,Pi:928,Rho:929,Sigma:931,Tau:932,Upsilon:933,Phi:934,Chi:935,Psi:936,Omega:937,alpha:945,beta:946,gamma:947,delta:948,epsilon:949,zeta:950,eta:951,theta:952,iota:953,kappa:954,lambda:955,mu:956,nu:957,xi:958,omicron:959,pi:960,rho:961,sigmaf:962,sigma:963,tau:964,upsilon:965,phi:966,chi:967,psi:968,omega:969,thetasym:977,upsih:978,piv:982,ensp:8194,emsp:8195,thinsp:8201,zwnj:8204,zwj:8205,lrm:8206,rlm:8207,ndash:8211,mdash:8212,lsquo:8216,rsquo:8217,sbquo:8218,ldquo:8220,rdquo:8221,bdquo:8222,dagger:8224,Dagger:8225,bull:8226,hellip:8230,permil:8240,prime:8242,Prime:8243,lsaquo:8249,rsaquo:8250,oline:8254,frasl:8260,euro:8364,image:8465,weierp:8472,real:8476,trade:8482,alefsym:8501,larr:8592,uarr:8593,rarr:8594,darr:8595,harr:8596,crarr:8629,lArr:8656,uArr:8657,rArr:8658,dArr:8659,hArr:8660,forall:8704,part:8706,exist:8707,empty:8709,nabla:8711,isin:8712,notin:8713,ni:8715,prod:8719,sum:8721,minus:8722,lowast:8727,radic:8730,prop:8733,infin:8734,ang:8736,and:8743,or:8744,cap:8745,cup:8746,int:8747,there4:8756,sim:8764,cong:8773,asymp:8776,ne:8800,equiv:8801,le:8804,ge:8805,sub:8834,sup:8835,nsub:8836,sube:8838,supe:8839,oplus:8853,otimes:8855,perp:8869,sdot:8901,lceil:8968,rceil:8969,lfloor:8970,rfloor:8971,lang:9001,rang:9002,loz:9674,spades:9824,clubs:9827,hearts:9829,diams:9830},Object.keys(U.ENTITIES).forEach(function(P){var R=U.ENTITIES[P],c=typeof R==="number"?String.fromCharCode(R):R;U.ENTITIES[P]=c});for(var s in U.STATE)U.STATE[U.STATE[s]]=s;E=U.STATE;function V0(P,R,c){P[R]&&P[R](c)}function S(P,R,c){if(P.textNode)h(P);V0(P,R,c)}function h(P){if(P.textNode=N(P.opt,P.textNode),P.textNode)V0(P,"ontext",P.textNode);P.textNode=""}function N(P,R){if(P.trim)R=R.trim();if(P.normalize)R=R.replace(/\s+/g," ");return R}function a(P,R){if(h(P),P.trackPosition)R+=` -Line: `+P.line+` -Column: `+P.column+` -Char: `+P.c;return R=Error(R),P.error=R,V0(P,"onerror",R),P}function $0(P){if(P.sawRoot&&!P.closedRoot)m(P,"Unclosed root tag");if(P.state!==E.BEGIN&&P.state!==E.BEGIN_WHITESPACE&&P.state!==E.TEXT)a(P,"Unexpected end");return h(P),P.c="",P.closed=!0,V0(P,"onend"),Z.call(P,P.strict,P.opt),P}function m(P,R){if(typeof P!=="object"||!(P instanceof Z))throw Error("bad call to strictFail");if(P.strict)a(P,R)}function J0(P){if(!P.strict)P.tagName=P.tagName[P.looseCase]();var R=P.tags[P.tags.length-1]||P,c=P.tag={name:P.tagName,attributes:{}};if(P.opt.xmlns)c.ns=R.ns;P.attribList.length=0,S(P,"onopentagstart",c)}function U0(P,R){var c=P.indexOf(":"),f=c<0?["",P]:P.split(":"),v=f[0],b=f[1];if(R&&P==="xmlns")v="xmlns",b="";return{prefix:v,local:b}}function L0(P){if(!P.strict)P.attribName=P.attribName[P.looseCase]();if(P.attribList.indexOf(P.attribName)!==-1||P.tag.attributes.hasOwnProperty(P.attribName)){P.attribName=P.attribValue="";return}if(P.opt.xmlns){var R=U0(P.attribName,!0),c=R.prefix,f=R.local;if(c==="xmlns")if(f==="xml"&&P.attribValue!==D)m(P,"xml: prefix must be bound to "+D+` -Actual: `+P.attribValue);else if(f==="xmlns"&&P.attribValue!==C)m(P,"xmlns: prefix must be bound to "+C+` -Actual: `+P.attribValue);else{var v=P.tag,b=P.tags[P.tags.length-1]||P;if(v.ns===b.ns)v.ns=Object.create(b.ns);v.ns[f]=P.attribValue}P.attribList.push([P.attribName,P.attribValue])}else P.tag.attributes[P.attribName]=P.attribValue,S(P,"onattribute",{name:P.attribName,value:P.attribValue});P.attribName=P.attribValue=""}function i(P,R){if(P.opt.xmlns){var c=P.tag,f=U0(P.tagName);if(c.prefix=f.prefix,c.local=f.local,c.uri=c.ns[f.prefix]||"",c.prefix&&!c.uri)m(P,"Unbound namespace prefix: "+JSON.stringify(P.tagName)),c.uri=f.prefix;var v=P.tags[P.tags.length-1]||P;if(c.ns&&v.ns!==c.ns)Object.keys(c.ns).forEach(function(u){S(P,"onopennamespace",{prefix:u,uri:c.ns[u]})});for(var b=0,e=P.attribList.length;b",P.tagName="",P.state=E.SCRIPT;return}S(P,"onscript",P.script),P.script=""}var R=P.tags.length,c=P.tagName;if(!P.strict)c=c[P.looseCase]();var f=c;while(R--){var v=P.tags[R];if(v.name!==f)m(P,"Unexpected close tag");else break}if(R<0){m(P,"Unmatched closing tag: "+P.tagName),P.textNode+="",P.state=E.TEXT;return}P.tagName=c;var b=P.tags.length;while(b-- >R){var e=P.tag=P.tags.pop();P.tagName=P.tag.name,S(P,"onclosetag",P.tagName);var I={};for(var t in e.ns)I[t]=e.ns[t];var T=P.tags[P.tags.length-1]||P;if(P.opt.xmlns&&e.ns!==T.ns)Object.keys(e.ns).forEach(function(K){var q=e.ns[K];S(P,"onclosenamespace",{prefix:K,uri:q})})}if(R===0)P.closedRoot=!0;P.tagName=P.attribValue=P.attribName="",P.attribList.length=0,P.state=E.TEXT}function r(P){var R=P.entity,c=R.toLowerCase(),f,v="";if(P.ENTITIES[R])return P.ENTITIES[R];if(P.ENTITIES[c])return P.ENTITIES[c];if(R=c,R.charAt(0)==="#")if(R.charAt(1)==="x")R=R.slice(2),f=parseInt(R,16),v=f.toString(16);else R=R.slice(1),f=parseInt(R,10),v=f.toString(10);if(R=R.replace(/^0+/,""),isNaN(f)||v.toLowerCase()!==R)return m(P,"Invalid character entity"),"&"+P.entity+";";return String.fromCodePoint(f)}function n(P,R){if(R==="<")P.state=E.OPEN_WAKA,P.startTagPosition=P.position;else if(!L(R))m(P,"Non-whitespace before first tag."),P.textNode=R,P.state=E.TEXT}function Z0(P,R){var c="";if(R")S(R,"onsgmldeclaration",R.sgmlDecl),R.sgmlDecl="",R.state=E.TEXT;else if(A(f))R.state=E.SGML_DECL_QUOTED,R.sgmlDecl+=f;else R.sgmlDecl+=f;continue;case E.SGML_DECL_QUOTED:if(f===R.q)R.state=E.SGML_DECL,R.q="";R.sgmlDecl+=f;continue;case E.DOCTYPE:if(f===">")R.state=E.TEXT,S(R,"ondoctype",R.doctype),R.doctype=!0;else if(R.doctype+=f,f==="[")R.state=E.DOCTYPE_DTD;else if(A(f))R.state=E.DOCTYPE_QUOTED,R.q=f;continue;case E.DOCTYPE_QUOTED:if(R.doctype+=f,f===R.q)R.q="",R.state=E.DOCTYPE;continue;case E.DOCTYPE_DTD:if(R.doctype+=f,f==="]")R.state=E.DOCTYPE;else if(A(f))R.state=E.DOCTYPE_DTD_QUOTED,R.q=f;continue;case E.DOCTYPE_DTD_QUOTED:if(R.doctype+=f,f===R.q)R.state=E.DOCTYPE_DTD,R.q="";continue;case E.COMMENT:if(f==="-")R.state=E.COMMENT_ENDING;else R.comment+=f;continue;case E.COMMENT_ENDING:if(f==="-"){if(R.state=E.COMMENT_ENDED,R.comment=N(R.opt,R.comment),R.comment)S(R,"oncomment",R.comment);R.comment=""}else R.comment+="-"+f,R.state=E.COMMENT;continue;case E.COMMENT_ENDED:if(f!==">")m(R,"Malformed comment"),R.comment+="--"+f,R.state=E.COMMENT;else R.state=E.TEXT;continue;case E.CDATA:if(f==="]")R.state=E.CDATA_ENDING;else R.cdata+=f;continue;case E.CDATA_ENDING:if(f==="]")R.state=E.CDATA_ENDING_2;else R.cdata+="]"+f,R.state=E.CDATA;continue;case E.CDATA_ENDING_2:if(f===">"){if(R.cdata)S(R,"oncdata",R.cdata);S(R,"onclosecdata"),R.cdata="",R.state=E.TEXT}else if(f==="]")R.cdata+="]";else R.cdata+="]]"+f,R.state=E.CDATA;continue;case E.PROC_INST:if(f==="?")R.state=E.PROC_INST_ENDING;else if(L(f))R.state=E.PROC_INST_BODY;else R.procInstName+=f;continue;case E.PROC_INST_BODY:if(!R.procInstBody&&L(f))continue;else if(f==="?")R.state=E.PROC_INST_ENDING;else R.procInstBody+=f;continue;case E.PROC_INST_ENDING:if(f===">")S(R,"onprocessinginstruction",{name:R.procInstName,body:R.procInstBody}),R.procInstName=R.procInstBody="",R.state=E.TEXT;else R.procInstBody+="?"+f,R.state=E.PROC_INST_BODY;continue;case E.OPEN_TAG:if(g(V,f))R.tagName+=f;else if(J0(R),f===">")i(R);else if(f==="/")R.state=E.OPEN_TAG_SLASH;else{if(!L(f))m(R,"Invalid character in tag name");R.state=E.ATTRIB}continue;case E.OPEN_TAG_SLASH:if(f===">")i(R,!0),_(R);else m(R,"Forward-slash in opening tag not followed by >"),R.state=E.ATTRIB;continue;case E.ATTRIB:if(L(f))continue;else if(f===">")i(R);else if(f==="/")R.state=E.OPEN_TAG_SLASH;else if(g(O,f))R.attribName=f,R.attribValue="",R.state=E.ATTRIB_NAME;else m(R,"Invalid attribute name");continue;case E.ATTRIB_NAME:if(f==="=")R.state=E.ATTRIB_VALUE;else if(f===">")m(R,"Attribute without value"),R.attribValue=R.attribName,L0(R),i(R);else if(L(f))R.state=E.ATTRIB_NAME_SAW_WHITE;else if(g(V,f))R.attribName+=f;else m(R,"Invalid attribute name");continue;case E.ATTRIB_NAME_SAW_WHITE:if(f==="=")R.state=E.ATTRIB_VALUE;else if(L(f))continue;else if(m(R,"Attribute without value"),R.tag.attributes[R.attribName]="",R.attribValue="",S(R,"onattribute",{name:R.attribName,value:""}),R.attribName="",f===">")i(R);else if(g(O,f))R.attribName=f,R.state=E.ATTRIB_NAME;else m(R,"Invalid attribute name"),R.state=E.ATTRIB;continue;case E.ATTRIB_VALUE:if(L(f))continue;else if(A(f))R.q=f,R.state=E.ATTRIB_VALUE_QUOTED;else m(R,"Unquoted attribute value"),R.state=E.ATTRIB_VALUE_UNQUOTED,R.attribValue=f;continue;case E.ATTRIB_VALUE_QUOTED:if(f!==R.q){if(f==="&")R.state=E.ATTRIB_VALUE_ENTITY_Q;else R.attribValue+=f;continue}L0(R),R.q="",R.state=E.ATTRIB_VALUE_CLOSED;continue;case E.ATTRIB_VALUE_CLOSED:if(L(f))R.state=E.ATTRIB;else if(f===">")i(R);else if(f==="/")R.state=E.OPEN_TAG_SLASH;else if(g(O,f))m(R,"No whitespace between attributes"),R.attribName=f,R.attribValue="",R.state=E.ATTRIB_NAME;else m(R,"Invalid attribute name");continue;case E.ATTRIB_VALUE_UNQUOTED:if(!y(f)){if(f==="&")R.state=E.ATTRIB_VALUE_ENTITY_U;else R.attribValue+=f;continue}if(L0(R),f===">")i(R);else R.state=E.ATTRIB;continue;case E.CLOSE_TAG:if(!R.tagName)if(L(f))continue;else if(d(O,f))if(R.script)R.script+="")_(R);else if(g(V,f))R.tagName+=f;else if(R.script)R.script+="")_(R);else m(R,"Invalid characters in closing tag");continue;case E.TEXT_ENTITY:case E.ATTRIB_VALUE_ENTITY_Q:case E.ATTRIB_VALUE_ENTITY_U:var e,I;switch(R.state){case E.TEXT_ENTITY:e=E.TEXT,I="textNode";break;case E.ATTRIB_VALUE_ENTITY_Q:e=E.ATTRIB_VALUE_QUOTED,I="attribValue";break;case E.ATTRIB_VALUE_ENTITY_U:e=E.ATTRIB_VALUE_UNQUOTED,I="attribValue";break}if(f===";")R[I]+=r(R),R.entity="",R.state=e;else if(g(R.entity.length?M:j,f))R.entity+=f;else m(R,"Invalid character in entity name"),R[I]+="&"+R.entity+f,R.entity="",R.state=e;continue;default:throw Error(R,"Unknown state: "+R.state)}}if(R.position>=R.bufferCheckPosition)J(R);return R}if(!String.fromCodePoint)(function(){var P=String.fromCharCode,R=Math.floor,c=function(){var f=16384,v=[],b,e,I=-1,t=arguments.length;if(!t)return"";var T="";while(++I1114111||R(K)!==K)throw RangeError("Invalid code point: "+K);if(K<=65535)v.push(K);else K-=65536,b=(K>>10)+55296,e=K%1024+56320,v.push(b,e);if(I+1===t||v.length>f)T+=P.apply(null,v),v.length=0}return T};if(Object.defineProperty)Object.defineProperty(String,"fromCodePoint",{value:c,configurable:!0,writable:!0});else String.fromCodePoint=c})()})($)}(_8),_8}var n6,WZ;function l9(){if(WZ)return n6;return WZ=1,n6={isArray:function($){if(Array.isArray)return Array.isArray($);return Object.prototype.toString.call($)==="[object Array]"}},n6}var o6,HZ;function a9(){if(HZ)return o6;HZ=1;var $=l9().isArray;return o6={copyOptions:function(U){var Y,Z={};for(Y in U)if(U.hasOwnProperty(Y))Z[Y]=U[Y];return Z},ensureFlagExists:function(U,Y){if(!(U in Y)||typeof Y[U]!=="boolean")Y[U]=!1},ensureSpacesExists:function(U){if(!("spaces"in U)||typeof U.spaces!=="number"&&typeof U.spaces!=="string")U.spaces=0},ensureAlwaysArrayExists:function(U){if(!("alwaysArray"in U)||typeof U.alwaysArray!=="boolean"&&!$(U.alwaysArray))U.alwaysArray=!1},ensureKeyExists:function(U,Y){if(!(U+"Key"in Y)||typeof Y[U+"Key"]!=="string")Y[U+"Key"]=Y.compact?"_"+U:U},checkFnExists:function(U,Y){return U+"Fn"in Y}},o6}var t6,jZ;function FQ(){if(jZ)return t6;jZ=1;var $=GX(),U=a9(),Y=l9().isArray,Z,J;function G(V){return Z=U.copyOptions(V),U.ensureFlagExists("ignoreDeclaration",Z),U.ensureFlagExists("ignoreInstruction",Z),U.ensureFlagExists("ignoreAttributes",Z),U.ensureFlagExists("ignoreText",Z),U.ensureFlagExists("ignoreComment",Z),U.ensureFlagExists("ignoreCdata",Z),U.ensureFlagExists("ignoreDoctype",Z),U.ensureFlagExists("compact",Z),U.ensureFlagExists("alwaysChildren",Z),U.ensureFlagExists("addParent",Z),U.ensureFlagExists("trim",Z),U.ensureFlagExists("nativeType",Z),U.ensureFlagExists("nativeTypeAttributes",Z),U.ensureFlagExists("sanitize",Z),U.ensureFlagExists("instructionHasAttributes",Z),U.ensureFlagExists("captureSpacesBetweenElements",Z),U.ensureAlwaysArrayExists(Z),U.ensureKeyExists("declaration",Z),U.ensureKeyExists("instruction",Z),U.ensureKeyExists("attributes",Z),U.ensureKeyExists("text",Z),U.ensureKeyExists("comment",Z),U.ensureKeyExists("cdata",Z),U.ensureKeyExists("doctype",Z),U.ensureKeyExists("type",Z),U.ensureKeyExists("name",Z),U.ensureKeyExists("elements",Z),U.ensureKeyExists("parent",Z),U.checkFnExists("doctype",Z),U.checkFnExists("instruction",Z),U.checkFnExists("cdata",Z),U.checkFnExists("comment",Z),U.checkFnExists("text",Z),U.checkFnExists("instructionName",Z),U.checkFnExists("elementName",Z),U.checkFnExists("attributeName",Z),U.checkFnExists("attributeValue",Z),U.checkFnExists("attributes",Z),Z}function X(V){var j=Number(V);if(!isNaN(j))return j;var M=V.toLowerCase();if(M==="true")return!0;else if(M==="false")return!1;return V}function Q(V,j){var M;if(Z.compact){if(!J[Z[V+"Key"]]&&(Y(Z.alwaysArray)?Z.alwaysArray.indexOf(Z[V+"Key"])!==-1:Z.alwaysArray))J[Z[V+"Key"]]=[];if(J[Z[V+"Key"]]&&!Y(J[Z[V+"Key"]]))J[Z[V+"Key"]]=[J[Z[V+"Key"]]];if(V+"Fn"in Z&&typeof j==="string")j=Z[V+"Fn"](j,J);if(V==="instruction"&&(("instructionFn"in Z)||("instructionNameFn"in Z))){for(M in j)if(j.hasOwnProperty(M))if("instructionFn"in Z)j[M]=Z.instructionFn(j[M],M,J);else{var L=j[M];delete j[M],j[Z.instructionNameFn(M,L,J)]=L}}if(Y(J[Z[V+"Key"]]))J[Z[V+"Key"]].push(j);else J[Z[V+"Key"]]=j}else{if(!J[Z.elementsKey])J[Z.elementsKey]=[];var A={};if(A[Z.typeKey]=V,V==="instruction"){for(M in j)if(j.hasOwnProperty(M))break;if(A[Z.nameKey]="instructionNameFn"in Z?Z.instructionNameFn(M,j,J):M,Z.instructionHasAttributes){if(A[Z.attributesKey]=j[M][Z.attributesKey],"instructionFn"in Z)A[Z.attributesKey]=Z.instructionFn(A[Z.attributesKey],M,J)}else{if("instructionFn"in Z)j[M]=Z.instructionFn(j[M],M,J);A[Z.instructionKey]=j[M]}}else{if(V+"Fn"in Z)j=Z[V+"Fn"](j,J);A[Z[V+"Key"]]=j}if(Z.addParent)A[Z.parentKey]=J;J[Z.elementsKey].push(A)}}function B(V){if("attributesFn"in Z&&V)V=Z.attributesFn(V,J);if((Z.trim||("attributeValueFn"in Z)||("attributeNameFn"in Z)||Z.nativeTypeAttributes)&&V){var j;for(j in V)if(V.hasOwnProperty(j)){if(Z.trim)V[j]=V[j].trim();if(Z.nativeTypeAttributes)V[j]=X(V[j]);if("attributeValueFn"in Z)V[j]=Z.attributeValueFn(V[j],j,J);if("attributeNameFn"in Z){var M=V[j];delete V[j],V[Z.attributeNameFn(j,V[j],J)]=M}}}return V}function F(V){var j={};if(V.body&&(V.name.toLowerCase()==="xml"||Z.instructionHasAttributes)){var M=/([\w:-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|(\w+))\s*/g,L;while((L=M.exec(V.body))!==null)j[L[1]]=L[2]||L[3]||L[4];j=B(j)}if(V.name.toLowerCase()==="xml"){if(Z.ignoreDeclaration)return;if(J[Z.declarationKey]={},Object.keys(j).length)J[Z.declarationKey][Z.attributesKey]=j;if(Z.addParent)J[Z.declarationKey][Z.parentKey]=J}else{if(Z.ignoreInstruction)return;if(Z.trim)V.body=V.body.trim();var A={};if(Z.instructionHasAttributes&&Object.keys(j).length)A[V.name]={},A[V.name][Z.attributesKey]=j;else A[V.name]=V.body;Q("instruction",A)}}function z(V,j){var M;if(typeof V==="object")j=V.attributes,V=V.name;if(j=B(j),"elementNameFn"in Z)V=Z.elementNameFn(V,J);if(Z.compact){if(M={},!Z.ignoreAttributes&&j&&Object.keys(j).length){M[Z.attributesKey]={};var L;for(L in j)if(j.hasOwnProperty(L))M[Z.attributesKey][L]=j[L]}if(!(V in J)&&(Y(Z.alwaysArray)?Z.alwaysArray.indexOf(V)!==-1:Z.alwaysArray))J[V]=[];if(J[V]&&!Y(J[V]))J[V]=[J[V]];if(Y(J[V]))J[V].push(M);else J[V]=M}else{if(!J[Z.elementsKey])J[Z.elementsKey]=[];if(M={},M[Z.typeKey]="element",M[Z.nameKey]=V,!Z.ignoreAttributes&&j&&Object.keys(j).length)M[Z.attributesKey]=j;if(Z.alwaysChildren)M[Z.elementsKey]=[];J[Z.elementsKey].push(M)}M[Z.parentKey]=J,J=M}function W(V){if(Z.ignoreText)return;if(!V.trim()&&!Z.captureSpacesBetweenElements)return;if(Z.trim)V=V.trim();if(Z.nativeType)V=X(V);if(Z.sanitize)V=V.replace(/&/g,"&").replace(//g,">");Q("text",V)}function k(V){if(Z.ignoreComment)return;if(Z.trim)V=V.trim();Q("comment",V)}function D(V){var j=J[Z.parentKey];if(!Z.addParent)delete J[Z.parentKey];J=j}function C(V){if(Z.ignoreCdata)return;if(Z.trim)V=V.trim();Q("cdata",V)}function H(V){if(Z.ignoreDoctype)return;if(V=V.replace(/^ /,""),Z.trim)V=V.trim();Q("doctype",V)}function O(V){V.note=V}return t6=function(V,j){var M=$.parser(!0,{}),L={};if(J=L,Z=G(j),M.opt={strictEntities:!0},M.onopentag=z,M.ontext=W,M.oncomment=k,M.onclosetag=D,M.onerror=O,M.oncdata=C,M.ondoctype=H,M.onprocessinginstruction=F,M.write(V).close(),L[Z.elementsKey]){var A=L[Z.elementsKey];delete L[Z.elementsKey],L[Z.elementsKey]=A,delete L.text}return L},t6}var e6,zZ;function KX(){if(zZ)return e6;zZ=1;var $=a9(),U=FQ();function Y(Z){var J=$.copyOptions(Z);return $.ensureSpacesExists(J),J}return e6=function(Z,J){var G,X,Q,B;if(G=Y(J),X=U(Z,G),B="compact"in G&&G.compact?"_parent":"parent","addParent"in G&&G.addParent)Q=JSON.stringify(X,function(F,z){return F===B?"_":z},G.spaces);else Q=JSON.stringify(X,null,G.spaces);return Q.replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")},e6}var $9,FZ;function NQ(){if(FZ)return $9;FZ=1;var $=a9(),U=l9().isArray,Y,Z;function J(M){var L=$.copyOptions(M);if($.ensureFlagExists("ignoreDeclaration",L),$.ensureFlagExists("ignoreInstruction",L),$.ensureFlagExists("ignoreAttributes",L),$.ensureFlagExists("ignoreText",L),$.ensureFlagExists("ignoreComment",L),$.ensureFlagExists("ignoreCdata",L),$.ensureFlagExists("ignoreDoctype",L),$.ensureFlagExists("compact",L),$.ensureFlagExists("indentText",L),$.ensureFlagExists("indentCdata",L),$.ensureFlagExists("indentAttributes",L),$.ensureFlagExists("indentInstruction",L),$.ensureFlagExists("fullTagEmptyElement",L),$.ensureFlagExists("noQuotesForNativeAttributes",L),$.ensureSpacesExists(L),typeof L.spaces==="number")L.spaces=Array(L.spaces+1).join(" ");return $.ensureKeyExists("declaration",L),$.ensureKeyExists("instruction",L),$.ensureKeyExists("attributes",L),$.ensureKeyExists("text",L),$.ensureKeyExists("comment",L),$.ensureKeyExists("cdata",L),$.ensureKeyExists("doctype",L),$.ensureKeyExists("type",L),$.ensureKeyExists("name",L),$.ensureKeyExists("elements",L),$.checkFnExists("doctype",L),$.checkFnExists("instruction",L),$.checkFnExists("cdata",L),$.checkFnExists("comment",L),$.checkFnExists("text",L),$.checkFnExists("instructionName",L),$.checkFnExists("elementName",L),$.checkFnExists("attributeName",L),$.checkFnExists("attributeValue",L),$.checkFnExists("attributes",L),$.checkFnExists("fullTagEmptyElement",L),L}function G(M,L,A){return(!A&&M.spaces?` -`:"")+Array(L+1).join(M.spaces)}function X(M,L,A){if(L.ignoreAttributes)return"";if("attributesFn"in L)M=L.attributesFn(M,Z,Y);var y,g,d,E,s=[];for(y in M)if(M.hasOwnProperty(y)&&M[y]!==null&&M[y]!==void 0)E=L.noQuotesForNativeAttributes&&typeof M[y]!=="string"?"":'"',g=""+M[y],g=g.replace(/"/g,"""),d="attributeNameFn"in L?L.attributeNameFn(y,g,Z,Y):y,s.push(L.spaces&&L.indentAttributes?G(L,A+1,!1):" "),s.push(d+"="+E+("attributeValueFn"in L?L.attributeValueFn(g,y,Z,Y):g)+E);if(M&&Object.keys(M).length&&L.spaces&&L.indentAttributes)s.push(G(L,A,!1));return s.join("")}function Q(M,L,A){return Y=M,Z="xml",L.ignoreDeclaration?"":""}function B(M,L,A){if(L.ignoreInstruction)return"";var y;for(y in M)if(M.hasOwnProperty(y))break;var g="instructionNameFn"in L?L.instructionNameFn(y,M[y],Z,Y):y;if(typeof M[y]==="object")return Y=M,Z=g,"";else{var d=M[y]?M[y]:"";if("instructionFn"in L)d=L.instructionFn(d,y,Z,Y);return""}}function F(M,L){return L.ignoreComment?"":""}function z(M,L){return L.ignoreCdata?"":"","]]]]>"))+"]]>"}function W(M,L){return L.ignoreDoctype?"":""}function k(M,L){if(L.ignoreText)return"";return M=""+M,M=M.replace(/&/g,"&"),M=M.replace(/&/g,"&").replace(//g,">"),"textFn"in L?L.textFn(M,Z,Y):M}function D(M,L){var A;if(M.elements&&M.elements.length)for(A=0;A"),M[L.elementsKey]&&M[L.elementsKey].length)y.push(H(M[L.elementsKey],L,A+1)),Y=M,Z=M.name;y.push(L.spaces&&D(M,L)?` -`+Array(A+1).join(L.spaces):""),y.push("")}else y.push("/>");return y.join("")}function H(M,L,A,y){return M.reduce(function(g,d){var E=G(L,A,y&&!g);switch(d.type){case"element":return g+E+C(d,L,A);case"comment":return g+E+F(d[L.commentKey],L);case"doctype":return g+E+W(d[L.doctypeKey],L);case"cdata":return g+(L.indentCdata?E:"")+z(d[L.cdataKey],L);case"text":return g+(L.indentText?E:"")+k(d[L.textKey],L);case"instruction":var s={};return s[d[L.nameKey]]=d[L.attributesKey]?d:d[L.instructionKey],g+(L.indentInstruction?E:"")+B(s,L,A)}},"")}function O(M,L,A){var y;for(y in M)if(M.hasOwnProperty(y))switch(y){case L.parentKey:case L.attributesKey:break;case L.textKey:if(L.indentText||A)return!0;break;case L.cdataKey:if(L.indentCdata||A)return!0;break;case L.instructionKey:if(L.indentInstruction||A)return!0;break;case L.doctypeKey:case L.commentKey:return!0;default:return!0}return!1}function V(M,L,A,y,g){Y=M,Z=L;var d="elementNameFn"in A?A.elementNameFn(L,M):L;if(typeof M>"u"||M===null||M==="")return"fullTagEmptyElementFn"in A&&A.fullTagEmptyElementFn(L,M)||A.fullTagEmptyElement?"<"+d+">":"<"+d+"/>";var E=[];if(L){if(E.push("<"+d),typeof M!=="object")return E.push(">"+k(M,A)+""),E.join("");if(M[A.attributesKey])E.push(X(M[A.attributesKey],A,y));var s=O(M,A,!0)||M[A.attributesKey]&&M[A.attributesKey]["xml:space"]==="preserve";if(!s)if("fullTagEmptyElementFn"in A)s=A.fullTagEmptyElementFn(L,M);else s=A.fullTagEmptyElement;if(s)E.push(">");else return E.push("/>"),E.join("")}if(E.push(j(M,A,y+1,!1)),Y=M,Z=L,L)E.push((g?G(A,y,!1):"")+"");return E.join("")}function j(M,L,A,y){var g,d,E,s=[];for(d in M)if(M.hasOwnProperty(d)){E=U(M[d])?M[d]:[M[d]];for(g=0;g{switch($.type){case void 0:case"element":let U=new p9($.name,$.attributes),Y=$.elements||[];for(let Z of Y){let J=U8(Z);if(J!==void 0)U.push(J)}return U;case"text":return $.text;default:return}};class RQ extends I0{}class p9 extends o{static fromXmlString($){let U=$8.xml2js($,{compact:!1});return U8(U)}constructor($,U){super($);if(U)this.root.push(new RQ(U))}push($){this.root.push($)}}class i9 extends o{constructor($){super("");this._attr=$}prepForXml($){return{_attr:this._attr}}}var VX="";class Y8 extends o{constructor($,U){super($);if(U)this.root=U.root}}var S0=($)=>{if(isNaN($))throw Error(`Invalid value '${$}' specified. Must be an integer.`);return Math.floor($)},W1=($)=>{let U=S0($);if(U<0)throw Error(`Invalid value '${$}' specified. Must be a positive integer.`);return U},Z8=($,U)=>{let Y=U*2;if($.length!==Y||isNaN(Number(`0x${$}`)))throw Error(`Invalid hex value '${$}'. Expected ${Y} digit hex value`);return $},BX=($)=>Z8($,4),DQ=($)=>Z8($,2),D9=($)=>Z8($,1),H1=($)=>{let U=$.slice(-2),Y=$.substring(0,$.length-2);return`${Number(Y)}${U}`},r9=($)=>{let U=H1($);if(parseFloat(U)<0)throw Error(`Invalid value '${U}' specified. Expected a positive number.`);return U},S2=($)=>{if($==="auto")return $;let U=$.charAt(0)==="#"?$.substring(1):$;return Z8(U,3)},e0=($)=>typeof $==="string"?H1($):S0($),AQ=($)=>typeof $==="string"?r9($):W1($),LX=($)=>typeof $==="string"?H1($):S0($),T0=($)=>typeof $==="string"?r9($):W1($),PQ=($)=>{let U=$.substring(0,$.length-1);return`${Number(U)}%`},s9=($)=>{if(typeof $==="number")return S0($);if($.slice(-1)==="%")return PQ($);return H1($)},TQ=W1,CQ=W1,OQ=($)=>$.toISOString();class X0 extends o{constructor($,U=!0){super($);if(U!==!0)this.root.push(new O0({val:U}))}}class q1 extends o{constructor($,U){super($);this.root.push(new O0({val:AQ(U)}))}}class k0 extends o{}class Y2 extends o{constructor($,U){super($);this.root.push(new O0({val:U}))}}var u2=($,U)=>new B0({name:$,attributes:{value:{key:"w:val",value:U}}});class k2 extends o{constructor($,U){super($);this.root.push(new O0({val:U}))}}class kQ extends o{constructor($,U){super($);this.root.push(new O0({val:U}))}}class L2 extends o{constructor($,U){super($);this.root.push(U)}}class B0 extends o{constructor({name:$,attributes:U,children:Y}){super($);if(U)this.root.push(new n1(U));if(Y)this.root.push(...Y)}}var m0={START:"start",CENTER:"center",END:"end",BOTH:"both",MEDIUM_KASHIDA:"mediumKashida",DISTRIBUTE:"distribute",NUM_TAB:"numTab",HIGH_KASHIDA:"highKashida",LOW_KASHIDA:"lowKashida",THAI_DISTRIBUTE:"thaiDistribute",LEFT:"left",RIGHT:"right",JUSTIFIED:"both"},n9=($)=>new B0({name:"w:jc",attributes:{val:{key:"w:val",value:$}}}),N0=($,{color:U,size:Y,space:Z,style:J})=>new B0({name:$,attributes:{style:{key:"w:val",value:J},color:{key:"w:color",value:U===void 0?void 0:S2(U)},size:{key:"w:sz",value:Y===void 0?void 0:TQ(Y)},space:{key:"w:space",value:Z===void 0?void 0:CQ(Z)}}}),Q8={SINGLE:"single",DASH_DOT_STROKED:"dashDotStroked",DASHED:"dashed",DASH_SMALL_GAP:"dashSmallGap",DOT_DASH:"dotDash",DOT_DOT_DASH:"dotDotDash",DOTTED:"dotted",DOUBLE:"double",DOUBLE_WAVE:"doubleWave",INSET:"inset",NIL:"nil",NONE:"none",OUTSET:"outset",THICK:"thick",THICK_THIN_LARGE_GAP:"thickThinLargeGap",THICK_THIN_MEDIUM_GAP:"thickThinMediumGap",THICK_THIN_SMALL_GAP:"thickThinSmallGap",THIN_THICK_LARGE_GAP:"thinThickLargeGap",THIN_THICK_MEDIUM_GAP:"thinThickMediumGap",THIN_THICK_SMALL_GAP:"thinThickSmallGap",THIN_THICK_THIN_LARGE_GAP:"thinThickThinLargeGap",THIN_THICK_THIN_MEDIUM_GAP:"thinThickThinMediumGap",THIN_THICK_THIN_SMALL_GAP:"thinThickThinSmallGap",THREE_D_EMBOSS:"threeDEmboss",THREE_D_ENGRAVE:"threeDEngrave",TRIPLE:"triple",WAVE:"wave"};class o9 extends Q2{constructor($){super("w:pBdr");if($.top)this.root.push(N0("w:top",$.top));if($.bottom)this.root.push(N0("w:bottom",$.bottom));if($.left)this.root.push(N0("w:left",$.left));if($.right)this.root.push(N0("w:right",$.right));if($.between)this.root.push(N0("w:between",$.between))}}class t9 extends o{constructor(){super("w:pBdr");let $=N0("w:bottom",{color:"auto",space:1,style:Q8.SINGLE,size:6});this.root.push($)}}var EQ=({start:$,end:U,left:Y,right:Z,hanging:J,firstLine:G})=>new B0({name:"w:ind",attributes:{start:{key:"w:start",value:$===void 0?void 0:e0($)},end:{key:"w:end",value:U===void 0?void 0:e0(U)},left:{key:"w:left",value:Y===void 0?void 0:e0(Y)},right:{key:"w:right",value:Z===void 0?void 0:e0(Z)},hanging:{key:"w:hanging",value:J===void 0?void 0:T0(J)},firstLine:{key:"w:firstLine",value:G===void 0?void 0:T0(G)}}}),SQ=()=>new B0({name:"w:br"}),e9={BEGIN:"begin",END:"end",SEPARATE:"separate"},$$=($,U)=>new B0({name:"w:fldChar",attributes:{type:{key:"w:fldCharType",value:$},dirty:{key:"w:dirty",value:U}}}),$2=($)=>$$(e9.BEGIN,$),I2=($)=>$$(e9.SEPARATE,$),U2=($)=>$$(e9.END,$),MX={CENTER:"center",INSIDE:"inside",LEFT:"left",OUTSIDE:"outside",RIGHT:"right"},IX={BOTTOM:"bottom",CENTER:"center",INSIDE:"inside",OUTSIDE:"outside",TOP:"top"},wX={DECIMAL:"decimal",UPPER_ROMAN:"upperRoman",LOWER_ROMAN:"lowerRoman",UPPER_LETTER:"upperLetter",LOWER_LETTER:"lowerLetter",ORDINAL:"ordinal",CARDINAL_TEXT:"cardinalText",ORDINAL_TEXT:"ordinalText",HEX:"hex",CHICAGO:"chicago",IDEOGRAPH_DIGITAL:"ideographDigital",JAPANESE_COUNTING:"japaneseCounting",AIUEO:"aiueo",IROHA:"iroha",DECIMAL_FULL_WIDTH:"decimalFullWidth",DECIMAL_HALF_WIDTH:"decimalHalfWidth",JAPANESE_LEGAL:"japaneseLegal",JAPANESE_DIGITAL_TEN_THOUSAND:"japaneseDigitalTenThousand",DECIMAL_ENCLOSED_CIRCLE:"decimalEnclosedCircle",DECIMAL_FULL_WIDTH_2:"decimalFullWidth2",AIUEO_FULL_WIDTH:"aiueoFullWidth",IROHA_FULL_WIDTH:"irohaFullWidth",DECIMAL_ZERO:"decimalZero",BULLET:"bullet",GANADA:"ganada",CHOSUNG:"chosung",DECIMAL_ENCLOSED_FULL_STOP:"decimalEnclosedFullstop",DECIMAL_ENCLOSED_PAREN:"decimalEnclosedParen",DECIMAL_ENCLOSED_CIRCLE_CHINESE:"decimalEnclosedCircleChinese",IDEOGRAPH_ENCLOSED_CIRCLE:"ideographEnclosedCircle",IDEOGRAPH_TRADITIONAL:"ideographTraditional",IDEOGRAPH_ZODIAC:"ideographZodiac",IDEOGRAPH_ZODIAC_TRADITIONAL:"ideographZodiacTraditional",TAIWANESE_COUNTING:"taiwaneseCounting",IDEOGRAPH_LEGAL_TRADITIONAL:"ideographLegalTraditional",TAIWANESE_COUNTING_THOUSAND:"taiwaneseCountingThousand",TAIWANESE_DIGITAL:"taiwaneseDigital",CHINESE_COUNTING:"chineseCounting",CHINESE_LEGAL_SIMPLIFIED:"chineseLegalSimplified",CHINESE_COUNTING_TEN_THOUSAND:"chineseCountingThousand",KOREAN_DIGITAL:"koreanDigital",KOREAN_COUNTING:"koreanCounting",KOREAN_LEGAL:"koreanLegal",KOREAN_DIGITAL_2:"koreanDigital2",VIETNAMESE_COUNTING:"vietnameseCounting",RUSSIAN_LOWER:"russianLower",RUSSIAN_UPPER:"russianUpper",NONE:"none",NUMBER_IN_DASH:"numberInDash",HEBREW_1:"hebrew1",HEBREW_2:"hebrew2",ARABIC_ALPHA:"arabicAlpha",ARABIC_ABJAD:"arabicAbjad",HINDI_VOWELS:"hindiVowels",HINDI_CONSONANTS:"hindiConsonants",HINDI_NUMBERS:"hindiNumbers",HINDI_COUNTING:"hindiCounting",THAI_LETTERS:"thaiLetters",THAI_NUMBERS:"thaiNumbers",THAI_COUNTING:"thaiCounting",BAHT_TEXT:"bahtText",DOLLAR_TEXT:"dollarText"},g0={DEFAULT:"default",PRESERVE:"preserve"};class x0 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{space:"xml:space"})}}class vQ extends o{constructor(){super("w:instrText");this.root.push(new x0({space:g0.PRESERVE})),this.root.push("PAGE")}}class _Q extends o{constructor(){super("w:instrText");this.root.push(new x0({space:g0.PRESERVE})),this.root.push("NUMPAGES")}}class yQ extends o{constructor(){super("w:instrText");this.root.push(new x0({space:g0.PRESERVE})),this.root.push("SECTIONPAGES")}}class bQ extends o{constructor(){super("w:instrText");this.root.push(new x0({space:g0.PRESERVE})),this.root.push("SECTION")}}var j1=({fill:$,color:U,type:Y})=>new B0({name:"w:shd",attributes:{fill:{key:"w:fill",value:$===void 0?void 0:S2($)},color:{key:"w:color",value:U===void 0?void 0:S2(U)},type:{key:"w:val",value:Y}}}),WX={CLEAR:"clear",DIAGONAL_CROSS:"diagCross",DIAGONAL_STRIPE:"diagStripe",HORIZONTAL_CROSS:"horzCross",HORIZONTAL_STRIPE:"horzStripe",NIL:"nil",PERCENT_5:"pct5",PERCENT_10:"pct10",PERCENT_12:"pct12",PERCENT_15:"pct15",PERCENT_20:"pct20",PERCENT_25:"pct25",PERCENT_30:"pct30",PERCENT_35:"pct35",PERCENT_37:"pct37",PERCENT_40:"pct40",PERCENT_45:"pct45",PERCENT_50:"pct50",PERCENT_55:"pct55",PERCENT_60:"pct60",PERCENT_62:"pct62",PERCENT_65:"pct65",PERCENT_70:"pct70",PERCENT_75:"pct75",PERCENT_80:"pct80",PERCENT_85:"pct85",PERCENT_87:"pct87",PERCENT_90:"pct90",PERCENT_95:"pct95",REVERSE_DIAGONAL_STRIPE:"reverseDiagStripe",SOLID:"solid",THIN_DIAGONAL_CROSS:"thinDiagCross",THIN_DIAGONAL_STRIPE:"thinDiagStripe",THIN_HORIZONTAL_CROSS:"thinHorzCross",THIN_REVERSE_DIAGONAL_STRIPE:"thinReverseDiagStripe",THIN_VERTICAL_STRIPE:"thinVertStripe",VERTICAL_STRIPE:"vertStripe"};class _0 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"w:id",author:"w:author",date:"w:date"})}}class gQ extends o{constructor($){super("w:del");this.root.push(new _0({id:$.id,author:$.author,date:$.date}))}}class xQ extends o{constructor($){super("w:ins");this.root.push(new _0({id:$.id,author:$.author,date:$.date}))}}var U$={DOT:"dot"},Y$=($=U$.DOT)=>new B0({name:"w:em",attributes:{val:{key:"w:val",value:$}}}),HX=()=>Y$(U$.DOT);class fQ extends o{constructor($){super("w:spacing");this.root.push(new O0({val:e0($)}))}}class hQ extends o{constructor($){super("w:color");this.root.push(new O0({val:S2($)}))}}class uQ extends o{constructor($){super("w:highlight");this.root.push(new O0({val:$}))}}class dQ extends o{constructor($){super("w:highlightCs");this.root.push(new O0({val:$}))}}var jX=($)=>new B0({name:"w:lang",attributes:{value:{key:"w:val",value:$.value},eastAsia:{key:"w:eastAsia",value:$.eastAsia},bidirectional:{key:"w:bidi",value:$.bidirectional}}}),g1=($,U)=>{if(typeof $==="string"){let Z=$;return new B0({name:"w:rFonts",attributes:{ascii:{key:"w:ascii",value:Z},cs:{key:"w:cs",value:Z},eastAsia:{key:"w:eastAsia",value:Z},hAnsi:{key:"w:hAnsi",value:Z},hint:{key:"w:hint",value:U}}})}let Y=$;return new B0({name:"w:rFonts",attributes:{ascii:{key:"w:ascii",value:Y.ascii},cs:{key:"w:cs",value:Y.cs},eastAsia:{key:"w:eastAsia",value:Y.eastAsia},hAnsi:{key:"w:hAnsi",value:Y.hAnsi},hint:{key:"w:hint",value:Y.hint}}})},cQ=($)=>new B0({name:"w:vertAlign",attributes:{val:{key:"w:val",value:$}}}),zX=()=>cQ("superscript"),FX=()=>cQ("subscript"),Z$={SINGLE:"single",WORDS:"words",DOUBLE:"double",THICK:"thick",DOTTED:"dotted",DOTTEDHEAVY:"dottedHeavy",DASH:"dash",DASHEDHEAVY:"dashedHeavy",DASHLONG:"dashLong",DASHLONGHEAVY:"dashLongHeavy",DOTDASH:"dotDash",DASHDOTHEAVY:"dashDotHeavy",DOTDOTDASH:"dotDotDash",DASHDOTDOTHEAVY:"dashDotDotHeavy",WAVE:"wave",WAVYHEAVY:"wavyHeavy",WAVYDOUBLE:"wavyDouble",NONE:"none"},mQ=($=Z$.SINGLE,U)=>new B0({name:"w:u",attributes:{val:{key:"w:val",value:$},color:{key:"w:color",value:U===void 0?void 0:S2(U)}}}),NX={BLINK_BACKGROUND:"blinkBackground",LIGHTS:"lights",ANTS_BLACK:"antsBlack",ANTS_RED:"antsRed",SHIMMER:"shimmer",SPARKLE:"sparkle",NONE:"none"},RX={BLACK:"black",BLUE:"blue",CYAN:"cyan",DARK_BLUE:"darkBlue",DARK_CYAN:"darkCyan",DARK_GRAY:"darkGray",DARK_GREEN:"darkGreen",DARK_MAGENTA:"darkMagenta",DARK_RED:"darkRed",DARK_YELLOW:"darkYellow",GREEN:"green",LIGHT_GRAY:"lightGray",MAGENTA:"magenta",NONE:"none",RED:"red",WHITE:"white",YELLOW:"yellow"};class J2 extends Q2{constructor($){var U,Y;super("w:rPr");if(!$)return;if($.style)this.push(new Y2("w:rStyle",$.style));if($.font)if(typeof $.font==="string")this.push(g1($.font));else if("name"in $.font)this.push(g1($.font.name,$.font.hint));else this.push(g1($.font));if($.bold!==void 0)this.push(new X0("w:b",$.bold));if($.boldComplexScript===void 0&&$.bold!==void 0||$.boldComplexScript)this.push(new X0("w:bCs",(U=$.boldComplexScript)!=null?U:$.bold));if($.italics!==void 0)this.push(new X0("w:i",$.italics));if($.italicsComplexScript===void 0&&$.italics!==void 0||$.italicsComplexScript)this.push(new X0("w:iCs",(Y=$.italicsComplexScript)!=null?Y:$.italics));if($.smallCaps!==void 0)this.push(new X0("w:smallCaps",$.smallCaps));else if($.allCaps!==void 0)this.push(new X0("w:caps",$.allCaps));if($.strike!==void 0)this.push(new X0("w:strike",$.strike));if($.doubleStrike!==void 0)this.push(new X0("w:dstrike",$.doubleStrike));if($.emboss!==void 0)this.push(new X0("w:emboss",$.emboss));if($.imprint!==void 0)this.push(new X0("w:imprint",$.imprint));if($.noProof!==void 0)this.push(new X0("w:noProof",$.noProof));if($.snapToGrid!==void 0)this.push(new X0("w:snapToGrid",$.snapToGrid));if($.vanish)this.push(new X0("w:vanish",$.vanish));if($.color)this.push(new hQ($.color));if($.characterSpacing)this.push(new fQ($.characterSpacing));if($.scale!==void 0)this.push(new k2("w:w",$.scale));if($.kern)this.push(new q1("w:kern",$.kern));if($.position)this.push(new Y2("w:position",$.position));if($.size!==void 0)this.push(new q1("w:sz",$.size));let Z=$.sizeComplexScript===void 0||$.sizeComplexScript===!0?$.size:$.sizeComplexScript;if(Z)this.push(new q1("w:szCs",Z));if($.highlight)this.push(new uQ($.highlight));let J=$.highlightComplexScript===void 0||$.highlightComplexScript===!0?$.highlight:$.highlightComplexScript;if(J)this.push(new dQ(J));if($.underline)this.push(mQ($.underline.type,$.underline.color));if($.effect)this.push(new Y2("w:effect",$.effect));if($.border)this.push(N0("w:bdr",$.border));if($.shading)this.push(j1($.shading));if($.subScript)this.push(FX());if($.superScript)this.push(zX());if($.rightToLeft!==void 0)this.push(new X0("w:rtl",$.rightToLeft));if($.emphasisMark)this.push(Y$($.emphasisMark.type));if($.language)this.push(jX($.language));if($.specVanish)this.push(new X0("w:specVanish",$.vanish));if($.math)this.push(new X0("w:oMath",$.math));if($.revision)this.push(new J$($.revision))}push($){this.root.push($)}}class Q$ extends J2{constructor($){super($);if($==null?void 0:$.insertion)this.push(new xQ($.insertion));if($==null?void 0:$.deletion)this.push(new gQ($.deletion))}}class J$ extends o{constructor($){super("w:rPrChange");this.root.push(new _0({id:$.id,author:$.author,date:$.date})),this.addChildElement(new J2($))}}class a2 extends o{constructor($){var U;super("w:t");if(typeof $==="string")this.root.push(new x0({space:g0.PRESERVE})),this.root.push($);else this.root.push(new x0({space:(U=$.space)!=null?U:g0.DEFAULT})),this.root.push($.text)}}var N2={CURRENT:"CURRENT",TOTAL_PAGES:"TOTAL_PAGES",TOTAL_PAGES_IN_SECTION:"TOTAL_PAGES_IN_SECTION",CURRENT_SECTION:"SECTION"};class C0 extends o{constructor($){super("w:r");if(Y0(this,"properties"),this.properties=new J2($),this.root.push(this.properties),$.break)for(let U=0;U<$.break;U++)this.root.push(SQ());if($.children)for(let U of $.children){if(typeof U==="string"){switch(U){case N2.CURRENT:this.root.push($2()),this.root.push(new vQ),this.root.push(I2()),this.root.push(U2());break;case N2.TOTAL_PAGES:this.root.push($2()),this.root.push(new _Q),this.root.push(I2()),this.root.push(U2());break;case N2.TOTAL_PAGES_IN_SECTION:this.root.push($2()),this.root.push(new yQ),this.root.push(I2()),this.root.push(U2());break;case N2.CURRENT_SECTION:this.root.push($2()),this.root.push(new bQ),this.root.push(I2()),this.root.push(U2());break;default:this.root.push(new a2(U));break}continue}this.root.push(U)}else if($.text!==void 0)this.root.push(new a2($.text))}}class p2 extends C0{constructor($){super(typeof $==="string"?{text:$}:$)}}class lQ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{char:"w:char",symbolfont:"w:font"})}}var DZ=class extends o{constructor(U="",Y="Wingdings"){super("w:sym");this.root.push(new lQ({char:U,symbolfont:Y}))}};class G$ extends C0{constructor($){if(typeof $==="string"){super({});return this.root.push(new DZ($)),this}super($);this.root.push(new DZ($.char,$.symbolfont))}}var Z9={},z0={},Q9,AZ;function z1(){if(AZ)return Q9;AZ=1,Q9=$;function $(U,Y){if(!U)throw Error(Y||"Assertion failed")}return $.equal=function(Y,Z,J){if(Y!=Z)throw Error(J||"Assertion failed: "+Y+" != "+Z)},Q9}var PZ;function G2(){if(PZ)return z0;PZ=1;var $=z1(),U=R2();z0.inherits=U;function Y(S,h){if((S.charCodeAt(h)&64512)!==55296)return!1;if(h<0||h+1>=S.length)return!1;return(S.charCodeAt(h+1)&64512)===56320}function Z(S,h){if(Array.isArray(S))return S.slice();if(!S)return[];var N=[];if(typeof S==="string"){if(!h){var a=0;for(var $0=0;$0>6|192,N[a++]=m&63|128;else if(Y(S,$0))m=65536+((m&1023)<<10)+(S.charCodeAt(++$0)&1023),N[a++]=m>>18|240,N[a++]=m>>12&63|128,N[a++]=m>>6&63|128,N[a++]=m&63|128;else N[a++]=m>>12|224,N[a++]=m>>6&63|128,N[a++]=m&63|128}}else if(h==="hex"){if(S=S.replace(/[^a-z0-9]+/ig,""),S.length%2!==0)S="0"+S;for($0=0;$0>>24|S>>>8&65280|S<<8&16711680|(S&255)<<24;return h>>>0}z0.htonl=G;function X(S,h){var N="";for(var a=0;a>>0}return m}z0.join32=F;function z(S,h){var N=Array(S.length*4);for(var a=0,$0=0;a>>24,N[$0+1]=m>>>16&255,N[$0+2]=m>>>8&255,N[$0+3]=m&255;else N[$0+3]=m>>>24,N[$0+2]=m>>>16&255,N[$0+1]=m>>>8&255,N[$0]=m&255}return N}z0.split32=z;function W(S,h){return S>>>h|S<<32-h}z0.rotr32=W;function k(S,h){return S<>>32-h}z0.rotl32=k;function D(S,h){return S+h>>>0}z0.sum32=D;function C(S,h,N){return S+h+N>>>0}z0.sum32_3=C;function H(S,h,N,a){return S+h+N+a>>>0}z0.sum32_4=H;function O(S,h,N,a,$0){return S+h+N+a+$0>>>0}z0.sum32_5=O;function V(S,h,N,a){var $0=S[h],m=S[h+1],J0=a+m>>>0,U0=(J0>>0,S[h+1]=J0}z0.sum64=V;function j(S,h,N,a){var $0=h+a>>>0,m=($0>>0}z0.sum64_hi=j;function M(S,h,N,a){var $0=h+a;return $0>>>0}z0.sum64_lo=M;function L(S,h,N,a,$0,m,J0,U0){var L0=0,i=h;i=i+a>>>0,L0+=i>>0,L0+=i>>0,L0+=i>>0}z0.sum64_4_hi=L;function A(S,h,N,a,$0,m,J0,U0){var L0=h+a+m+U0;return L0>>>0}z0.sum64_4_lo=A;function y(S,h,N,a,$0,m,J0,U0,L0,i){var _=0,r=h;r=r+a>>>0,_+=r>>0,_+=r>>0,_+=r>>0,_+=r>>0}z0.sum64_5_hi=y;function g(S,h,N,a,$0,m,J0,U0,L0,i){var _=h+a+m+U0+i;return _>>>0}z0.sum64_5_lo=g;function d(S,h,N){var a=h<<32-N|S>>>N;return a>>>0}z0.rotr64_hi=d;function E(S,h,N){var a=S<<32-N|h>>>N;return a>>>0}z0.rotr64_lo=E;function s(S,h,N){return S>>>N}z0.shr64_hi=s;function V0(S,h,N){var a=S<<32-N|h>>>N;return a>>>0}return z0.shr64_lo=V0,z0}var J9={},TZ;function F1(){if(TZ)return J9;TZ=1;var $=G2(),U=z1();function Y(){this.pending=null,this.pendingTotal=0,this.blockSize=this.constructor.blockSize,this.outSize=this.constructor.outSize,this.hmacStrength=this.constructor.hmacStrength,this.padLength=this.constructor.padLength/8,this.endian="big",this._delta8=this.blockSize/8,this._delta32=this.blockSize/32}return J9.BlockHash=Y,Y.prototype.update=function(J,G){if(J=$.toArray(J,G),!this.pending)this.pending=J;else this.pending=this.pending.concat(J);if(this.pendingTotal+=J.length,this.pending.length>=this._delta8){J=this.pending;var X=J.length%this._delta8;if(this.pending=J.slice(J.length-X,J.length),this.pending.length===0)this.pending=null;J=$.join32(J,0,J.length-X,this.endian);for(var Q=0;Q>>24&255,Q[B++]=J>>>16&255,Q[B++]=J>>>8&255,Q[B++]=J&255}else{Q[B++]=J&255,Q[B++]=J>>>8&255,Q[B++]=J>>>16&255,Q[B++]=J>>>24&255,Q[B++]=0,Q[B++]=0,Q[B++]=0,Q[B++]=0;for(F=8;F>>3}s0.g0_256=B;function F(z){return U(z,17)^U(z,19)^z>>>10}return s0.g1_256=F,s0}var G9,OZ;function DX(){if(OZ)return G9;OZ=1;var $=G2(),U=F1(),Y=aQ(),Z=$.rotl32,J=$.sum32,G=$.sum32_5,X=Y.ft_1,Q=U.BlockHash,B=[1518500249,1859775393,2400959708,3395469782];function F(){if(!(this instanceof F))return new F;Q.call(this),this.h=[1732584193,4023233417,2562383102,271733878,3285377520],this.W=Array(80)}return $.inherits(F,Q),G9=F,F.blockSize=512,F.outSize=160,F.hmacStrength=80,F.padLength=64,F.prototype._update=function(W,k){var D=this.W;for(var C=0;C<16;C++)D[C]=W[k+C];for(;Cthis.blockSize)J=new this.Hash().update(J).digest();U(J.length<=this.blockSize);for(var G=J.length;G{return(Y=U)=>{let Z="",J=Y|0;while(J--)Z+=$[Math.random()*$.length|0];return Z}},yX=($=21)=>{let U="",Y=$|0;while(Y--)U+=vX[Math.random()*64|0];return U},bX=($)=>Math.floor($/25.4*72*20),d0=($)=>Math.floor($*72*20),N1=($=0)=>{let U=$;return()=>++U},rQ=()=>N1(),sQ=()=>N1(1),nQ=()=>N1(),oQ=()=>N1(),R1=()=>yX().toLowerCase(),A9=($)=>SX.sha1().update($ instanceof ArrayBuffer?new Uint8Array($):$).digest("hex"),Y1=($)=>_X("1234567890abcdef",$)(),tQ=()=>`${Y1(8)}-${Y1(4)}-${Y1(4)}-${Y1(4)}-${Y1(12)}`,X1=($)=>new Uint8Array(new TextEncoder().encode($)),eQ={CHARACTER:"character",COLUMN:"column",INSIDE_MARGIN:"insideMargin",LEFT_MARGIN:"leftMargin",MARGIN:"margin",OUTSIDE_MARGIN:"outsideMargin",PAGE:"page",RIGHT_MARGIN:"rightMargin"},$J={BOTTOM_MARGIN:"bottomMargin",INSIDE_MARGIN:"insideMargin",LINE:"line",MARGIN:"margin",OUTSIDE_MARGIN:"outsideMargin",PAGE:"page",PARAGRAPH:"paragraph",TOP_MARGIN:"topMargin"},UJ=()=>new B0({name:"wp:simplePos",attributes:{x:{key:"x",value:0},y:{key:"y",value:0}}}),YJ=($)=>new B0({name:"wp:align",children:[$]}),ZJ=($)=>new B0({name:"wp:posOffset",children:[$.toString()]}),QJ=({relative:$,align:U,offset:Y})=>new B0({name:"wp:positionH",attributes:{relativeFrom:{key:"relativeFrom",value:$!=null?$:eQ.PAGE}},children:[(()=>{if(U)return YJ(U);else if(Y!==void 0)return ZJ(Y);else throw Error("There is no configuration provided for floating position (Align or offset)")})()]}),JJ=({relative:$,align:U,offset:Y})=>new B0({name:"wp:positionV",attributes:{relativeFrom:{key:"relativeFrom",value:$!=null?$:$J.PAGE}},children:[(()=>{if(U)return YJ(U);else if(Y!==void 0)return ZJ(Y);else throw Error("There is no configuration provided for floating position (Align or offset)")})()]}),GJ=(($)=>{return $.CENTER="ctr",$.TOP="t",$.BOTTOM="b",$})(GJ||{}),KJ=($={})=>{var U,Y,Z,J;return new B0({name:"wps:bodyPr",attributes:{lIns:{key:"lIns",value:(U=$.margins)==null?void 0:U.left},rIns:{key:"rIns",value:(Y=$.margins)==null?void 0:Y.right},tIns:{key:"tIns",value:(Z=$.margins)==null?void 0:Z.top},bIns:{key:"bIns",value:(J=$.margins)==null?void 0:J.bottom},anchor:{key:"anchor",value:$.verticalAnchor}},children:[...$.noAutoFit?[new X0("a:noAutofit",$.noAutoFit)]:[]]})},gX=($={txBox:"1"})=>new B0({name:"wps:cNvSpPr",attributes:{txBox:{key:"txBox",value:$.txBox}}}),xX=($)=>new B0({name:"w:txbxContent",children:[...$]}),fX=($)=>new B0({name:"wps:txbx",children:[xX($)]});class qJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{cx:"cx",cy:"cy"})}}class XJ extends o{constructor($,U){super("a:ext");Y0(this,"attributes"),this.attributes=new qJ({cx:$,cy:U}),this.root.push(this.attributes)}}class VJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{x:"x",y:"y"})}}class BJ extends o{constructor($,U){super("a:off");this.root.push(new VJ({x:$!=null?$:0,y:U!=null?U:0}))}}class LJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{flipVertical:"flipV",flipHorizontal:"flipH",rotation:"rot"})}}class K$ extends o{constructor($){var U,Y,Z,J,G,X;super("a:xfrm");Y0(this,"extents"),Y0(this,"offset"),this.root.push(new LJ({flipVertical:(U=$.flip)==null?void 0:U.vertical,flipHorizontal:(Y=$.flip)==null?void 0:Y.horizontal,rotation:$.rotation})),this.offset=new BJ((J=(Z=$.offset)==null?void 0:Z.emus)==null?void 0:J.x,(X=(G=$.offset)==null?void 0:G.emus)==null?void 0:X.y),this.extents=new XJ($.emus.x,$.emus.y),this.root.push(this.offset),this.root.push(this.extents)}}var MJ=()=>new B0({name:"a:noFill"}),hX=($)=>new B0({name:"a:srgbClr",attributes:{value:{key:"val",value:$.value}}}),uX=($)=>new B0({name:"a:schemeClr",attributes:{value:{key:"val",value:$.value}}}),P9=($)=>new B0({name:"a:solidFill",children:[$.type==="rgb"?hX($):uX($)]}),dX=($)=>new B0({name:"a:ln",attributes:{width:{key:"w",value:$.width},cap:{key:"cap",value:$.cap},compoundLine:{key:"cmpd",value:$.compoundLine},align:{key:"algn",value:$.align}},children:[$.type==="noFill"?MJ():$.solidFillType==="rgb"?P9({type:"rgb",value:$.value}):P9({type:"scheme",value:$.value})]});class IJ extends o{constructor(){super("a:avLst")}}class wJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{prst:"prst"})}}class WJ extends o{constructor(){super("a:prstGeom");this.root.push(new wJ({prst:"rect"})),this.root.push(new IJ)}}class HJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{bwMode:"bwMode"})}}class q$ extends o{constructor({element:$,outline:U,solidFill:Y,transform:Z}){super(`${$}:spPr`);if(Y0(this,"form"),this.root.push(new HJ({bwMode:"auto"})),this.form=new K$(Z),this.root.push(this.form),this.root.push(new WJ),U)this.root.push(MJ()),this.root.push(dX(U));if(Y)this.root.push(P9(Y))}}var xZ=($)=>new B0({name:"wps:wsp",children:[gX($.nonVisualProperties),new q$({element:"wps",transform:$.transformation,outline:$.outline,solidFill:$.solidFill}),fX($.children),KJ($.bodyProperties)]});class x1 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{uri:"uri"})}}var cX=($)=>new B0({name:"asvg:svgBlip",attributes:{asvg:{key:"xmlns:asvg",value:"http://schemas.microsoft.com/office/drawing/2016/SVG/main"},embed:{key:"r:embed",value:`rId{${$.fileName}}`}}}),mX=($)=>new B0({name:"a:ext",attributes:{uri:{key:"uri",value:"{96DAC541-7B7A-43D3-8B79-37D633B846F1}"}},children:[cX($)]}),lX=($)=>new B0({name:"a:extLst",children:[mX($)]}),aX=($)=>new B0({name:"a:blip",attributes:{embed:{key:"r:embed",value:`rId{${$.type==="svg"?$.fallback.fileName:$.fileName}}`},cstate:{key:"cstate",value:"none"}},children:$.type==="svg"?[lX($)]:[]});class jJ extends o{constructor(){super("a:srcRect")}}class zJ extends o{constructor(){super("a:fillRect")}}class FJ extends o{constructor(){super("a:stretch");this.root.push(new zJ)}}class NJ extends o{constructor($){super("pic:blipFill");this.root.push(aX($)),this.root.push(new jJ),this.root.push(new FJ)}}class RJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{noChangeAspect:"noChangeAspect",noChangeArrowheads:"noChangeArrowheads"})}}class DJ extends o{constructor(){super("a:picLocks");this.root.push(new RJ({noChangeAspect:1,noChangeArrowheads:1}))}}class AJ extends o{constructor(){super("pic:cNvPicPr");this.root.push(new DJ)}}var PJ=($,U)=>new B0({name:"a:hlinkClick",attributes:R0(W0({},U?{xmlns:{key:"xmlns:a",value:"http://schemas.openxmlformats.org/drawingml/2006/main"}}:{}),{id:{key:"r:id",value:`rId${$}`}})});class TJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"id",name:"name",descr:"descr"})}}class CJ extends o{constructor(){super("pic:cNvPr");this.root.push(new TJ({id:0,name:"",descr:""}))}prepForXml($){for(let U=$.stack.length-1;U>=0;U--){let Y=$.stack[U];if(!(Y instanceof _2))continue;this.root.push(PJ(Y.linkId,!1));break}return super.prepForXml($)}}class OJ extends o{constructor(){super("pic:nvPicPr");this.root.push(new CJ),this.root.push(new AJ)}}class kJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{xmlns:"xmlns:pic"})}}class T9 extends o{constructor({mediaData:$,transform:U,outline:Y}){super("pic:pic");this.root.push(new kJ({xmlns:"http://schemas.openxmlformats.org/drawingml/2006/picture"})),this.root.push(new OJ),this.root.push(new NJ($)),this.root.push(new q$({element:"pic",transform:U,outline:Y}))}}var pX=($)=>new B0({name:"wpg:grpSpPr",children:[new K$($)]}),iX=()=>new B0({name:"wpg:cNvGrpSpPr"}),rX=($)=>new B0({name:"wpg:wgp",children:[iX(),pX($.transformation),...$.children]});class EJ extends o{constructor({mediaData:$,transform:U,outline:Y,solidFill:Z}){super("a:graphicData");if($.type==="wps"){this.root.push(new x1({uri:"http://schemas.microsoft.com/office/word/2010/wordprocessingShape"}));let J=xZ(R0(W0({},$.data),{transformation:U,outline:Y,solidFill:Z}));this.root.push(J)}else if($.type==="wpg"){this.root.push(new x1({uri:"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"}));let G=$.children.map((Q)=>{if(Q.type==="wps")return xZ(R0(W0({},Q.data),{transformation:Q.transformation,outline:Q.outline,solidFill:Q.solidFill}));else return new T9({mediaData:Q,transform:Q.transformation,outline:Q.outline})}),X=rX({children:G,transformation:U});this.root.push(X)}else{this.root.push(new x1({uri:"http://schemas.openxmlformats.org/drawingml/2006/picture"}));let G=new T9({mediaData:$,transform:U,outline:Y});this.root.push(G)}}}class SJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{a:"xmlns:a"})}}class X$ extends o{constructor({mediaData:$,transform:U,outline:Y,solidFill:Z}){super("a:graphic");Y0(this,"data"),this.root.push(new SJ({a:"http://schemas.openxmlformats.org/drawingml/2006/main"})),this.data=new EJ({mediaData:$,transform:U,outline:Y,solidFill:Z}),this.root.push(this.data)}}var G1={NONE:0,SQUARE:1,TIGHT:2,TOP_AND_BOTTOM:3},vJ={BOTH_SIDES:"bothSides",LEFT:"left",RIGHT:"right",LARGEST:"largest"},C9=()=>new B0({name:"wp:wrapNone"}),_J=($,U={top:0,bottom:0,left:0,right:0})=>new B0({name:"wp:wrapSquare",attributes:{wrapText:{key:"wrapText",value:$.side||vJ.BOTH_SIDES},distT:{key:"distT",value:U.top},distB:{key:"distB",value:U.bottom},distL:{key:"distL",value:U.left},distR:{key:"distR",value:U.right}}}),yJ=($={top:0,bottom:0})=>new B0({name:"wp:wrapTight",attributes:{distT:{key:"distT",value:$.top},distB:{key:"distB",value:$.bottom}}}),bJ=($={top:0,bottom:0})=>new B0({name:"wp:wrapTopAndBottom",attributes:{distT:{key:"distT",value:$.top},distB:{key:"distB",value:$.bottom}}});class V$ extends o{constructor({name:$,description:U,title:Y,id:Z}={name:"",description:"",title:""}){super("wp:docPr");Y0(this,"docPropertiesUniqueNumericId",nQ());let J={id:{key:"id",value:Z!=null?Z:this.docPropertiesUniqueNumericId()},name:{key:"name",value:$}};if(U!==null&&U!==void 0)J.description={key:"descr",value:U};if(Y!==null&&Y!==void 0)J.title={key:"title",value:Y};this.root.push(new n1(J))}prepForXml($){for(let U=$.stack.length-1;U>=0;U--){let Y=$.stack[U];if(!(Y instanceof _2))continue;this.root.push(PJ(Y.linkId,!0));break}return super.prepForXml($)}}var gJ=({top:$,right:U,bottom:Y,left:Z})=>new B0({name:"wp:effectExtent",attributes:{top:{key:"t",value:$},right:{key:"r",value:U},bottom:{key:"b",value:Y},left:{key:"l",value:Z}}}),xJ=({x:$,y:U})=>new B0({name:"wp:extent",attributes:{x:{key:"cx",value:$},y:{key:"cy",value:U}}});class fJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{xmlns:"xmlns:a",noChangeAspect:"noChangeAspect"})}}class hJ extends o{constructor(){super("a:graphicFrameLocks");this.root.push(new fJ({xmlns:"http://schemas.openxmlformats.org/drawingml/2006/main",noChangeAspect:1}))}}var uJ=()=>new B0({name:"wp:cNvGraphicFramePr",children:[new hJ]});class dJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{distT:"distT",distB:"distB",distL:"distL",distR:"distR",allowOverlap:"allowOverlap",behindDoc:"behindDoc",layoutInCell:"layoutInCell",locked:"locked",relativeHeight:"relativeHeight",simplePos:"simplePos"})}}class cJ extends o{constructor({mediaData:$,transform:U,drawingOptions:Y}){super("wp:anchor");let Z=W0({allowOverlap:!0,behindDocument:!1,lockAnchor:!1,layoutInCell:!0,verticalPosition:{},horizontalPosition:{}},Y.floating);if(this.root.push(new dJ({distT:Z.margins?Z.margins.top||0:0,distB:Z.margins?Z.margins.bottom||0:0,distL:Z.margins?Z.margins.left||0:0,distR:Z.margins?Z.margins.right||0:0,simplePos:"0",allowOverlap:Z.allowOverlap===!0?"1":"0",behindDoc:Z.behindDocument===!0?"1":"0",locked:Z.lockAnchor===!0?"1":"0",layoutInCell:Z.layoutInCell===!0?"1":"0",relativeHeight:Z.zIndex?Z.zIndex:U.emus.y})),this.root.push(UJ()),this.root.push(QJ(Z.horizontalPosition)),this.root.push(JJ(Z.verticalPosition)),this.root.push(xJ({x:U.emus.x,y:U.emus.y})),this.root.push(gJ({top:0,right:0,bottom:0,left:0})),Y.floating!==void 0&&Y.floating.wrap!==void 0)switch(Y.floating.wrap.type){case G1.SQUARE:this.root.push(_J(Y.floating.wrap,Y.floating.margins));break;case G1.TIGHT:this.root.push(yJ(Y.floating.margins));break;case G1.TOP_AND_BOTTOM:this.root.push(bJ(Y.floating.margins));break;case G1.NONE:default:this.root.push(C9())}else this.root.push(C9());this.root.push(new V$(Y.docProperties)),this.root.push(uJ()),this.root.push(new X$({mediaData:$,transform:U,outline:Y.outline,solidFill:Y.solidFill}))}}var sX=({mediaData:$,transform:U,docProperties:Y,outline:Z,solidFill:J})=>{var G,X,Q,B;return new B0({name:"wp:inline",attributes:{distanceTop:{key:"distT",value:0},distanceBottom:{key:"distB",value:0},distanceLeft:{key:"distL",value:0},distanceRight:{key:"distR",value:0}},children:[xJ({x:U.emus.x,y:U.emus.y}),gJ(Z?{top:((G=Z.width)!=null?G:9525)*2,right:((X=Z.width)!=null?X:9525)*2,bottom:((Q=Z.width)!=null?Q:9525)*2,left:((B=Z.width)!=null?B:9525)*2}:{top:0,right:0,bottom:0,left:0}),new V$(Y),uJ(),new X$({mediaData:$,transform:U,outline:Z,solidFill:J})]})};class D1 extends o{constructor($,U={}){super("w:drawing");if(!U.floating)this.root.push(sX({mediaData:$,transform:$.transformation,docProperties:U.docProperties,outline:U.outline,solidFill:U.solidFill}));else this.root.push(new cJ({mediaData:$,transform:$.transformation,drawingOptions:U}))}}var nX=($)=>{let Y=$.indexOf(";base64,"),Z=Y===-1?0:Y+8;return new Uint8Array(atob($.substring(Z)).split("").map((J)=>J.charCodeAt(0)))},mJ=($)=>typeof $==="string"?nX($):$,M9=($,U)=>({data:mJ($.data),fileName:U,transformation:{pixels:{x:Math.round($.transformation.width),y:Math.round($.transformation.height)},emus:{x:Math.round($.transformation.width*9525),y:Math.round($.transformation.height*9525)},flip:$.transformation.flip,rotation:$.transformation.rotation?$.transformation.rotation*60000:void 0}});class lJ extends C0{constructor($){super({});Y0(this,"imageData");let Y=`${A9($.data)}.${$.type}`;this.imageData=$.type==="svg"?R0(W0({type:$.type},M9($,Y)),{fallback:W0({type:$.fallback.type},M9(R0(W0({},$.fallback),{transformation:$.transformation}),`${A9($.fallback.data)}.${$.fallback.type}`))}):W0({type:$.type},M9($,Y));let Z=new D1(this.imageData,{floating:$.floating,docProperties:$.altText,outline:$.outline});this.root.push(Z)}prepForXml($){if($.file.Media.addImage(this.imageData.fileName,this.imageData),this.imageData.type==="svg")$.file.Media.addImage(this.imageData.fallback.fileName,this.imageData.fallback);return super.prepForXml($)}}var B$=($)=>{var U,Y,Z,J,G,X,Q,B;return{offset:{pixels:{x:Math.round((Y=(U=$.offset)==null?void 0:U.left)!=null?Y:0),y:Math.round((J=(Z=$.offset)==null?void 0:Z.top)!=null?J:0)},emus:{x:Math.round(((X=(G=$.offset)==null?void 0:G.left)!=null?X:0)*9525),y:Math.round(((B=(Q=$.offset)==null?void 0:Q.top)!=null?B:0)*9525)}},pixels:{x:Math.round($.width),y:Math.round($.height)},emus:{x:Math.round($.width*9525),y:Math.round($.height*9525)},flip:$.flip,rotation:$.rotation?$.rotation*60000:void 0}};class aJ extends C0{constructor($){super({});Y0(this,"wpsShapeData"),this.wpsShapeData={type:$.type,transformation:B$($.transformation),data:W0({},$)};let U=new D1(this.wpsShapeData,{floating:$.floating,docProperties:$.altText,outline:$.outline,solidFill:$.solidFill});this.root.push(U)}}class pJ extends C0{constructor($){super({});Y0(this,"wpgGroupData"),Y0(this,"mediaDatas"),this.wpgGroupData={type:$.type,transformation:B$($.transformation),children:$.children};let U=new D1(this.wpgGroupData,{floating:$.floating,docProperties:$.altText});this.mediaDatas=$.children.filter((Y)=>Y.type!=="wps").map((Y)=>Y),this.root.push(U)}prepForXml($){return this.mediaDatas.forEach((U)=>{if($.file.Media.addImage(U.fileName,U),U.type==="svg")$.file.Media.addImage(U.fallback.fileName,U.fallback)}),super.prepForXml($)}}class iJ extends o{constructor($){super("w:instrText");this.root.push(new x0({space:g0.PRESERVE})),this.root.push(`SEQ ${$}`)}}class rJ extends C0{constructor($){super({});this.root.push($2(!0)),this.root.push(new iJ($)),this.root.push(I2()),this.root.push(U2())}}class sJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{instr:"w:instr"})}}class J8 extends o{constructor($,U){super("w:fldSimple");if(this.root.push(new sJ({instr:$})),U!==void 0)this.root.push(new p2(U))}}class nJ extends J8{constructor($){super(` MERGEFIELD ${$} `,`«${$}»`)}}class oJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{xmlns:"xmlns"})}}var tJ={EXTERNAL:"External"},oX=($,U,Y,Z)=>new B0({name:"Relationship",attributes:{id:{key:"Id",value:$},type:{key:"Type",value:U},target:{key:"Target",value:Y},targetMode:{key:"TargetMode",value:Z}}});class W2 extends o{constructor(){super("Relationships");this.root.push(new oJ({xmlns:"http://schemas.openxmlformats.org/package/2006/relationships"}))}addRelationship($,U,Y,Z){this.root.push(oX(`rId${$}`,U,Y,Z))}get RelationshipCount(){return this.root.length-1}}class eJ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"w:id",initials:"w:initials",author:"w:author",date:"w:date"})}}class G8 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"w:id"})}}class $G extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{"xmlns:cx":"xmlns:cx","xmlns:cx1":"xmlns:cx1","xmlns:cx2":"xmlns:cx2","xmlns:cx3":"xmlns:cx3","xmlns:cx4":"xmlns:cx4","xmlns:cx5":"xmlns:cx5","xmlns:cx6":"xmlns:cx6","xmlns:cx7":"xmlns:cx7","xmlns:cx8":"xmlns:cx8","xmlns:mc":"xmlns:mc","xmlns:aink":"xmlns:aink","xmlns:am3d":"xmlns:am3d","xmlns:o":"xmlns:o","xmlns:r":"xmlns:r","xmlns:m":"xmlns:m","xmlns:v":"xmlns:v","xmlns:wp14":"xmlns:wp14","xmlns:wp":"xmlns:wp","xmlns:w10":"xmlns:w10","xmlns:w":"xmlns:w","xmlns:w14":"xmlns:w14","xmlns:w15":"xmlns:w15","xmlns:w16cex":"xmlns:w16cex","xmlns:w16cid":"xmlns:w16cid","xmlns:w16":"xmlns:w16","xmlns:w16sdtdh":"xmlns:w16sdtdh","xmlns:w16se":"xmlns:w16se","xmlns:wpg":"xmlns:wpg","xmlns:wpi":"xmlns:wpi","xmlns:wne":"xmlns:wne","xmlns:wps":"xmlns:wps"})}}class UG extends o{constructor($){super("w:commentRangeStart");this.root.push(new G8({id:$}))}}class YG extends o{constructor($){super("w:commentRangeEnd");this.root.push(new G8({id:$}))}}class ZG extends o{constructor($){super("w:commentReference");this.root.push(new G8({id:$}))}}class L$ extends o{constructor({id:$,initials:U,author:Y,date:Z=new Date,children:J}){super("w:comment");this.root.push(new eJ({id:$,initials:U,author:Y,date:Z.toISOString()}));for(let G of J)this.root.push(G)}}class M$ extends o{constructor({children:$}){super("w:comments");Y0(this,"relationships"),this.root.push(new $G({"xmlns:cx":"http://schemas.microsoft.com/office/drawing/2014/chartex","xmlns:cx1":"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex","xmlns:cx2":"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex","xmlns:cx3":"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex","xmlns:cx4":"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex","xmlns:cx5":"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex","xmlns:cx6":"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex","xmlns:cx7":"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex","xmlns:cx8":"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex","xmlns:mc":"http://schemas.openxmlformats.org/markup-compatibility/2006","xmlns:aink":"http://schemas.microsoft.com/office/drawing/2016/ink","xmlns:am3d":"http://schemas.microsoft.com/office/drawing/2017/model3d","xmlns:o":"urn:schemas-microsoft-com:office:office","xmlns:r":"http://schemas.openxmlformats.org/officeDocument/2006/relationships","xmlns:m":"http://schemas.openxmlformats.org/officeDocument/2006/math","xmlns:v":"urn:schemas-microsoft-com:vml","xmlns:wp14":"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing","xmlns:wp":"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing","xmlns:w10":"urn:schemas-microsoft-com:office:word","xmlns:w":"http://schemas.openxmlformats.org/wordprocessingml/2006/main","xmlns:w14":"http://schemas.microsoft.com/office/word/2010/wordml","xmlns:w15":"http://schemas.microsoft.com/office/word/2012/wordml","xmlns:w16cex":"http://schemas.microsoft.com/office/word/2018/wordml/cex","xmlns:w16cid":"http://schemas.microsoft.com/office/word/2016/wordml/cid","xmlns:w16":"http://schemas.microsoft.com/office/word/2018/wordml","xmlns:w16sdtdh":"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash","xmlns:w16se":"http://schemas.microsoft.com/office/word/2015/wordml/symex","xmlns:wpg":"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup","xmlns:wpi":"http://schemas.microsoft.com/office/word/2010/wordprocessingInk","xmlns:wne":"http://schemas.microsoft.com/office/word/2006/wordml","xmlns:wps":"http://schemas.microsoft.com/office/word/2010/wordprocessingShape"}));for(let U of $)this.root.push(new L$(U));this.relationships=new W2}get Relationships(){return this.relationships}}class QG extends k0{constructor(){super("w:noBreakHyphen")}}class JG extends k0{constructor(){super("w:softHyphen")}}class GG extends k0{constructor(){super("w:dayShort")}}class KG extends k0{constructor(){super("w:monthShort")}}class qG extends k0{constructor(){super("w:yearShort")}}class XG extends k0{constructor(){super("w:dayLong")}}class VG extends k0{constructor(){super("w:monthLong")}}class BG extends k0{constructor(){super("w:yearLong")}}class LG extends k0{constructor(){super("w:annotationRef")}}class MG extends k0{constructor(){super("w:footnoteRef")}}class I$ extends k0{constructor(){super("w:endnoteRef")}}class IG extends k0{constructor(){super("w:separator")}}class wG extends k0{constructor(){super("w:continuationSeparator")}}class WG extends k0{constructor(){super("w:pgNum")}}class HG extends k0{constructor(){super("w:cr")}}class w$ extends k0{constructor(){super("w:tab")}}class jG extends k0{constructor(){super("w:lastRenderedPageBreak")}}var tX={LEFT:"left",CENTER:"center",RIGHT:"right"},eX={MARGIN:"margin",INDENT:"indent"},$V={NONE:"none",DOT:"dot",HYPHEN:"hyphen",UNDERSCORE:"underscore",MIDDLE_DOT:"middleDot"};class zG extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{alignment:"w:alignment",relativeTo:"w:relativeTo",leader:"w:leader"})}}class FG extends o{constructor($){super("w:ptab");this.root.push(new zG({alignment:$.alignment,relativeTo:$.relativeTo,leader:$.leader}))}}var NG={COLUMN:"column",PAGE:"page"};class W$ extends o{constructor($){super("w:br");this.root.push(new O0({type:$}))}}class RG extends C0{constructor(){super({});this.root.push(new W$(NG.PAGE))}}class DG extends C0{constructor(){super({});this.root.push(new W$(NG.COLUMN))}}class H$ extends o{constructor(){super("w:pageBreakBefore")}}var v2={AT_LEAST:"atLeast",EXACTLY:"exactly",EXACT:"exact",AUTO:"auto"},AG=({after:$,before:U,line:Y,lineRule:Z,beforeAutoSpacing:J,afterAutoSpacing:G})=>new B0({name:"w:spacing",attributes:{after:{key:"w:after",value:$},before:{key:"w:before",value:U},line:{key:"w:line",value:Y},lineRule:{key:"w:lineRule",value:Z},beforeAutoSpacing:{key:"w:beforeAutospacing",value:J},afterAutoSpacing:{key:"w:afterAutospacing",value:G}}}),UV={HEADING_1:"Heading1",HEADING_2:"Heading2",HEADING_3:"Heading3",HEADING_4:"Heading4",HEADING_5:"Heading5",HEADING_6:"Heading6",TITLE:"Title"},K1=($)=>new B0({name:"w:pStyle",attributes:{val:{key:"w:val",value:$}}}),O9={LEFT:"left",RIGHT:"right",CENTER:"center",BAR:"bar",CLEAR:"clear",DECIMAL:"decimal",END:"end",NUM:"num",START:"start"},YV={DOT:"dot",HYPHEN:"hyphen",MIDDLE_DOT:"middleDot",NONE:"none",UNDERSCORE:"underscore"},ZV={MAX:9026},PG=({type:$,position:U,leader:Y})=>new B0({name:"w:tab",attributes:{val:{key:"w:val",value:$},pos:{key:"w:pos",value:U},leader:{key:"w:leader",value:Y}}}),TG=($)=>new B0({name:"w:tabs",children:$.map((U)=>PG(U))});class V1 extends o{constructor($,U){super("w:numPr");this.root.push(new CG(U)),this.root.push(new OG($))}}class CG extends o{constructor($){super("w:ilvl");if($>9)throw Error("Level cannot be greater than 9. Read more here: https://answers.microsoft.com/en-us/msoffice/forum/all/does-word-support-more-than-9-list-levels/d130fdcd-1781-446d-8c84-c6c79124e4d7");this.root.push(new O0({val:$}))}}class OG extends o{constructor($){super("w:numId");this.root.push(new O0({val:typeof $==="string"?`{${$}}`:$}))}}class r2 extends o{constructor(){super(...arguments);Y0(this,"fileChild",Symbol())}}class kG extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"r:id",history:"w:history",anchor:"w:anchor"})}}var QV={INTERNAL:"INTERNAL",EXTERNAL:"EXTERNAL"};class _2 extends o{constructor($,U,Y){super("w:hyperlink");Y0(this,"linkId"),this.linkId=U;let Z={history:1,anchor:Y?Y:void 0,id:!Y?`rId${this.linkId}`:void 0},J=new kG(Z);this.root.push(J),$.forEach((G)=>{this.root.push(G)})}}class j$ extends _2{constructor($){super($.children,R1(),$.anchor)}}class K8 extends o{constructor($){super("w:externalHyperlink");this.options=$}}class EG extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"w:id",name:"w:name"})}}class SG extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"w:id"})}}class z${constructor($){Y0(this,"bookmarkUniqueNumericId",oQ()),Y0(this,"start"),Y0(this,"children"),Y0(this,"end");let U=this.bookmarkUniqueNumericId();this.start=new F$($.id,U),this.children=$.children,this.end=new N$(U)}}class F$ extends o{constructor($,U){super("w:bookmarkStart");let Y=new EG({name:$,id:U});this.root.push(Y)}}class N$ extends o{constructor($){super("w:bookmarkEnd");let U=new SG({id:$});this.root.push(U)}}var vG=(($)=>{return $.NONE="none",$.RELATIVE="relative",$.NO_CONTEXT="no_context",$.FULL_CONTEXT="full_context",$})(vG||{}),JV={["relative"]:"\\r",["no_context"]:"\\n",["full_context"]:"\\w",["none"]:void 0};class _G extends J8{constructor($,U,Y={}){let{hyperlink:Z=!0,referenceFormat:J="full_context"}=Y,G=`REF ${$}`,X=[...Z?["\\h"]:[],...[JV[J]].filter((B)=>!!B)],Q=`${G} ${X.join(" ")}`;super(Q,U)}}var yG=($)=>new B0({name:"w:outlineLvl",attributes:{val:{key:"w:val",value:$}}});class bG extends o{constructor($,U={}){super("w:instrText");this.root.push(new x0({space:g0.PRESERVE}));let Y=`PAGEREF ${$}`;if(U.hyperlink)Y=`${Y} \\h`;if(U.useRelativePosition)Y=`${Y} \\p`;this.root.push(Y)}}class gG extends C0{constructor($,U={}){super({children:[$2(!0),new bG($,U),U2()]})}}var GV={ANSI:"00",DEFAULT:"01",SYMBOL:"02",MAC:"4D",JIS:"80",HANGUL:"81",JOHAB:"82",GB_2312:"86",CHINESEBIG5:"88",GREEK:"A1",TURKISH:"A2",VIETNAMESE:"A3",HEBREW:"B1",ARABIC:"B2",BALTIC:"BA",RUSSIAN:"CC",THAI:"DE",EASTEUROPE:"EE",OEM:"FF"},_1=({id:$,fontKey:U,subsetted:Y},Z)=>new B0({name:Z,attributes:W0({id:{key:"r:id",value:$}},U?{fontKey:{key:"w:fontKey",value:`{${U}}`}}:{}),children:[...Y?[new X0("w:subsetted",Y)]:[]]}),KV=({name:$,altName:U,panose1:Y,charset:Z,family:J,notTrueType:G,pitch:X,sig:Q,embedRegular:B,embedBold:F,embedItalic:z,embedBoldItalic:W})=>new B0({name:"w:font",attributes:{name:{key:"w:name",value:$}},children:[...U?[u2("w:altName",U)]:[],...Y?[u2("w:panose1",Y)]:[],...Z?[u2("w:charset",Z)]:[],u2("w:family",J),...G?[new X0("w:notTrueType",G)]:[],u2("w:pitch",X),...Q?[new B0({name:"w:sig",attributes:{usb0:{key:"w:usb0",value:Q.usb0},usb1:{key:"w:usb1",value:Q.usb1},usb2:{key:"w:usb2",value:Q.usb2},usb3:{key:"w:usb3",value:Q.usb3},csb0:{key:"w:csb0",value:Q.csb0},csb1:{key:"w:csb1",value:Q.csb1}}})]:[],...B?[_1(B,"w:embedRegular")]:[],...F?[_1(F,"w:embedBold")]:[],...z?[_1(z,"w:embedItalic")]:[],...W?[_1(W,"w:embedBoldItalic")]:[]]}),qV=({name:$,index:U,fontKey:Y,characterSet:Z})=>KV({name:$,sig:{usb0:"E0002AFF",usb1:"C000247B",usb2:"00000009",usb3:"00000000",csb0:"000001FF",csb1:"00000000"},charset:Z,family:"auto",pitch:"variable",embedRegular:{fontKey:Y,id:`rId${U}`}}),XV=($)=>new B0({name:"w:fonts",attributes:{mc:{key:"xmlns:mc",value:"http://schemas.openxmlformats.org/markup-compatibility/2006"},r:{key:"xmlns:r",value:"http://schemas.openxmlformats.org/officeDocument/2006/relationships"},w:{key:"xmlns:w",value:"http://schemas.openxmlformats.org/wordprocessingml/2006/main"},w14:{key:"xmlns:w14",value:"http://schemas.microsoft.com/office/word/2010/wordml"},w15:{key:"xmlns:w15",value:"http://schemas.microsoft.com/office/word/2012/wordml"},w16cex:{key:"xmlns:w16cex",value:"http://schemas.microsoft.com/office/word/2018/wordml/cex"},w16cid:{key:"xmlns:w16cid",value:"http://schemas.microsoft.com/office/word/2016/wordml/cid"},w16:{key:"xmlns:w16",value:"http://schemas.microsoft.com/office/word/2018/wordml"},w16sdtdh:{key:"xmlns:w16sdtdh",value:"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash"},w16se:{key:"xmlns:w16se",value:"http://schemas.microsoft.com/office/word/2015/wordml/symex"},Ignorable:{key:"mc:Ignorable",value:"w14 w15 w16se w16cid w16 w16cex w16sdtdh"}},children:$.map((U,Y)=>qV({name:U.name,index:Y+1,fontKey:U.fontKey,characterSet:U.characterSet}))});class R${constructor($){Y0(this,"fontTable"),Y0(this,"relationships"),Y0(this,"fontOptionsWithKey",[]),this.options=$,this.fontOptionsWithKey=$.map((U)=>R0(W0({},U),{fontKey:tQ()})),this.fontTable=XV(this.fontOptionsWithKey),this.relationships=new W2;for(let U=0;U<$.length;U++)this.relationships.addRelationship(U+1,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/font",`fonts/${$[U].name}.odttf`)}get View(){return this.fontTable}get Relationships(){return this.relationships}}var VV=()=>new B0({name:"w:wordWrap",attributes:{val:{key:"w:val",value:0}}}),BV={NONE:"none",DROP:"drop",MARGIN:"margin"},LV={MARGIN:"margin",PAGE:"page",TEXT:"text"},MV={AROUND:"around",AUTO:"auto",NONE:"none",NOT_BESIDE:"notBeside",THROUGH:"through",TIGHT:"tight"},xG=($)=>{var U,Y;return new B0({name:"w:framePr",attributes:{anchorLock:{key:"w:anchorLock",value:$.anchorLock},dropCap:{key:"w:dropCap",value:$.dropCap},width:{key:"w:w",value:$.width},height:{key:"w:h",value:$.height},x:{key:"w:x",value:$.position?$.position.x:void 0},y:{key:"w:y",value:$.position?$.position.y:void 0},anchorHorizontal:{key:"w:hAnchor",value:$.anchor.horizontal},anchorVertical:{key:"w:vAnchor",value:$.anchor.vertical},spaceHorizontal:{key:"w:hSpace",value:(U=$.space)==null?void 0:U.horizontal},spaceVertical:{key:"w:vSpace",value:(Y=$.space)==null?void 0:Y.vertical},rule:{key:"w:hRule",value:$.rule},alignmentX:{key:"w:xAlign",value:$.alignment?$.alignment.x:void 0},alignmentY:{key:"w:yAlign",value:$.alignment?$.alignment.y:void 0},lines:{key:"w:lines",value:$.lines},wrap:{key:"w:wrap",value:$.wrap}}})};class Z2 extends Q2{constructor($){var U,Y;super("w:pPr",$==null?void 0:$.includeIfEmpty);if(Y0(this,"numberingReferences",[]),!$)return this;if($.heading)this.push(K1($.heading));if($.bullet)this.push(K1("ListParagraph"));if($.numbering){if(!$.style&&!$.heading){if(!$.numbering.custom)this.push(K1("ListParagraph"))}}if($.style)this.push(K1($.style));if($.keepNext!==void 0)this.push(new X0("w:keepNext",$.keepNext));if($.keepLines!==void 0)this.push(new X0("w:keepLines",$.keepLines));if($.pageBreakBefore)this.push(new H$);if($.frame)this.push(xG($.frame));if($.widowControl!==void 0)this.push(new X0("w:widowControl",$.widowControl));if($.bullet)this.push(new V1(1,$.bullet.level));if($.numbering)this.numberingReferences.push({reference:$.numbering.reference,instance:(U=$.numbering.instance)!=null?U:0}),this.push(new V1(`${$.numbering.reference}-${(Y=$.numbering.instance)!=null?Y:0}`,$.numbering.level));else if($.numbering===!1)this.push(new V1(0,0));if($.border)this.push(new o9($.border));if($.thematicBreak)this.push(new t9);if($.shading)this.push(j1($.shading));if($.wordWrap)this.push(VV());if($.overflowPunctuation)this.push(new X0("w:overflowPunct",$.overflowPunctuation));let Z=[...$.rightTabStop!==void 0?[{type:O9.RIGHT,position:$.rightTabStop}]:[],...$.tabStops?$.tabStops:[],...$.leftTabStop!==void 0?[{type:O9.LEFT,position:$.leftTabStop}]:[]];if(Z.length>0)this.push(TG(Z));if($.bidirectional!==void 0)this.push(new X0("w:bidi",$.bidirectional));if($.spacing)this.push(AG($.spacing));if($.indent)this.push(EQ($.indent));if($.contextualSpacing!==void 0)this.push(new X0("w:contextualSpacing",$.contextualSpacing));if($.alignment)this.push(n9($.alignment));if($.outlineLevel!==void 0)this.push(yG($.outlineLevel));if($.suppressLineNumbers!==void 0)this.push(new X0("w:suppressLineNumbers",$.suppressLineNumbers));if($.autoSpaceEastAsianText!==void 0)this.push(new X0("w:autoSpaceDN",$.autoSpaceEastAsianText));if($.run)this.push(new Q$($.run));if($.revision)this.push(new D$($.revision))}push($){this.root.push($)}prepForXml($){if(!($.viewWrapper instanceof R$))for(let U of this.numberingReferences)$.file.Numbering.createConcreteNumberingInstance(U.reference,U.instance);return super.prepForXml($)}}class D$ extends o{constructor($){super("w:pPrChange");this.root.push(new _0({id:$.id,author:$.author,date:$.date})),this.root.push(new Z2(R0(W0({},$),{includeIfEmpty:!0})))}}class h0 extends r2{constructor($){super("w:p");if(Y0(this,"properties"),typeof $==="string")return this.properties=new Z2({}),this.root.push(this.properties),this.root.push(new p2($)),this;if(this.properties=new Z2($),this.root.push(this.properties),$.text)this.root.push(new p2($.text));if($.children)for(let U of $.children){if(U instanceof z$){this.root.push(U.start);for(let Y of U.children)this.root.push(Y);this.root.push(U.end);continue}this.root.push(U)}}prepForXml($){for(let U of this.root)if(U instanceof K8){let Y=this.root.indexOf(U),Z=new _2(U.options.children,R1());$.viewWrapper.Relationships.addRelationship(Z.linkId,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",U.options.link,tJ.EXTERNAL),this.root[Y]=Z}return super.prepForXml($)}addRunToFront($){return this.root.splice(1,0,$),this}}var IV=class extends o{constructor(U){super("m:oMath");for(let Y of U.children)this.root.push(Y)}};class fG extends o{constructor($){super("m:t");this.root.push($)}}class hG extends o{constructor($){super("m:r");this.root.push(new fG($))}}class A$ extends o{constructor($){super("m:den");for(let U of $)this.root.push(U)}}class P$ extends o{constructor($){super("m:num");for(let U of $)this.root.push(U)}}class uG extends o{constructor($){super("m:f");this.root.push(new P$($.numerator)),this.root.push(new A$($.denominator))}}var dG=({accent:$})=>new B0({name:"m:chr",attributes:{accent:{key:"m:val",value:$}}}),y0=({children:$})=>new B0({name:"m:e",children:$}),cG=({value:$})=>new B0({name:"m:limLoc",attributes:{value:{key:"m:val",value:$||"undOvr"}}}),wV=()=>new B0({name:"m:subHide",attributes:{hide:{key:"m:val",value:1}}}),WV=()=>new B0({name:"m:supHide",attributes:{hide:{key:"m:val",value:1}}}),T$=({accent:$,hasSuperScript:U,hasSubScript:Y,limitLocationVal:Z})=>new B0({name:"m:naryPr",children:[...$?[dG({accent:$})]:[],cG({value:Z}),...!U?[WV()]:[],...!Y?[wV()]:[]]}),s2=({children:$})=>new B0({name:"m:sub",children:$}),n2=({children:$})=>new B0({name:"m:sup",children:$});class mG extends o{constructor($){super("m:nary");if(this.root.push(T$({accent:"∑",hasSuperScript:!!$.superScript,hasSubScript:!!$.subScript})),$.subScript)this.root.push(s2({children:$.subScript}));if($.superScript)this.root.push(n2({children:$.superScript}));this.root.push(y0({children:$.children}))}}class lG extends o{constructor($){super("m:nary");if(this.root.push(T$({accent:"",hasSuperScript:!!$.superScript,hasSubScript:!!$.subScript,limitLocationVal:"subSup"})),$.subScript)this.root.push(s2({children:$.subScript}));if($.superScript)this.root.push(n2({children:$.superScript}));this.root.push(y0({children:$.children}))}}class q8 extends o{constructor($){super("m:lim");for(let U of $)this.root.push(U)}}class aG extends o{constructor($){super("m:limUpp");this.root.push(y0({children:$.children})),this.root.push(new q8($.limit))}}class pG extends o{constructor($){super("m:limLow");this.root.push(y0({children:$.children})),this.root.push(new q8($.limit))}}var iG=()=>new B0({name:"m:sSupPr"});class rG extends o{constructor($){super("m:sSup");this.root.push(iG()),this.root.push(y0({children:$.children})),this.root.push(n2({children:$.superScript}))}}var sG=()=>new B0({name:"m:sSubPr"});class nG extends o{constructor($){super("m:sSub");this.root.push(sG()),this.root.push(y0({children:$.children})),this.root.push(s2({children:$.subScript}))}}var oG=()=>new B0({name:"m:sSubSupPr"});class tG extends o{constructor($){super("m:sSubSup");this.root.push(oG()),this.root.push(y0({children:$.children})),this.root.push(s2({children:$.subScript})),this.root.push(n2({children:$.superScript}))}}var eG=()=>new B0({name:"m:sPrePr"});class $K extends B0{constructor({children:$,subScript:U,superScript:Y}){super({name:"m:sPre",children:[eG(),y0({children:$}),s2({children:U}),n2({children:Y})]})}}var HV="";class C$ extends o{constructor($){super("m:deg");if($)for(let U of $)this.root.push(U)}}class UK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{hide:"m:val"})}}class YK extends o{constructor(){super("m:degHide");this.root.push(new UK({hide:1}))}}class O$ extends o{constructor($){super("m:radPr");if(!$)this.root.push(new YK)}}class ZK extends o{constructor($){super("m:rad");this.root.push(new O$(!!$.degree)),this.root.push(new C$($.degree)),this.root.push(y0({children:$.children}))}}class k$ extends o{constructor($){super("m:fName");for(let U of $)this.root.push(U)}}class E$ extends o{constructor(){super("m:funcPr")}}class QK extends o{constructor($){super("m:func");this.root.push(new E$),this.root.push(new k$($.name)),this.root.push(y0({children:$.children}))}}var jV=({character:$})=>new B0({name:"m:begChr",attributes:{character:{key:"m:val",value:$}}}),zV=({character:$})=>new B0({name:"m:endChr",attributes:{character:{key:"m:val",value:$}}}),X8=({characters:$})=>new B0({name:"m:dPr",children:$?[jV({character:$.beginningCharacter}),zV({character:$.endingCharacter})]:[]});class JK extends o{constructor($){super("m:d");this.root.push(X8({})),this.root.push(y0({children:$.children}))}}class GK extends o{constructor($){super("m:d");this.root.push(X8({characters:{beginningCharacter:"[",endingCharacter:"]"}})),this.root.push(y0({children:$.children}))}}class KK extends o{constructor($){super("m:d");this.root.push(X8({characters:{beginningCharacter:"{",endingCharacter:"}"}})),this.root.push(y0({children:$.children}))}}class qK extends o{constructor($){super("m:d");this.root.push(X8({characters:{beginningCharacter:"〈",endingCharacter:"〉"}})),this.root.push(y0({children:$.children}))}}var FV=($)=>new B0({name:"w:gridCol",attributes:$!==void 0?{width:{key:"w:w",value:T0($)}}:void 0});class S$ extends o{constructor($,U){super("w:tblGrid");for(let Y of $)this.root.push(FV(Y));if(U)this.root.push(new VK(U))}}class XK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"w:id"})}}class VK extends o{constructor($){super("w:tblGridChange");this.root.push(new XK({id:$.id})),this.root.push(new S$($.columnWidths))}}class BK extends o{constructor($){super("w:ins");this.root.push(new _0({id:$.id,author:$.author,date:$.date})),this.addChildElement(new p2($))}}class LK extends o{constructor(){super("w:delInstrText");this.root.push(new x0({space:g0.PRESERVE})),this.root.push("PAGE")}}class MK extends o{constructor(){super("w:delInstrText");this.root.push(new x0({space:g0.PRESERVE})),this.root.push("NUMPAGES")}}class IK extends o{constructor(){super("w:delInstrText");this.root.push(new x0({space:g0.PRESERVE})),this.root.push("SECTIONPAGES")}}class k9 extends o{constructor($){super("w:delText");this.root.push(new x0({space:g0.PRESERVE})),this.root.push($)}}class wK extends o{constructor($){super("w:del");Y0(this,"deletedTextRunWrapper"),this.root.push(new _0({id:$.id,author:$.author,date:$.date})),this.deletedTextRunWrapper=new WK($),this.addChildElement(this.deletedTextRunWrapper)}}class WK extends o{constructor($){super("w:r");if(this.root.push(new J2($)),$.children)for(let U of $.children){if(typeof U==="string"){switch(U){case N2.CURRENT:this.root.push($2()),this.root.push(new LK),this.root.push(I2()),this.root.push(U2());break;case N2.TOTAL_PAGES:this.root.push($2()),this.root.push(new MK),this.root.push(I2()),this.root.push(U2());break;case N2.TOTAL_PAGES_IN_SECTION:this.root.push($2()),this.root.push(new IK),this.root.push(I2()),this.root.push(U2());break;default:this.root.push(new k9(U));break}continue}this.root.push(U)}else if($.text)this.root.push(new k9($.text));if($.break)for(let U=0;U<$.break;U++)this.root.splice(1,0,SQ())}}class v$ extends o{constructor($){super("w:ins");this.root.push(new _0({id:$.id,author:$.author,date:$.date}))}}class _$ extends o{constructor($){super("w:del");this.root.push(new _0({id:$.id,author:$.author,date:$.date}))}}class y$ extends o{constructor($){super("w:cellIns");this.root.push(new _0({id:$.id,author:$.author,date:$.date}))}}class b$ extends o{constructor($){super("w:cellDel");this.root.push(new _0({id:$.id,author:$.author,date:$.date}))}}var NV={CONTINUE:"cont",RESTART:"rest"};class g$ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"w:id",author:"w:author",date:"w:date",verticalMerge:"w:vMerge",verticalMergeOriginal:"w:vMergeOrig"})}}class x$ extends o{constructor($){super("w:cellMerge");this.root.push(new g$($))}}var HK={TOP:"top",CENTER:"center",BOTTOM:"bottom"},jK=R0(W0({},HK),{BOTH:"both"}),RV=jK,f$=($)=>new B0({name:"w:vAlign",attributes:{verticalAlign:{key:"w:val",value:$}}}),zK=({marginUnitType:$=l1.DXA,top:U,left:Y,bottom:Z,right:J})=>[{name:"w:top",size:U},{name:"w:left",size:Y},{name:"w:bottom",size:Z},{name:"w:right",size:J}].filter((G)=>G.size!==void 0).map(({name:G,size:X})=>M1(G,{type:$,size:X})),DV=($)=>{let U=zK($);if(U.length===0)return;return new B0({name:"w:tblCellMar",children:U})},AV=($)=>{let U=zK($);if(U.length===0)return;return new B0({name:"w:tcMar",children:U})},l1={AUTO:"auto",DXA:"dxa",NIL:"nil",PERCENTAGE:"pct"},M1=($,{type:U=l1.AUTO,size:Y})=>{let Z=Y;if(U===l1.PERCENTAGE&&typeof Y==="number")Z=`${Y}%`;return new B0({name:$,attributes:{type:{key:"w:type",value:U},size:{key:"w:w",value:s9(Z)}}})};class h$ extends Q2{constructor($){super("w:tcBorders");if($.top)this.root.push(N0("w:top",$.top));if($.start)this.root.push(N0("w:start",$.start));if($.left)this.root.push(N0("w:left",$.left));if($.bottom)this.root.push(N0("w:bottom",$.bottom));if($.end)this.root.push(N0("w:end",$.end));if($.right)this.root.push(N0("w:right",$.right))}}class FK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{val:"w:val"})}}class u$ extends o{constructor($){super("w:gridSpan");this.root.push(new FK({val:S0($)}))}}var d$={CONTINUE:"continue",RESTART:"restart"};class NK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{val:"w:val"})}}class a1 extends o{constructor($){super("w:vMerge");this.root.push(new NK({val:$}))}}var PV={BOTTOM_TO_TOP_LEFT_TO_RIGHT:"btLr",LEFT_TO_RIGHT_TOP_TO_BOTTOM:"lrTb",TOP_TO_BOTTOM_RIGHT_TO_LEFT:"tbRl"};class RK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{val:"w:val"})}}class c$ extends o{constructor($){super("w:textDirection");this.root.push(new RK({val:$}))}}class m$ extends Q2{constructor($){super("w:tcPr",$.includeIfEmpty);if($.width)this.root.push(M1("w:tcW",$.width));if($.columnSpan)this.root.push(new u$($.columnSpan));if($.verticalMerge)this.root.push(new a1($.verticalMerge));else if($.rowSpan&&$.rowSpan>1)this.root.push(new a1(d$.RESTART));if($.borders)this.root.push(new h$($.borders));if($.shading)this.root.push(j1($.shading));if($.margins){let U=AV($.margins);if(U)this.root.push(U)}if($.textDirection)this.root.push(new c$($.textDirection));if($.verticalAlign)this.root.push(f$($.verticalAlign));if($.insertion)this.root.push(new y$($.insertion));if($.deletion)this.root.push(new b$($.deletion));if($.revision)this.root.push(new DK($.revision));if($.cellMerge)this.root.push(new x$($.cellMerge))}}class DK extends o{constructor($){super("w:tcPrChange");this.root.push(new _0({id:$.id,author:$.author,date:$.date})),this.root.push(new m$(R0(W0({},$),{includeIfEmpty:!0})))}}class V8 extends o{constructor($){super("w:tc");this.options=$,this.root.push(new m$($));for(let U of $.children)this.root.push(U)}prepForXml($){if(!(this.root[this.root.length-1]instanceof h0))this.root.push(new h0({}));return super.prepForXml($)}}var x2={style:Q8.NONE,size:0,color:"auto"},f2={style:Q8.SINGLE,size:4,color:"auto"};class B8 extends o{constructor($){var U,Y,Z,J,G,X;super("w:tblBorders");this.root.push(N0("w:top",(U=$.top)!=null?U:f2)),this.root.push(N0("w:left",(Y=$.left)!=null?Y:f2)),this.root.push(N0("w:bottom",(Z=$.bottom)!=null?Z:f2)),this.root.push(N0("w:right",(J=$.right)!=null?J:f2)),this.root.push(N0("w:insideH",(G=$.insideHorizontal)!=null?G:f2)),this.root.push(N0("w:insideV",(X=$.insideVertical)!=null?X:f2))}}Y0(B8,"NONE",{top:x2,bottom:x2,left:x2,right:x2,insideHorizontal:x2,insideVertical:x2});var TV={MARGIN:"margin",PAGE:"page",TEXT:"text"},CV={CENTER:"center",INSIDE:"inside",LEFT:"left",OUTSIDE:"outside",RIGHT:"right"},OV={CENTER:"center",INSIDE:"inside",BOTTOM:"bottom",OUTSIDE:"outside",INLINE:"inline",TOP:"top"},kV={NEVER:"never",OVERLAP:"overlap"},EV=($)=>new B0({name:"w:tblOverlap",attributes:{val:{key:"w:val",value:$}}}),AK=({horizontalAnchor:$,verticalAnchor:U,absoluteHorizontalPosition:Y,relativeHorizontalPosition:Z,absoluteVerticalPosition:J,relativeVerticalPosition:G,bottomFromText:X,topFromText:Q,leftFromText:B,rightFromText:F,overlap:z})=>new B0({name:"w:tblpPr",attributes:{leftFromText:{key:"w:leftFromText",value:B===void 0?void 0:T0(B)},rightFromText:{key:"w:rightFromText",value:F===void 0?void 0:T0(F)},topFromText:{key:"w:topFromText",value:Q===void 0?void 0:T0(Q)},bottomFromText:{key:"w:bottomFromText",value:X===void 0?void 0:T0(X)},absoluteHorizontalPosition:{key:"w:tblpX",value:Y===void 0?void 0:e0(Y)},absoluteVerticalPosition:{key:"w:tblpY",value:J===void 0?void 0:e0(J)},horizontalAnchor:{key:"w:horzAnchor",value:$},relativeHorizontalPosition:{key:"w:tblpXSpec",value:Z},relativeVerticalPosition:{key:"w:tblpYSpec",value:G},verticalAnchor:{key:"w:vertAnchor",value:U}},children:z?[EV(z)]:void 0}),SV={AUTOFIT:"autofit",FIXED:"fixed"},PK=($)=>new B0({name:"w:tblLayout",attributes:{type:{key:"w:type",value:$}}}),vV={DXA:"dxa"},TK=({type:$=vV.DXA,value:U})=>new B0({name:"w:tblCellSpacing",attributes:{type:{key:"w:type",value:$},value:{key:"w:w",value:s9(U)}}}),CK=({firstRow:$,lastRow:U,firstColumn:Y,lastColumn:Z,noHBand:J,noVBand:G})=>new B0({name:"w:tblLook",attributes:{firstRow:{key:"w:firstRow",value:$},lastRow:{key:"w:lastRow",value:U},firstColumn:{key:"w:firstColumn",value:Y},lastColumn:{key:"w:lastColumn",value:Z},noHBand:{key:"w:noHBand",value:J},noVBand:{key:"w:noVBand",value:G}}});class L8 extends Q2{constructor($){super("w:tblPr",$.includeIfEmpty);if($.style)this.root.push(new Y2("w:tblStyle",$.style));if($.float)this.root.push(AK($.float));if($.visuallyRightToLeft!==void 0)this.root.push(new X0("w:bidiVisual",$.visuallyRightToLeft));if($.width)this.root.push(M1("w:tblW",$.width));if($.alignment)this.root.push(n9($.alignment));if($.indent)this.root.push(M1("w:tblInd",$.indent));if($.borders)this.root.push(new B8($.borders));if($.shading)this.root.push(j1($.shading));if($.layout)this.root.push(PK($.layout));if($.cellMargin){let U=DV($.cellMargin);if(U)this.root.push(U)}if($.tableLook)this.root.push(CK($.tableLook));if($.cellSpacing)this.root.push(TK($.cellSpacing));if($.revision)this.root.push(new OK($.revision))}}class OK extends o{constructor($){super("w:tblPrChange");this.root.push(new _0({id:$.id,author:$.author,date:$.date})),this.root.push(new L8(R0(W0({},$),{includeIfEmpty:!0})))}}class kK extends r2{constructor({rows:$,width:U,columnWidths:Y=Array(Math.max(...$.map((H)=>H.CellCount))).fill(100),columnWidthsRevision:Z,margins:J,indent:G,float:X,layout:Q,style:B,borders:F,alignment:z,visuallyRightToLeft:W,tableLook:k,cellSpacing:D,revision:C}){super("w:tbl");this.root.push(new L8({borders:F!=null?F:{},width:U!=null?U:{size:100},indent:G,float:X,layout:Q,style:B,alignment:z,cellMargin:J,visuallyRightToLeft:W,tableLook:k,cellSpacing:D,revision:C})),this.root.push(new S$(Y,Z));for(let H of $)this.root.push(H);$.forEach((H,O)=>{if(O===$.length-1)return;let V=0;H.cells.forEach((j)=>{if(j.options.rowSpan&&j.options.rowSpan>1){let M=new V8({rowSpan:j.options.rowSpan-1,columnSpan:j.options.columnSpan,borders:j.options.borders,children:[],verticalMerge:d$.CONTINUE});$[O+1].addCellToColumnIndex(M,V)}V+=j.options.columnSpan||1})})}}var _V={AUTO:"auto",ATLEAST:"atLeast",EXACT:"exact"},EK=($,U)=>new B0({name:"w:trHeight",attributes:{value:{key:"w:val",value:T0($)},rule:{key:"w:hRule",value:U}}});class M8 extends Q2{constructor($){super("w:trPr",$.includeIfEmpty);if($.cantSplit!==void 0)this.root.push(new X0("w:cantSplit",$.cantSplit));if($.tableHeader!==void 0)this.root.push(new X0("w:tblHeader",$.tableHeader));if($.height)this.root.push(EK($.height.value,$.height.rule));if($.cellSpacing)this.root.push(TK($.cellSpacing));if($.insertion)this.root.push(new v$($.insertion));if($.deletion)this.root.push(new _$($.deletion));if($.revision)this.root.push(new l$($.revision))}}class l$ extends o{constructor($){super("w:trPrChange");this.root.push(new _0({id:$.id,author:$.author,date:$.date})),this.root.push(new M8(R0(W0({},$),{includeIfEmpty:!0})))}}class SK extends o{constructor($){super("w:tr");this.options=$,this.root.push(new M8($));for(let U of $.children)this.root.push(U)}get CellCount(){return this.options.children.length}get cells(){return this.root.filter(($)=>$ instanceof V8)}addCellToIndex($,U){this.root.splice(U+1,0,$)}addCellToColumnIndex($,U){let Y=this.columnIndexToRootIndex(U,!0);this.addCellToIndex($,Y-1)}rootIndexToColumnIndex($){if($<1||$>=this.root.length)throw Error(`cell 'rootIndex' should between 1 to ${this.root.length-1}`);let U=0;for(let Y=1;Y<$;Y++){let Z=this.root[Y];U+=Z.options.columnSpan||1}return U}columnIndexToRootIndex($,U=!1){if($<0)throw Error("cell 'columnIndex' should not less than zero");let Y=0,Z=1;while(Y<=$){if(Z>=this.root.length)if(U)return this.root.length;else throw Error(`cell 'columnIndex' should not great than ${Y-1}`);let J=this.root[Z];Z+=1,Y+=J&&J.options.columnSpan||1}return Z-1}}class vK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{xmlns:"xmlns",vt:"xmlns:vt"})}}class _K extends o{constructor(){super("Properties");this.root.push(new vK({xmlns:"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",vt:"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"}))}}class yK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{xmlns:"xmlns"})}}var B2=($,U)=>new B0({name:"Default",attributes:{contentType:{key:"ContentType",value:$},extension:{key:"Extension",value:U}}}),f0=($,U)=>new B0({name:"Override",attributes:{contentType:{key:"ContentType",value:$},partName:{key:"PartName",value:U}}});class bK extends o{constructor(){super("Types");this.root.push(new yK({xmlns:"http://schemas.openxmlformats.org/package/2006/content-types"})),this.root.push(B2("image/png","png")),this.root.push(B2("image/jpeg","jpeg")),this.root.push(B2("image/jpeg","jpg")),this.root.push(B2("image/bmp","bmp")),this.root.push(B2("image/gif","gif")),this.root.push(B2("image/svg+xml","svg")),this.root.push(B2("application/vnd.openxmlformats-package.relationships+xml","rels")),this.root.push(B2("application/xml","xml")),this.root.push(B2("application/vnd.openxmlformats-officedocument.obfuscatedFont","odttf")),this.root.push(f0("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml","/word/document.xml")),this.root.push(f0("application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml","/word/styles.xml")),this.root.push(f0("application/vnd.openxmlformats-package.core-properties+xml","/docProps/core.xml")),this.root.push(f0("application/vnd.openxmlformats-officedocument.custom-properties+xml","/docProps/custom.xml")),this.root.push(f0("application/vnd.openxmlformats-officedocument.extended-properties+xml","/docProps/app.xml")),this.root.push(f0("application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml","/word/numbering.xml")),this.root.push(f0("application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml","/word/footnotes.xml")),this.root.push(f0("application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml","/word/endnotes.xml")),this.root.push(f0("application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml","/word/settings.xml")),this.root.push(f0("application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml","/word/comments.xml")),this.root.push(f0("application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml","/word/fontTable.xml"))}addFooter($){this.root.push(f0("application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",`/word/footer${$}.xml`))}addHeader($){this.root.push(f0("application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",`/word/header${$}.xml`))}}var p1={wpc:"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",mc:"http://schemas.openxmlformats.org/markup-compatibility/2006",o:"urn:schemas-microsoft-com:office:office",r:"http://schemas.openxmlformats.org/officeDocument/2006/relationships",m:"http://schemas.openxmlformats.org/officeDocument/2006/math",v:"urn:schemas-microsoft-com:vml",wp14:"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",wp:"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",w10:"urn:schemas-microsoft-com:office:word",w:"http://schemas.openxmlformats.org/wordprocessingml/2006/main",w14:"http://schemas.microsoft.com/office/word/2010/wordml",w15:"http://schemas.microsoft.com/office/word/2012/wordml",wpg:"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",wpi:"http://schemas.microsoft.com/office/word/2010/wordprocessingInk",wne:"http://schemas.microsoft.com/office/word/2006/wordml",wps:"http://schemas.microsoft.com/office/word/2010/wordprocessingShape",cp:"http://schemas.openxmlformats.org/package/2006/metadata/core-properties",dc:"http://purl.org/dc/elements/1.1/",dcterms:"http://purl.org/dc/terms/",dcmitype:"http://purl.org/dc/dcmitype/",xsi:"http://www.w3.org/2001/XMLSchema-instance",cx:"http://schemas.microsoft.com/office/drawing/2014/chartex",cx1:"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex",cx2:"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex",cx3:"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex",cx4:"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex",cx5:"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex",cx6:"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex",cx7:"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex",cx8:"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex",aink:"http://schemas.microsoft.com/office/drawing/2016/ink",am3d:"http://schemas.microsoft.com/office/drawing/2017/model3d",w16cex:"http://schemas.microsoft.com/office/word/2018/wordml/cex",w16cid:"http://schemas.microsoft.com/office/word/2016/wordml/cid",w16:"http://schemas.microsoft.com/office/word/2018/wordml",w16sdtdh:"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash",w16se:"http://schemas.microsoft.com/office/word/2015/wordml/symex"};class o2 extends I0{constructor($,U){super(W0({Ignorable:U},Object.fromEntries($.map((Y)=>[Y,p1[Y]]))));Y0(this,"xmlKeys",W0({Ignorable:"mc:Ignorable"},Object.fromEntries(Object.keys(p1).map((Y)=>[Y,`xmlns:${Y}`]))))}}class gK extends o{constructor($){super("cp:coreProperties");if(this.root.push(new o2(["cp","dc","dcterms","dcmitype","xsi"])),$.title)this.root.push(new L2("dc:title",$.title));if($.subject)this.root.push(new L2("dc:subject",$.subject));if($.creator)this.root.push(new L2("dc:creator",$.creator));if($.keywords)this.root.push(new L2("cp:keywords",$.keywords));if($.description)this.root.push(new L2("dc:description",$.description));if($.lastModifiedBy)this.root.push(new L2("cp:lastModifiedBy",$.lastModifiedBy));if($.revision)this.root.push(new L2("cp:revision",String($.revision)));this.root.push(new E9("dcterms:created")),this.root.push(new E9("dcterms:modified"))}}class xK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{type:"xsi:type"})}}class E9 extends o{constructor($){super($);this.root.push(new xK({type:"dcterms:W3CDTF"})),this.root.push(OQ(new Date))}}class fK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{xmlns:"xmlns",vt:"xmlns:vt"})}}class hK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{formatId:"fmtid",pid:"pid",name:"name"})}}class uK extends o{constructor($,U){super("property");this.root.push(new hK({formatId:"{D5CDD505-2E9C-101B-9397-08002B2CF9AE}",pid:$.toString(),name:U.name})),this.root.push(new dK(U.value))}}class dK extends o{constructor($){super("vt:lpwstr");this.root.push($)}}class cK extends o{constructor($){super("Properties");Y0(this,"nextId"),Y0(this,"properties",[]),this.root.push(new fK({xmlns:"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties",vt:"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"})),this.nextId=2;for(let U of $)this.addCustomProperty(U)}prepForXml($){return this.properties.forEach((U)=>this.root.push(U)),super.prepForXml($)}addCustomProperty($){this.properties.push(new uK(this.nextId++,$))}}var mK=({space:$,count:U,separate:Y,equalWidth:Z,children:J})=>new B0({name:"w:cols",attributes:{space:{key:"w:space",value:$===void 0?void 0:T0($)},count:{key:"w:num",value:U===void 0?void 0:S0(U)},separate:{key:"w:sep",value:Y},equalWidth:{key:"w:equalWidth",value:Z}},children:!Z&&J?J:void 0}),yV={DEFAULT:"default",LINES:"lines",LINES_AND_CHARS:"linesAndChars",SNAP_TO_CHARS:"snapToChars"},lK=({type:$,linePitch:U,charSpace:Y})=>new B0({name:"w:docGrid",attributes:{type:{key:"w:type",value:$},linePitch:{key:"w:linePitch",value:S0(U)},charSpace:{key:"w:charSpace",value:Y?S0(Y):void 0}}}),E2={DEFAULT:"default",FIRST:"first",EVEN:"even"},S9={HEADER:"w:headerReference",FOOTER:"w:footerReference"},f1=($,U)=>new B0({name:$,attributes:{type:{key:"w:type",value:U.type||E2.DEFAULT},id:{key:"r:id",value:`rId${U.id}`}}}),bV={NEW_PAGE:"newPage",NEW_SECTION:"newSection",CONTINUOUS:"continuous"},aK=({countBy:$,start:U,restart:Y,distance:Z})=>new B0({name:"w:lnNumType",attributes:{countBy:{key:"w:countBy",value:$===void 0?void 0:S0($)},start:{key:"w:start",value:U===void 0?void 0:S0(U)},restart:{key:"w:restart",value:Y},distance:{key:"w:distance",value:Z===void 0?void 0:T0(Z)}}}),gV={ALL_PAGES:"allPages",FIRST_PAGE:"firstPage",NOT_FIRST_PAGE:"notFirstPage"},xV={PAGE:"page",TEXT:"text"},fV={BACK:"back",FRONT:"front"};class v9 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{display:"w:display",offsetFrom:"w:offsetFrom",zOrder:"w:zOrder"})}}class a$ extends Q2{constructor($){super("w:pgBorders");if(!$)return this;if($.pageBorders)this.root.push(new v9({display:$.pageBorders.display,offsetFrom:$.pageBorders.offsetFrom,zOrder:$.pageBorders.zOrder}));else this.root.push(new v9({}));if($.pageBorderTop)this.root.push(N0("w:top",$.pageBorderTop));if($.pageBorderLeft)this.root.push(N0("w:left",$.pageBorderLeft));if($.pageBorderBottom)this.root.push(N0("w:bottom",$.pageBorderBottom));if($.pageBorderRight)this.root.push(N0("w:right",$.pageBorderRight))}}var pK=($,U,Y,Z,J,G,X)=>new B0({name:"w:pgMar",attributes:{top:{key:"w:top",value:e0($)},right:{key:"w:right",value:T0(U)},bottom:{key:"w:bottom",value:e0(Y)},left:{key:"w:left",value:T0(Z)},header:{key:"w:header",value:T0(J)},footer:{key:"w:footer",value:T0(G)},gutter:{key:"w:gutter",value:T0(X)}}}),hV={HYPHEN:"hyphen",PERIOD:"period",COLON:"colon",EM_DASH:"emDash",EN_DASH:"endash"},iK=({start:$,formatType:U,separator:Y})=>new B0({name:"w:pgNumType",attributes:{start:{key:"w:start",value:$===void 0?void 0:S0($)},formatType:{key:"w:fmt",value:U},separator:{key:"w:chapSep",value:Y}}}),i1={PORTRAIT:"portrait",LANDSCAPE:"landscape"},rK=({width:$,height:U,orientation:Y,code:Z})=>{let J=T0($),G=T0(U);return new B0({name:"w:pgSz",attributes:{width:{key:"w:w",value:Y===i1.LANDSCAPE?G:J},height:{key:"w:h",value:Y===i1.LANDSCAPE?J:G},orientation:{key:"w:orient",value:Y},code:{key:"w:code",value:Z}}})},uV={LEFT_TO_RIGHT_TOP_TO_BOTTOM:"lrTb",TOP_TO_BOTTOM_RIGHT_TO_LEFT:"tbRl"};class sK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{val:"w:val"})}}class p$ extends o{constructor($){super("w:textDirection");this.root.push(new sK({val:$}))}}var dV={NEXT_PAGE:"nextPage",NEXT_COLUMN:"nextColumn",CONTINUOUS:"continuous",EVEN_PAGE:"evenPage",ODD_PAGE:"oddPage"},nK=($)=>new B0({name:"w:type",attributes:{val:{key:"w:val",value:$}}}),F2={TOP:1440,RIGHT:1440,BOTTOM:1440,LEFT:1440,HEADER:708,FOOTER:708,GUTTER:0},h1={WIDTH:11906,HEIGHT:16838,ORIENTATION:i1.PORTRAIT};class I8 extends o{constructor({page:{size:{width:$=h1.WIDTH,height:U=h1.HEIGHT,orientation:Y=h1.ORIENTATION}={},margin:{top:Z=F2.TOP,right:J=F2.RIGHT,bottom:G=F2.BOTTOM,left:X=F2.LEFT,header:Q=F2.HEADER,footer:B=F2.FOOTER,gutter:F=F2.GUTTER}={},pageNumbers:z={},borders:W,textDirection:k}={},grid:{linePitch:D=360,charSpace:C,type:H}={},headerWrapperGroup:O={},footerWrapperGroup:V={},lineNumbers:j,titlePage:M,verticalAlign:L,column:A,type:y,revision:g}={}){super("w:sectPr");if(this.addHeaderFooterGroup(S9.HEADER,O),this.addHeaderFooterGroup(S9.FOOTER,V),y)this.root.push(nK(y));if(this.root.push(rK({width:$,height:U,orientation:Y})),this.root.push(pK(Z,J,G,X,Q,B,F)),W)this.root.push(new a$(W));if(j)this.root.push(aK(j));if(this.root.push(iK(z)),A)this.root.push(mK(A));if(L)this.root.push(f$(L));if(M!==void 0)this.root.push(new X0("w:titlePg",M));if(k)this.root.push(new p$(k));if(g)this.root.push(new i$(g));this.root.push(lK({linePitch:D,charSpace:C,type:H}))}addHeaderFooterGroup($,U){if(U.default)this.root.push(f1($,{type:E2.DEFAULT,id:U.default.View.ReferenceId}));if(U.first)this.root.push(f1($,{type:E2.FIRST,id:U.first.View.ReferenceId}));if(U.even)this.root.push(f1($,{type:E2.EVEN,id:U.even.View.ReferenceId}))}}class i$ extends o{constructor($){super("w:sectPrChange");this.root.push(new _0({id:$.id,author:$.author,date:$.date})),this.root.push(new I8($))}}class oK extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{width:"w:w",space:"w:space"})}}class tK extends o{constructor($){super("w:col");this.root.push(new oK({width:T0($.width),space:$.space===void 0?void 0:T0($.space)}))}}class r$ extends o{constructor(){super("w:body");Y0(this,"sections",[])}addSection($){let U=this.sections.pop();this.root.push(this.createSectionParagraph(U)),this.sections.push(new I8($))}prepForXml($){if(this.sections.length===1)this.root.splice(0,1),this.root.push(this.sections.pop());return super.prepForXml($)}push($){this.root.push($)}createSectionParagraph($){let U=new h0({}),Y=new Z2({});return Y.push($),U.addChildElement(Y),U}}class s$ extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{color:"w:color",themeColor:"w:themeColor",themeShade:"w:themeShade",themeTint:"w:themeTint"})}}class n$ extends o{constructor($){super("w:background");this.root.push(new s$({color:$.color===void 0?void 0:S2($.color),themeColor:$.themeColor,themeShade:$.themeShade===void 0?void 0:D9($.themeShade),themeTint:$.themeTint===void 0?void 0:D9($.themeTint)}))}}class eK extends o{constructor($){super("w:document");if(Y0(this,"body"),this.root.push(new o2(["wpc","mc","o","r","m","v","wp14","wp","w10","w","w14","w15","wpg","wpi","wne","wps","cx","cx1","cx2","cx3","cx4","cx5","cx6","cx7","cx8","aink","am3d","w16cex","w16cid","w16","w16sdtdh","w16se"],"w14 w15 wp14")),this.body=new r$,$.background)this.root.push(new n$($.background));this.root.push(this.body)}add($){return this.body.push($),this}get Body(){return this.body}}class $5{constructor($){Y0(this,"document"),Y0(this,"relationships"),this.document=new eK($),this.relationships=new W2}get View(){return this.document}get Relationships(){return this.relationships}}class U5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{wpc:"xmlns:wpc",mc:"xmlns:mc",o:"xmlns:o",r:"xmlns:r",m:"xmlns:m",v:"xmlns:v",wp14:"xmlns:wp14",wp:"xmlns:wp",w10:"xmlns:w10",w:"xmlns:w",w14:"xmlns:w14",w15:"xmlns:w15",wpg:"xmlns:wpg",wpi:"xmlns:wpi",wne:"xmlns:wne",wps:"xmlns:wps",Ignorable:"mc:Ignorable"})}}class Y5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{type:"w:type",id:"w:id"})}}class Z5 extends C0{constructor(){super({style:"EndnoteReference"});this.root.push(new I$)}}var fZ={SEPARATOR:"separator",CONTINUATION_SEPARATOR:"continuationSeparator"};class u1 extends o{constructor($){super("w:endnote");this.root.push(new Y5({type:$.type,id:$.id}));for(let U=0;U<$.children.length;U++){let Y=$.children[U];if(U===0)Y.addRunToFront(new Z5);this.root.push(Y)}}}class Q5 extends o{constructor(){super("w:continuationSeparator")}}class o$ extends C0{constructor(){super({});this.root.push(new Q5)}}class J5 extends o{constructor(){super("w:separator")}}class t$ extends C0{constructor(){super({});this.root.push(new J5)}}class e$ extends o{constructor(){super("w:endnotes");this.root.push(new U5({wpc:"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",mc:"http://schemas.openxmlformats.org/markup-compatibility/2006",o:"urn:schemas-microsoft-com:office:office",r:"http://schemas.openxmlformats.org/officeDocument/2006/relationships",m:"http://schemas.openxmlformats.org/officeDocument/2006/math",v:"urn:schemas-microsoft-com:vml",wp14:"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",wp:"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",w10:"urn:schemas-microsoft-com:office:word",w:"http://schemas.openxmlformats.org/wordprocessingml/2006/main",w14:"http://schemas.microsoft.com/office/word/2010/wordml",w15:"http://schemas.microsoft.com/office/word/2012/wordml",wpg:"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",wpi:"http://schemas.microsoft.com/office/word/2010/wordprocessingInk",wne:"http://schemas.microsoft.com/office/word/2006/wordml",wps:"http://schemas.microsoft.com/office/word/2010/wordprocessingShape",Ignorable:"w14 w15 wp14"}));let $=new u1({id:-1,type:fZ.SEPARATOR,children:[new h0({spacing:{after:0,line:240,lineRule:v2.AUTO},children:[new t$]})]});this.root.push($);let U=new u1({id:0,type:fZ.CONTINUATION_SEPARATOR,children:[new h0({spacing:{after:0,line:240,lineRule:v2.AUTO},children:[new o$]})]});this.root.push(U)}createEndnote($,U){let Y=new u1({id:$,children:U});this.root.push(Y)}}class G5{constructor(){Y0(this,"endnotes"),Y0(this,"relationships"),this.endnotes=new e$,this.relationships=new W2}get View(){return this.endnotes}get Relationships(){return this.relationships}}class K5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{wpc:"xmlns:wpc",mc:"xmlns:mc",o:"xmlns:o",r:"xmlns:r",m:"xmlns:m",v:"xmlns:v",wp14:"xmlns:wp14",wp:"xmlns:wp",w10:"xmlns:w10",w:"xmlns:w",w14:"xmlns:w14",w15:"xmlns:w15",wpg:"xmlns:wpg",wpi:"xmlns:wpi",wne:"xmlns:wne",wps:"xmlns:wps",cp:"xmlns:cp",dc:"xmlns:dc",dcterms:"xmlns:dcterms",dcmitype:"xmlns:dcmitype",xsi:"xmlns:xsi",type:"xsi:type"})}}var cV=class extends Y8{constructor(U,Y){super("w:ftr",Y);if(Y0(this,"refId"),this.refId=U,!Y)this.root.push(new K5({wpc:"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",mc:"http://schemas.openxmlformats.org/markup-compatibility/2006",o:"urn:schemas-microsoft-com:office:office",r:"http://schemas.openxmlformats.org/officeDocument/2006/relationships",m:"http://schemas.openxmlformats.org/officeDocument/2006/math",v:"urn:schemas-microsoft-com:vml",wp14:"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",wp:"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",w10:"urn:schemas-microsoft-com:office:word",w:"http://schemas.openxmlformats.org/wordprocessingml/2006/main",w14:"http://schemas.microsoft.com/office/word/2010/wordml",w15:"http://schemas.microsoft.com/office/word/2012/wordml",wpg:"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",wpi:"http://schemas.microsoft.com/office/word/2010/wordprocessingInk",wne:"http://schemas.microsoft.com/office/word/2006/wordml",wps:"http://schemas.microsoft.com/office/word/2010/wordprocessingShape"}))}get ReferenceId(){return this.refId}add(U){this.root.push(U)}};class $U{constructor($,U,Y){Y0(this,"footer"),Y0(this,"relationships"),this.media=$,this.footer=new cV(U,Y),this.relationships=new W2}add($){this.footer.add($)}addChildElement($){this.footer.addChildElement($)}get View(){return this.footer}get Relationships(){return this.relationships}get Media(){return this.media}}class q5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{type:"w:type",id:"w:id"})}}class X5 extends o{constructor(){super("w:footnoteRef")}}class V5 extends C0{constructor(){super({style:"FootnoteReference"});this.root.push(new X5)}}var hZ={SEPERATOR:"separator",CONTINUATION_SEPERATOR:"continuationSeparator"};class d1 extends o{constructor($){super("w:footnote");this.root.push(new q5({type:$.type,id:$.id}));for(let U=0;U<$.children.length;U++){let Y=$.children[U];if(U===0)Y.addRunToFront(new V5);this.root.push(Y)}}}class B5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{wpc:"xmlns:wpc",mc:"xmlns:mc",o:"xmlns:o",r:"xmlns:r",m:"xmlns:m",v:"xmlns:v",wp14:"xmlns:wp14",wp:"xmlns:wp",w10:"xmlns:w10",w:"xmlns:w",w14:"xmlns:w14",w15:"xmlns:w15",wpg:"xmlns:wpg",wpi:"xmlns:wpi",wne:"xmlns:wne",wps:"xmlns:wps",Ignorable:"mc:Ignorable"})}}class UU extends o{constructor(){super("w:footnotes");this.root.push(new B5({wpc:"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",mc:"http://schemas.openxmlformats.org/markup-compatibility/2006",o:"urn:schemas-microsoft-com:office:office",r:"http://schemas.openxmlformats.org/officeDocument/2006/relationships",m:"http://schemas.openxmlformats.org/officeDocument/2006/math",v:"urn:schemas-microsoft-com:vml",wp14:"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",wp:"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",w10:"urn:schemas-microsoft-com:office:word",w:"http://schemas.openxmlformats.org/wordprocessingml/2006/main",w14:"http://schemas.microsoft.com/office/word/2010/wordml",w15:"http://schemas.microsoft.com/office/word/2012/wordml",wpg:"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",wpi:"http://schemas.microsoft.com/office/word/2010/wordprocessingInk",wne:"http://schemas.microsoft.com/office/word/2006/wordml",wps:"http://schemas.microsoft.com/office/word/2010/wordprocessingShape",Ignorable:"w14 w15 wp14"}));let $=new d1({id:-1,type:hZ.SEPERATOR,children:[new h0({spacing:{after:0,line:240,lineRule:v2.AUTO},children:[new t$]})]});this.root.push($);let U=new d1({id:0,type:hZ.CONTINUATION_SEPERATOR,children:[new h0({spacing:{after:0,line:240,lineRule:v2.AUTO},children:[new o$]})]});this.root.push(U)}createFootNote($,U){let Y=new d1({id:$,children:U});this.root.push(Y)}}class L5{constructor(){Y0(this,"footnotess"),Y0(this,"relationships"),this.footnotess=new UU,this.relationships=new W2}get View(){return this.footnotess}get Relationships(){return this.relationships}}class M5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{wpc:"xmlns:wpc",mc:"xmlns:mc",o:"xmlns:o",r:"xmlns:r",m:"xmlns:m",v:"xmlns:v",wp14:"xmlns:wp14",wp:"xmlns:wp",w10:"xmlns:w10",w:"xmlns:w",w14:"xmlns:w14",w15:"xmlns:w15",wpg:"xmlns:wpg",wpi:"xmlns:wpi",wne:"xmlns:wne",wps:"xmlns:wps",cp:"xmlns:cp",dc:"xmlns:dc",dcterms:"xmlns:dcterms",dcmitype:"xmlns:dcmitype",xsi:"xmlns:xsi",type:"xsi:type",cx:"xmlns:cx",cx1:"xmlns:cx1",cx2:"xmlns:cx2",cx3:"xmlns:cx3",cx4:"xmlns:cx4",cx5:"xmlns:cx5",cx6:"xmlns:cx6",cx7:"xmlns:cx7",cx8:"xmlns:cx8",w16cid:"xmlns:w16cid",w16se:"xmlns:w16se"})}}var mV=class extends Y8{constructor(U,Y){super("w:hdr",Y);if(Y0(this,"refId"),this.refId=U,!Y)this.root.push(new M5({wpc:"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",mc:"http://schemas.openxmlformats.org/markup-compatibility/2006",o:"urn:schemas-microsoft-com:office:office",r:"http://schemas.openxmlformats.org/officeDocument/2006/relationships",m:"http://schemas.openxmlformats.org/officeDocument/2006/math",v:"urn:schemas-microsoft-com:vml",wp14:"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",wp:"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",w10:"urn:schemas-microsoft-com:office:word",w:"http://schemas.openxmlformats.org/wordprocessingml/2006/main",w14:"http://schemas.microsoft.com/office/word/2010/wordml",w15:"http://schemas.microsoft.com/office/word/2012/wordml",wpg:"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",wpi:"http://schemas.microsoft.com/office/word/2010/wordprocessingInk",wne:"http://schemas.microsoft.com/office/word/2006/wordml",wps:"http://schemas.microsoft.com/office/word/2010/wordprocessingShape",cx:"http://schemas.microsoft.com/office/drawing/2014/chartex",cx1:"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex",cx2:"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex",cx3:"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex",cx4:"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex",cx5:"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex",cx6:"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex",cx7:"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex",cx8:"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex",w16cid:"http://schemas.microsoft.com/office/word/2016/wordml/cid",w16se:"http://schemas.microsoft.com/office/word/2015/wordml/symex"}))}get ReferenceId(){return this.refId}add(U){this.root.push(U)}};class YU{constructor($,U,Y){Y0(this,"header"),Y0(this,"relationships"),this.media=$,this.header=new mV(U,Y),this.relationships=new W2}add($){return this.header.add($),this}addChildElement($){this.header.addChildElement($)}get View(){return this.header}get Relationships(){return this.relationships}get Media(){return this.media}}class w8{constructor(){Y0(this,"map"),this.map=new Map}addImage($,U){this.map.set($,U)}get Array(){return Array.from(this.map.values())}}var lV="",n0={DECIMAL:"decimal",UPPER_ROMAN:"upperRoman",LOWER_ROMAN:"lowerRoman",UPPER_LETTER:"upperLetter",LOWER_LETTER:"lowerLetter",ORDINAL:"ordinal",CARDINAL_TEXT:"cardinalText",ORDINAL_TEXT:"ordinalText",HEX:"hex",CHICAGO:"chicago",IDEOGRAPH__DIGITAL:"ideographDigital",JAPANESE_COUNTING:"japaneseCounting",AIUEO:"aiueo",IROHA:"iroha",DECIMAL_FULL_WIDTH:"decimalFullWidth",DECIMAL_HALF_WIDTH:"decimalHalfWidth",JAPANESE_LEGAL:"japaneseLegal",JAPANESE_DIGITAL_TEN_THOUSAND:"japaneseDigitalTenThousand",DECIMAL_ENCLOSED_CIRCLE:"decimalEnclosedCircle",DECIMAL_FULL_WIDTH2:"decimalFullWidth2",AIUEO_FULL_WIDTH:"aiueoFullWidth",IROHA_FULL_WIDTH:"irohaFullWidth",DECIMAL_ZERO:"decimalZero",BULLET:"bullet",GANADA:"ganada",CHOSUNG:"chosung",DECIMAL_ENCLOSED_FULLSTOP:"decimalEnclosedFullstop",DECIMAL_ENCLOSED_PARENTHESES:"decimalEnclosedParen",DECIMAL_ENCLOSED_CIRCLE_CHINESE:"decimalEnclosedCircleChinese",IDEOGRAPH_ENCLOSED_CIRCLE:"ideographEnclosedCircle",IDEOGRAPH_TRADITIONAL:"ideographTraditional",IDEOGRAPH_ZODIAC:"ideographZodiac",IDEOGRAPH_ZODIAC_TRADITIONAL:"ideographZodiacTraditional",TAIWANESE_COUNTING:"taiwaneseCounting",IDEOGRAPH_LEGAL_TRADITIONAL:"ideographLegalTraditional",TAIWANESE_COUNTING_THOUSAND:"taiwaneseCountingThousand",TAIWANESE_DIGITAL:"taiwaneseDigital",CHINESE_COUNTING:"chineseCounting",CHINESE_LEGAL_SIMPLIFIED:"chineseLegalSimplified",CHINESE_COUNTING_THOUSAND:"chineseCountingThousand",KOREAN_DIGITAL:"koreanDigital",KOREAN_COUNTING:"koreanCounting",KOREAN_LEGAL:"koreanLegal",KOREAN_DIGITAL2:"koreanDigital2",VIETNAMESE_COUNTING:"vietnameseCounting",RUSSIAN_LOWER:"russianLower",RUSSIAN_UPPER:"russianUpper",NONE:"none",NUMBER_IN_DASH:"numberInDash",HEBREW1:"hebrew1",HEBREW2:"hebrew2",ARABIC_ALPHA:"arabicAlpha",ARABIC_ABJAD:"arabicAbjad",HINDI_VOWELS:"hindiVowels",HINDI_CONSONANTS:"hindiConsonants",HINDI_NUMBERS:"hindiNumbers",HINDI_COUNTING:"hindiCounting",THAI_LETTERS:"thaiLetters",THAI_NUMBERS:"thaiNumbers",THAI_COUNTING:"thaiCounting",BAHT_TEXT:"bahtText",DOLLAR_TEXT:"dollarText",CUSTOM:"custom"};class I5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{ilvl:"w:ilvl",tentative:"w15:tentative"})}}class w5 extends o{constructor($){super("w:numFmt");this.root.push(new O0({val:$}))}}class W5 extends o{constructor($){super("w:lvlText");this.root.push(new O0({val:$}))}}class H5 extends o{constructor($){super("w:lvlJc");this.root.push(new O0({val:$}))}}var aV={NOTHING:"nothing",SPACE:"space",TAB:"tab"};class j5 extends o{constructor($){super("w:suff");this.root.push(new O0({val:$}))}}class z5 extends o{constructor(){super("w:isLgl")}}class W8 extends o{constructor({level:$,format:U,text:Y,alignment:Z=m0.START,start:J=1,style:G,suffix:X,isLegalNumberingStyle:Q}){super("w:lvl");if(Y0(this,"paragraphProperties"),Y0(this,"runProperties"),this.root.push(new k2("w:start",S0(J))),U)this.root.push(new w5(U));if(X)this.root.push(new j5(X));if(Q)this.root.push(new z5);if(Y)this.root.push(new W5(Y));if(this.root.push(new H5(Z)),this.paragraphProperties=new Z2(G&&G.paragraph),this.runProperties=new J2(G&&G.run),this.root.push(this.paragraphProperties),this.root.push(this.runProperties),$>9)throw Error("Level cannot be greater than 9. Read more here: https://answers.microsoft.com/en-us/msoffice/forum/all/does-word-support-more-than-9-list-levels/d130fdcd-1781-446d-8c84-c6c79124e4d7");this.root.push(new I5({ilvl:S0($),tentative:1}))}}class ZU extends W8{}class F5 extends W8{}class N5 extends o{constructor($){super("w:multiLevelType");this.root.push(new O0({val:$}))}}class R5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{abstractNumId:"w:abstractNumId",restartNumberingAfterBreak:"w15:restartNumberingAfterBreak"})}}class r1 extends o{constructor($,U){super("w:abstractNum");Y0(this,"id"),this.root.push(new R5({abstractNumId:S0($),restartNumberingAfterBreak:0})),this.root.push(new N5("hybridMultilevel")),this.id=$;for(let Y of U)this.root.push(new ZU(Y))}}class D5 extends o{constructor($){super("w:abstractNumId");this.root.push(new O0({val:$}))}}class A5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{numId:"w:numId"})}}class s1 extends o{constructor($){super("w:num");if(Y0(this,"numId"),Y0(this,"reference"),Y0(this,"instance"),this.numId=$.numId,this.reference=$.reference,this.instance=$.instance,this.root.push(new A5({numId:S0($.numId)})),this.root.push(new D5(S0($.abstractNumId))),$.overrideLevels&&$.overrideLevels.length)for(let U of $.overrideLevels)this.root.push(new QU(U.num,U.start))}}class P5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{ilvl:"w:ilvl"})}}class QU extends o{constructor($,U){super("w:lvlOverride");if(this.root.push(new P5({ilvl:$})),U!==void 0)this.root.push(new C5(U))}}class T5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{val:"w:val"})}}class C5 extends o{constructor($){super("w:startOverride");this.root.push(new T5({val:$}))}}class JU extends o{constructor($){super("w:numbering");Y0(this,"abstractNumberingMap",new Map),Y0(this,"concreteNumberingMap",new Map),Y0(this,"referenceConfigMap",new Map),Y0(this,"abstractNumUniqueNumericId",rQ()),Y0(this,"concreteNumUniqueNumericId",sQ()),this.root.push(new o2(["wpc","mc","o","r","m","v","wp14","wp","w10","w","w14","w15","wpg","wpi","wne","wps"],"w14 w15 wp14"));let U=new r1(this.abstractNumUniqueNumericId(),[{level:0,format:n0.BULLET,text:"●",alignment:m0.LEFT,style:{paragraph:{indent:{left:d0(0.5),hanging:d0(0.25)}}}},{level:1,format:n0.BULLET,text:"○",alignment:m0.LEFT,style:{paragraph:{indent:{left:d0(1),hanging:d0(0.25)}}}},{level:2,format:n0.BULLET,text:"■",alignment:m0.LEFT,style:{paragraph:{indent:{left:2160,hanging:d0(0.25)}}}},{level:3,format:n0.BULLET,text:"●",alignment:m0.LEFT,style:{paragraph:{indent:{left:2880,hanging:d0(0.25)}}}},{level:4,format:n0.BULLET,text:"○",alignment:m0.LEFT,style:{paragraph:{indent:{left:3600,hanging:d0(0.25)}}}},{level:5,format:n0.BULLET,text:"■",alignment:m0.LEFT,style:{paragraph:{indent:{left:4320,hanging:d0(0.25)}}}},{level:6,format:n0.BULLET,text:"●",alignment:m0.LEFT,style:{paragraph:{indent:{left:5040,hanging:d0(0.25)}}}},{level:7,format:n0.BULLET,text:"●",alignment:m0.LEFT,style:{paragraph:{indent:{left:5760,hanging:d0(0.25)}}}},{level:8,format:n0.BULLET,text:"●",alignment:m0.LEFT,style:{paragraph:{indent:{left:6480,hanging:d0(0.25)}}}}]);this.concreteNumberingMap.set("default-bullet-numbering",new s1({numId:1,abstractNumId:U.id,reference:"default-bullet-numbering",instance:0,overrideLevels:[{num:0,start:1}]})),this.abstractNumberingMap.set("default-bullet-numbering",U);for(let Y of $.config)this.abstractNumberingMap.set(Y.reference,new r1(this.abstractNumUniqueNumericId(),Y.levels)),this.referenceConfigMap.set(Y.reference,Y.levels)}prepForXml($){for(let U of this.abstractNumberingMap.values())this.root.push(U);for(let U of this.concreteNumberingMap.values())this.root.push(U);return super.prepForXml($)}createConcreteNumberingInstance($,U){let Y=this.abstractNumberingMap.get($);if(!Y)return;let Z=`${$}-${U}`;if(this.concreteNumberingMap.has(Z))return;let J=this.referenceConfigMap.get($),G=J&&J[0].start,X={numId:this.concreteNumUniqueNumericId(),abstractNumId:Y.id,reference:$,instance:U,overrideLevels:[typeof G==="number"&&Number.isInteger(G)?{num:0,start:G}:{num:0,start:1}]};this.concreteNumberingMap.set(Z,new s1(X))}get ConcreteNumbering(){return Array.from(this.concreteNumberingMap.values())}get ReferenceConfig(){return Array.from(this.referenceConfigMap.values())}}var pV=($)=>new B0({name:"w:compatSetting",attributes:{version:{key:"w:val",value:$},name:{key:"w:name",value:"compatibilityMode"},uri:{key:"w:uri",value:"http://schemas.microsoft.com/office/word"}}});class O5 extends o{constructor($){super("w:compat");if($.version)this.root.push(pV($.version));if($.useSingleBorderforContiguousCells)this.root.push(new X0("w:useSingleBorderforContiguousCells",$.useSingleBorderforContiguousCells));if($.wordPerfectJustification)this.root.push(new X0("w:wpJustification",$.wordPerfectJustification));if($.noTabStopForHangingIndent)this.root.push(new X0("w:noTabHangInd",$.noTabStopForHangingIndent));if($.noLeading)this.root.push(new X0("w:noLeading",$.noLeading));if($.spaceForUnderline)this.root.push(new X0("w:spaceForUL",$.spaceForUnderline));if($.noColumnBalance)this.root.push(new X0("w:noColumnBalance",$.noColumnBalance));if($.balanceSingleByteDoubleByteWidth)this.root.push(new X0("w:balanceSingleByteDoubleByteWidth",$.balanceSingleByteDoubleByteWidth));if($.noExtraLineSpacing)this.root.push(new X0("w:noExtraLineSpacing",$.noExtraLineSpacing));if($.doNotLeaveBackslashAlone)this.root.push(new X0("w:doNotLeaveBackslashAlone",$.doNotLeaveBackslashAlone));if($.underlineTrailingSpaces)this.root.push(new X0("w:ulTrailSpace",$.underlineTrailingSpaces));if($.doNotExpandShiftReturn)this.root.push(new X0("w:doNotExpandShiftReturn",$.doNotExpandShiftReturn));if($.spacingInWholePoints)this.root.push(new X0("w:spacingInWholePoints",$.spacingInWholePoints));if($.lineWrapLikeWord6)this.root.push(new X0("w:lineWrapLikeWord6",$.lineWrapLikeWord6));if($.printBodyTextBeforeHeader)this.root.push(new X0("w:printBodyTextBeforeHeader",$.printBodyTextBeforeHeader));if($.printColorsBlack)this.root.push(new X0("w:printColBlack",$.printColorsBlack));if($.spaceWidth)this.root.push(new X0("w:wpSpaceWidth",$.spaceWidth));if($.showBreaksInFrames)this.root.push(new X0("w:showBreaksInFrames",$.showBreaksInFrames));if($.subFontBySize)this.root.push(new X0("w:subFontBySize",$.subFontBySize));if($.suppressBottomSpacing)this.root.push(new X0("w:suppressBottomSpacing",$.suppressBottomSpacing));if($.suppressTopSpacing)this.root.push(new X0("w:suppressTopSpacing",$.suppressTopSpacing));if($.suppressSpacingAtTopOfPage)this.root.push(new X0("w:suppressSpacingAtTopOfPage",$.suppressSpacingAtTopOfPage));if($.suppressTopSpacingWP)this.root.push(new X0("w:suppressTopSpacingWP",$.suppressTopSpacingWP));if($.suppressSpBfAfterPgBrk)this.root.push(new X0("w:suppressSpBfAfterPgBrk",$.suppressSpBfAfterPgBrk));if($.swapBordersFacingPages)this.root.push(new X0("w:swapBordersFacingPages",$.swapBordersFacingPages));if($.convertMailMergeEsc)this.root.push(new X0("w:convMailMergeEsc",$.convertMailMergeEsc));if($.truncateFontHeightsLikeWP6)this.root.push(new X0("w:truncateFontHeightsLikeWP6",$.truncateFontHeightsLikeWP6));if($.macWordSmallCaps)this.root.push(new X0("w:mwSmallCaps",$.macWordSmallCaps));if($.usePrinterMetrics)this.root.push(new X0("w:usePrinterMetrics",$.usePrinterMetrics));if($.doNotSuppressParagraphBorders)this.root.push(new X0("w:doNotSuppressParagraphBorders",$.doNotSuppressParagraphBorders));if($.wrapTrailSpaces)this.root.push(new X0("w:wrapTrailSpaces",$.wrapTrailSpaces));if($.footnoteLayoutLikeWW8)this.root.push(new X0("w:footnoteLayoutLikeWW8",$.footnoteLayoutLikeWW8));if($.shapeLayoutLikeWW8)this.root.push(new X0("w:shapeLayoutLikeWW8",$.shapeLayoutLikeWW8));if($.alignTablesRowByRow)this.root.push(new X0("w:alignTablesRowByRow",$.alignTablesRowByRow));if($.forgetLastTabAlignment)this.root.push(new X0("w:forgetLastTabAlignment",$.forgetLastTabAlignment));if($.adjustLineHeightInTable)this.root.push(new X0("w:adjustLineHeightInTable",$.adjustLineHeightInTable));if($.autoSpaceLikeWord95)this.root.push(new X0("w:autoSpaceLikeWord95",$.autoSpaceLikeWord95));if($.noSpaceRaiseLower)this.root.push(new X0("w:noSpaceRaiseLower",$.noSpaceRaiseLower));if($.doNotUseHTMLParagraphAutoSpacing)this.root.push(new X0("w:doNotUseHTMLParagraphAutoSpacing",$.doNotUseHTMLParagraphAutoSpacing));if($.layoutRawTableWidth)this.root.push(new X0("w:layoutRawTableWidth",$.layoutRawTableWidth));if($.layoutTableRowsApart)this.root.push(new X0("w:layoutTableRowsApart",$.layoutTableRowsApart));if($.useWord97LineBreakRules)this.root.push(new X0("w:useWord97LineBreakRules",$.useWord97LineBreakRules));if($.doNotBreakWrappedTables)this.root.push(new X0("w:doNotBreakWrappedTables",$.doNotBreakWrappedTables));if($.doNotSnapToGridInCell)this.root.push(new X0("w:doNotSnapToGridInCell",$.doNotSnapToGridInCell));if($.selectFieldWithFirstOrLastCharacter)this.root.push(new X0("w:selectFldWithFirstOrLastChar",$.selectFieldWithFirstOrLastCharacter));if($.applyBreakingRules)this.root.push(new X0("w:applyBreakingRules",$.applyBreakingRules));if($.doNotWrapTextWithPunctuation)this.root.push(new X0("w:doNotWrapTextWithPunct",$.doNotWrapTextWithPunctuation));if($.doNotUseEastAsianBreakRules)this.root.push(new X0("w:doNotUseEastAsianBreakRules",$.doNotUseEastAsianBreakRules));if($.useWord2002TableStyleRules)this.root.push(new X0("w:useWord2002TableStyleRules",$.useWord2002TableStyleRules));if($.growAutofit)this.root.push(new X0("w:growAutofit",$.growAutofit));if($.useFELayout)this.root.push(new X0("w:useFELayout",$.useFELayout));if($.useNormalStyleForList)this.root.push(new X0("w:useNormalStyleForList",$.useNormalStyleForList));if($.doNotUseIndentAsNumberingTabStop)this.root.push(new X0("w:doNotUseIndentAsNumberingTabStop",$.doNotUseIndentAsNumberingTabStop));if($.useAlternateEastAsianLineBreakRules)this.root.push(new X0("w:useAltKinsokuLineBreakRules",$.useAlternateEastAsianLineBreakRules));if($.allowSpaceOfSameStyleInTable)this.root.push(new X0("w:allowSpaceOfSameStyleInTable",$.allowSpaceOfSameStyleInTable));if($.doNotSuppressIndentation)this.root.push(new X0("w:doNotSuppressIndentation",$.doNotSuppressIndentation));if($.doNotAutofitConstrainedTables)this.root.push(new X0("w:doNotAutofitConstrainedTables",$.doNotAutofitConstrainedTables));if($.autofitToFirstFixedWidthCell)this.root.push(new X0("w:autofitToFirstFixedWidthCell",$.autofitToFirstFixedWidthCell));if($.underlineTabInNumberingList)this.root.push(new X0("w:underlineTabInNumList",$.underlineTabInNumberingList));if($.displayHangulFixedWidth)this.root.push(new X0("w:displayHangulFixedWidth",$.displayHangulFixedWidth));if($.splitPgBreakAndParaMark)this.root.push(new X0("w:splitPgBreakAndParaMark",$.splitPgBreakAndParaMark));if($.doNotVerticallyAlignCellWithSp)this.root.push(new X0("w:doNotVertAlignCellWithSp",$.doNotVerticallyAlignCellWithSp));if($.doNotBreakConstrainedForcedTable)this.root.push(new X0("w:doNotBreakConstrainedForcedTable",$.doNotBreakConstrainedForcedTable));if($.ignoreVerticalAlignmentInTextboxes)this.root.push(new X0("w:doNotVertAlignInTxbx",$.ignoreVerticalAlignmentInTextboxes));if($.useAnsiKerningPairs)this.root.push(new X0("w:useAnsiKerningPairs",$.useAnsiKerningPairs));if($.cachedColumnBalance)this.root.push(new X0("w:cachedColBalance",$.cachedColumnBalance))}}class k5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{wpc:"xmlns:wpc",mc:"xmlns:mc",o:"xmlns:o",r:"xmlns:r",m:"xmlns:m",v:"xmlns:v",wp14:"xmlns:wp14",wp:"xmlns:wp",w10:"xmlns:w10",w:"xmlns:w",w14:"xmlns:w14",w15:"xmlns:w15",wpg:"xmlns:wpg",wpi:"xmlns:wpi",wne:"xmlns:wne",wps:"xmlns:wps",Ignorable:"mc:Ignorable"})}}class E5 extends o{constructor($){var U,Y,Z,J,G,X,Q,B;super("w:settings");if(this.root.push(new k5({wpc:"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",mc:"http://schemas.openxmlformats.org/markup-compatibility/2006",o:"urn:schemas-microsoft-com:office:office",r:"http://schemas.openxmlformats.org/officeDocument/2006/relationships",m:"http://schemas.openxmlformats.org/officeDocument/2006/math",v:"urn:schemas-microsoft-com:vml",wp14:"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",wp:"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",w10:"urn:schemas-microsoft-com:office:word",w:"http://schemas.openxmlformats.org/wordprocessingml/2006/main",w14:"http://schemas.microsoft.com/office/word/2010/wordml",w15:"http://schemas.microsoft.com/office/word/2012/wordml",wpg:"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",wpi:"http://schemas.microsoft.com/office/word/2010/wordprocessingInk",wne:"http://schemas.microsoft.com/office/word/2006/wordml",wps:"http://schemas.microsoft.com/office/word/2010/wordprocessingShape",Ignorable:"w14 w15 wp14"})),this.root.push(new X0("w:displayBackgroundShape",!0)),$.trackRevisions!==void 0)this.root.push(new X0("w:trackRevisions",$.trackRevisions));if($.evenAndOddHeaders!==void 0)this.root.push(new X0("w:evenAndOddHeaders",$.evenAndOddHeaders));if($.updateFields!==void 0)this.root.push(new X0("w:updateFields",$.updateFields));if($.defaultTabStop!==void 0)this.root.push(new k2("w:defaultTabStop",$.defaultTabStop));if(((U=$.hyphenation)==null?void 0:U.autoHyphenation)!==void 0)this.root.push(new X0("w:autoHyphenation",$.hyphenation.autoHyphenation));if(((Y=$.hyphenation)==null?void 0:Y.hyphenationZone)!==void 0)this.root.push(new k2("w:hyphenationZone",$.hyphenation.hyphenationZone));if(((Z=$.hyphenation)==null?void 0:Z.consecutiveHyphenLimit)!==void 0)this.root.push(new k2("w:consecutiveHyphenLimit",$.hyphenation.consecutiveHyphenLimit));if(((J=$.hyphenation)==null?void 0:J.doNotHyphenateCaps)!==void 0)this.root.push(new X0("w:doNotHyphenateCaps",$.hyphenation.doNotHyphenateCaps));this.root.push(new O5(R0(W0({},(G=$.compatibility)!=null?G:{}),{version:(B=(Q=(X=$.compatibility)==null?void 0:X.version)!=null?Q:$.compatibilityModeVersion)!=null?B:15})))}}class GU extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{val:"w:val"})}}class S5 extends o{constructor($){super("w:name");this.root.push(new GU({val:$}))}}class v5 extends o{constructor($){super("w:uiPriority");this.root.push(new GU({val:S0($)}))}}class _5 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{type:"w:type",styleId:"w:styleId",default:"w:default",customStyle:"w:customStyle"})}}class KU extends o{constructor($,U){super("w:style");if(this.root.push(new _5($)),U.name)this.root.push(new S5(U.name));if(U.basedOn)this.root.push(new Y2("w:basedOn",U.basedOn));if(U.next)this.root.push(new Y2("w:next",U.next));if(U.link)this.root.push(new Y2("w:link",U.link));if(U.uiPriority!==void 0)this.root.push(new v5(U.uiPriority));if(U.semiHidden!==void 0)this.root.push(new X0("w:semiHidden",U.semiHidden));if(U.unhideWhenUsed!==void 0)this.root.push(new X0("w:unhideWhenUsed",U.unhideWhenUsed));if(U.quickFormat!==void 0)this.root.push(new X0("w:qFormat",U.quickFormat))}}class y2 extends KU{constructor($){super({type:"paragraph",styleId:$.id},$);Y0(this,"paragraphProperties"),Y0(this,"runProperties"),this.paragraphProperties=new Z2($.paragraph),this.runProperties=new J2($.run),this.root.push(this.paragraphProperties),this.root.push(this.runProperties)}}class D2 extends KU{constructor($){super({type:"character",styleId:$.id},W0({uiPriority:99,unhideWhenUsed:!0},$));Y0(this,"runProperties"),this.runProperties=new J2($.run),this.root.push(this.runProperties)}}class H2 extends y2{constructor($){super(W0({basedOn:"Normal",next:"Normal",quickFormat:!0},$))}}class y5 extends H2{constructor($){super(W0({id:"Title",name:"Title"},$))}}class b5 extends H2{constructor($){super(W0({id:"Heading1",name:"Heading 1"},$))}}class g5 extends H2{constructor($){super(W0({id:"Heading2",name:"Heading 2"},$))}}class x5 extends H2{constructor($){super(W0({id:"Heading3",name:"Heading 3"},$))}}class f5 extends H2{constructor($){super(W0({id:"Heading4",name:"Heading 4"},$))}}class h5 extends H2{constructor($){super(W0({id:"Heading5",name:"Heading 5"},$))}}class u5 extends H2{constructor($){super(W0({id:"Heading6",name:"Heading 6"},$))}}class d5 extends H2{constructor($){super(W0({id:"Strong",name:"Strong"},$))}}class c5 extends y2{constructor($){super(W0({id:"ListParagraph",name:"List Paragraph",basedOn:"Normal",quickFormat:!0},$))}}class m5 extends y2{constructor($){super(W0({id:"FootnoteText",name:"footnote text",link:"FootnoteTextChar",basedOn:"Normal",uiPriority:99,semiHidden:!0,unhideWhenUsed:!0,paragraph:{spacing:{after:0,line:240,lineRule:v2.AUTO}},run:{size:20}},$))}}class l5 extends D2{constructor($){super(W0({id:"FootnoteReference",name:"footnote reference",basedOn:"DefaultParagraphFont",semiHidden:!0,run:{superScript:!0}},$))}}class a5 extends D2{constructor($){super(W0({id:"FootnoteTextChar",name:"Footnote Text Char",basedOn:"DefaultParagraphFont",link:"FootnoteText",semiHidden:!0,run:{size:20}},$))}}class p5 extends y2{constructor($){super(W0({id:"EndnoteText",name:"endnote text",link:"EndnoteTextChar",basedOn:"Normal",uiPriority:99,semiHidden:!0,unhideWhenUsed:!0,paragraph:{spacing:{after:0,line:240,lineRule:v2.AUTO}},run:{size:20}},$))}}class i5 extends D2{constructor($){super(W0({id:"EndnoteReference",name:"endnote reference",basedOn:"DefaultParagraphFont",semiHidden:!0,run:{superScript:!0}},$))}}class r5 extends D2{constructor($){super(W0({id:"EndnoteTextChar",name:"Endnote Text Char",basedOn:"DefaultParagraphFont",link:"EndnoteText",semiHidden:!0,run:{size:20}},$))}}class s5 extends D2{constructor($){super(W0({id:"Hyperlink",name:"Hyperlink",basedOn:"DefaultParagraphFont",run:{color:"0563C1",underline:{type:Z$.SINGLE}}},$))}}class B1 extends o{constructor($){super("w:styles");if($.initialStyles)this.root.push($.initialStyles);if($.importedStyles)for(let U of $.importedStyles)this.root.push(U);if($.paragraphStyles)for(let U of $.paragraphStyles)this.root.push(new y2(U));if($.characterStyles)for(let U of $.characterStyles)this.root.push(new D2(U))}}class qU extends o{constructor($){super("w:pPrDefault");this.root.push(new Z2($))}}class XU extends o{constructor($){super("w:rPrDefault");this.root.push(new J2($))}}class VU extends o{constructor($){super("w:docDefaults");Y0(this,"runPropertiesDefaults"),Y0(this,"paragraphPropertiesDefaults"),this.runPropertiesDefaults=new XU($.run),this.paragraphPropertiesDefaults=new qU($.paragraph),this.root.push(this.runPropertiesDefaults),this.root.push(this.paragraphPropertiesDefaults)}}class n5{newInstance($){let U=$8.xml2js($,{compact:!1}),Y;for(let J of U.elements||[])if(J.name==="w:styles")Y=J;if(Y===void 0)throw Error("can not find styles element");let Z=Y.elements||[];return{initialStyles:new i9(Y.attributes),importedStyles:Z.map((J)=>U8(J))}}}class c1{newInstance($={}){var U;return{initialStyles:new o2(["mc","r","w","w14","w15"],"w14 w15"),importedStyles:[new VU((U=$.document)!=null?U:{}),new y5(W0({run:{size:56}},$.title)),new b5(W0({run:{color:"2E74B5",size:32}},$.heading1)),new g5(W0({run:{color:"2E74B5",size:26}},$.heading2)),new x5(W0({run:{color:"1F4D78",size:24}},$.heading3)),new f5(W0({run:{color:"2E74B5",italics:!0}},$.heading4)),new h5(W0({run:{color:"2E74B5"}},$.heading5)),new u5(W0({run:{color:"1F4D78"}},$.heading6)),new d5(W0({run:{bold:!0}},$.strong)),new c5($.listParagraph||{}),new s5($.hyperlink||{}),new l5($.footnoteReference||{}),new m5($.footnoteText||{}),new a5($.footnoteTextChar||{}),new i5($.endnoteReference||{}),new p5($.endnoteText||{}),new r5($.endnoteTextChar||{})]}}}class o5{constructor($){Y0(this,"currentRelationshipId",1),Y0(this,"documentWrapper"),Y0(this,"headers",[]),Y0(this,"footers",[]),Y0(this,"coreProperties"),Y0(this,"numbering"),Y0(this,"media"),Y0(this,"fileRelationships"),Y0(this,"footnotesWrapper"),Y0(this,"endnotesWrapper"),Y0(this,"settings"),Y0(this,"contentTypes"),Y0(this,"customProperties"),Y0(this,"appProperties"),Y0(this,"styles"),Y0(this,"comments"),Y0(this,"fontWrapper");var U,Y,Z,J,G,X,Q,B,F,z,W,k,D;if(this.coreProperties=new gK(R0(W0({},$),{creator:(U=$.creator)!=null?U:"Un-named",revision:(Y=$.revision)!=null?Y:1,lastModifiedBy:(Z=$.lastModifiedBy)!=null?Z:"Un-named"})),this.numbering=new JU($.numbering?$.numbering:{config:[]}),this.comments=new M$((J=$.comments)!=null?J:{children:[]}),this.fileRelationships=new W2,this.customProperties=new cK((G=$.customProperties)!=null?G:[]),this.appProperties=new _K,this.footnotesWrapper=new L5,this.endnotesWrapper=new G5,this.contentTypes=new bK,this.documentWrapper=new $5({background:$.background}),this.settings=new E5({compatibilityModeVersion:$.compatabilityModeVersion,compatibility:$.compatibility,evenAndOddHeaders:$.evenAndOddHeaderAndFooters?!0:!1,trackRevisions:(X=$.features)==null?void 0:X.trackRevisions,updateFields:(Q=$.features)==null?void 0:Q.updateFields,defaultTabStop:$.defaultTabStop,hyphenation:{autoHyphenation:(B=$.hyphenation)==null?void 0:B.autoHyphenation,hyphenationZone:(F=$.hyphenation)==null?void 0:F.hyphenationZone,consecutiveHyphenLimit:(z=$.hyphenation)==null?void 0:z.consecutiveHyphenLimit,doNotHyphenateCaps:(W=$.hyphenation)==null?void 0:W.doNotHyphenateCaps}}),this.media=new w8,$.externalStyles!==void 0){let H=new c1().newInstance((k=$.styles)==null?void 0:k.default),V=new n5().newInstance($.externalStyles);this.styles=new B1(R0(W0({},V),{importedStyles:[...H.importedStyles,...V.importedStyles]}))}else if($.styles){let H=new c1().newInstance($.styles.default);this.styles=new B1(W0(W0({},H),$.styles))}else{let C=new c1;this.styles=new B1(C.newInstance())}this.addDefaultRelationships();for(let C of $.sections)this.addSection(C);if($.footnotes)for(let C in $.footnotes)this.footnotesWrapper.View.createFootNote(parseFloat(C),$.footnotes[C].children);if($.endnotes)for(let C in $.endnotes)this.endnotesWrapper.View.createEndnote(parseFloat(C),$.endnotes[C].children);this.fontWrapper=new R$((D=$.fonts)!=null?D:[])}addSection({headers:$={},footers:U={},children:Y,properties:Z}){this.documentWrapper.View.Body.addSection(R0(W0({},Z),{headerWrapperGroup:{default:$.default?this.createHeader($.default):void 0,first:$.first?this.createHeader($.first):void 0,even:$.even?this.createHeader($.even):void 0},footerWrapperGroup:{default:U.default?this.createFooter(U.default):void 0,first:U.first?this.createFooter(U.first):void 0,even:U.even?this.createFooter(U.even):void 0}}));for(let J of Y)this.documentWrapper.View.add(J)}createHeader($){let U=new YU(this.media,this.currentRelationshipId++);for(let Y of $.options.children)U.add(Y);return this.addHeaderToDocument(U),U}createFooter($){let U=new $U(this.media,this.currentRelationshipId++);for(let Y of $.options.children)U.add(Y);return this.addFooterToDocument(U),U}addHeaderToDocument($,U=E2.DEFAULT){this.headers.push({header:$,type:U}),this.documentWrapper.Relationships.addRelationship($.View.ReferenceId,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",`header${this.headers.length}.xml`),this.contentTypes.addHeader(this.headers.length)}addFooterToDocument($,U=E2.DEFAULT){this.footers.push({footer:$,type:U}),this.documentWrapper.Relationships.addRelationship($.View.ReferenceId,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",`footer${this.footers.length}.xml`),this.contentTypes.addFooter(this.footers.length)}addDefaultRelationships(){this.fileRelationships.addRelationship(1,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument","word/document.xml"),this.fileRelationships.addRelationship(2,"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties","docProps/core.xml"),this.fileRelationships.addRelationship(3,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties","docProps/app.xml"),this.fileRelationships.addRelationship(4,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties","docProps/custom.xml"),this.documentWrapper.Relationships.addRelationship(this.currentRelationshipId++,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles","styles.xml"),this.documentWrapper.Relationships.addRelationship(this.currentRelationshipId++,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering","numbering.xml"),this.documentWrapper.Relationships.addRelationship(this.currentRelationshipId++,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes","footnotes.xml"),this.documentWrapper.Relationships.addRelationship(this.currentRelationshipId++,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes","endnotes.xml"),this.documentWrapper.Relationships.addRelationship(this.currentRelationshipId++,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings","settings.xml"),this.documentWrapper.Relationships.addRelationship(this.currentRelationshipId++,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments","comments.xml")}get Document(){return this.documentWrapper}get Styles(){return this.styles}get CoreProperties(){return this.coreProperties}get Numbering(){return this.numbering}get Media(){return this.media}get FileRelationships(){return this.fileRelationships}get Headers(){return this.headers.map(($)=>$.header)}get Footers(){return this.footers.map(($)=>$.footer)}get ContentTypes(){return this.contentTypes}get CustomProperties(){return this.customProperties}get AppProperties(){return this.appProperties}get FootNotes(){return this.footnotesWrapper}get Endnotes(){return this.endnotesWrapper}get Settings(){return this.settings}get Comments(){return this.comments}get FontTable(){return this.fontWrapper}}class t5 extends o{constructor($={}){super("w:instrText");Y0(this,"properties"),this.properties=$,this.root.push(new x0({space:g0.PRESERVE}));let U="TOC";if(this.properties.captionLabel)U=`${U} \\a "${this.properties.captionLabel}"`;if(this.properties.entriesFromBookmark)U=`${U} \\b "${this.properties.entriesFromBookmark}"`;if(this.properties.captionLabelIncludingNumbers)U=`${U} \\c "${this.properties.captionLabelIncludingNumbers}"`;if(this.properties.sequenceAndPageNumbersSeparator)U=`${U} \\d "${this.properties.sequenceAndPageNumbersSeparator}"`;if(this.properties.tcFieldIdentifier)U=`${U} \\f "${this.properties.tcFieldIdentifier}"`;if(this.properties.hyperlink)U=`${U} \\h`;if(this.properties.tcFieldLevelRange)U=`${U} \\l "${this.properties.tcFieldLevelRange}"`;if(this.properties.pageNumbersEntryLevelsRange)U=`${U} \\n "${this.properties.pageNumbersEntryLevelsRange}"`;if(this.properties.headingStyleRange)U=`${U} \\o "${this.properties.headingStyleRange}"`;if(this.properties.entryAndPageNumberSeparator)U=`${U} \\p "${this.properties.entryAndPageNumberSeparator}"`;if(this.properties.seqFieldIdentifierForPrefix)U=`${U} \\s "${this.properties.seqFieldIdentifierForPrefix}"`;if(this.properties.stylesWithLevels&&this.properties.stylesWithLevels.length){let Y=this.properties.stylesWithLevels.map((Z)=>`${Z.styleName},${Z.level}`).join(",");U=`${U} \\t "${Y}"`}if(this.properties.useAppliedParagraphOutlineLevel)U=`${U} \\u`;if(this.properties.preserveTabInEntries)U=`${U} \\w`;if(this.properties.preserveNewLineInEntries)U=`${U} \\x`;if(this.properties.hideTabAndPageNumbersInWebView)U=`${U} \\z`;this.root.push(U)}}class BU extends o{constructor(){super("w:sdtContent")}}class LU extends o{constructor($){super("w:sdtPr");if($)this.root.push(new Y2("w:alias",$))}}class e5 extends r2{constructor($="Table of Contents",U={}){var Y=U,{contentChildren:Z=[],cachedEntries:J=[],beginDirty:G=!0}=Y,X=oZ(Y,["contentChildren","cachedEntries","beginDirty"]);super("w:sdt");this.root.push(new LU($));let Q=new BU,B=[new C0({children:[$2(G),new t5(X),I2()]})],F=[new C0({children:[U2()]})];if(J!==void 0&&J.length>0){let{stylesWithLevels:W}=X,k=J.map((C,H)=>{var O,V;let j=this.buildCachedContentParagraphChild(C,X),M=(V=(O=W==null?void 0:W.find((A)=>A.level===C.level))==null?void 0:O.styleName)!=null?V:`TOC${C.level}`,L=H===0?[...B,j]:H===J.length-1?[j,...F]:[j];return new h0({style:M,tabStops:this.getTabStopsForLevel(C.level),children:L})}),D=k;if(J.length<=1)D=[...k,new h0({children:F})];for(let C of D)Q.addChildElement(C)}else{let W=new h0({children:B});Q.addChildElement(W);for(let D of Z)Q.addChildElement(D);let k=new h0({children:F});Q.addChildElement(k)}this.root.push(Q)}getTabStopsForLevel($,U=9025){return[{type:"clear",position:U+1-($-1)*240},{type:"right",position:U,leader:"dot"}]}buildCachedContentRun($,U){var Y,Z;return new C0({style:(U==null?void 0:U.hyperlink)&&$.href!==void 0?"IndexLink":void 0,children:[new a2({text:$.title}),new w$,new a2({text:(Z=(Y=$.page)==null?void 0:Y.toString())!=null?Z:""})]})}buildCachedContentParagraphChild($,U){let Y=this.buildCachedContentRun($,U);if((U==null?void 0:U.hyperlink)&&$.href!==void 0)return new j$({anchor:$.href,children:[Y]});return Y}}class $7{constructor($,U){Y0(this,"styleName"),Y0(this,"level"),this.styleName=$,this.level=U}}class U7{constructor($={children:[]}){Y0(this,"options"),this.options=$}}class Y7{constructor($={children:[]}){Y0(this,"options"),this.options=$}}class MU extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"w:id"})}}class IU extends o{constructor($){super("w:footnoteReference");this.root.push(new MU({id:$}))}}class Z7 extends C0{constructor($){super({style:"FootnoteReference"});this.root.push(new IU($))}}class wU extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{id:"w:id"})}}class WU extends o{constructor($){super("w:endnoteReference");this.root.push(new wU({id:$}))}}class Q7 extends C0{constructor($){super({style:"EndnoteReference"});this.root.push(new WU($))}}class _9 extends I0{constructor(){super(...arguments);Y0(this,"xmlKeys",{val:"w14:val",symbolfont:"w14:font"})}}class L1 extends o{constructor($,U,Y){super($);if(Y)this.root.push(new _9({val:DQ(U),symbolfont:Y}));else this.root.push(new _9({val:U}))}}class HU extends o{constructor($){var U,Y,Z,J,G,X,Q,B;super("w14:checkbox");Y0(this,"DEFAULT_UNCHECKED_SYMBOL","2610"),Y0(this,"DEFAULT_CHECKED_SYMBOL","2612"),Y0(this,"DEFAULT_FONT","MS Gothic");let F=($==null?void 0:$.checked)?"1":"0",z,W;this.root.push(new L1("w14:checked",F)),z=((U=$==null?void 0:$.checkedState)==null?void 0:U.value)?(Y=$==null?void 0:$.checkedState)==null?void 0:Y.value:this.DEFAULT_CHECKED_SYMBOL,W=((Z=$==null?void 0:$.checkedState)==null?void 0:Z.font)?(J=$==null?void 0:$.checkedState)==null?void 0:J.font:this.DEFAULT_FONT,this.root.push(new L1("w14:checkedState",z,W)),z=((G=$==null?void 0:$.uncheckedState)==null?void 0:G.value)?(X=$==null?void 0:$.uncheckedState)==null?void 0:X.value:this.DEFAULT_UNCHECKED_SYMBOL,W=((Q=$==null?void 0:$.uncheckedState)==null?void 0:Q.font)?(B=$==null?void 0:$.uncheckedState)==null?void 0:B.font:this.DEFAULT_FONT,this.root.push(new L1("w14:uncheckedState",z,W))}}class J7 extends o{constructor($){var U,Y,Z,J;super("w:sdt");Y0(this,"DEFAULT_UNCHECKED_SYMBOL","2610"),Y0(this,"DEFAULT_CHECKED_SYMBOL","2612"),Y0(this,"DEFAULT_FONT","MS Gothic");let G=new LU($==null?void 0:$.alias);G.addChildElement(new HU($)),this.root.push(G);let X=new BU,Q=(U=$==null?void 0:$.checkedState)==null?void 0:U.font,B=(Y=$==null?void 0:$.checkedState)==null?void 0:Y.value,F=(Z=$==null?void 0:$.uncheckedState)==null?void 0:Z.font,z=(J=$==null?void 0:$.uncheckedState)==null?void 0:J.value,W,k;if($==null?void 0:$.checked)W=Q?Q:this.DEFAULT_FONT,k=B?B:this.DEFAULT_CHECKED_SYMBOL;else W=F?F:this.DEFAULT_FONT,k=z?z:this.DEFAULT_UNCHECKED_SYMBOL;let D=new G$({char:k,symbolfont:W});X.addChildElement(D),this.root.push(X)}}var iV=({shape:$})=>new B0({name:"w:pict",children:[$]}),rV=({children:$=[]})=>new B0({name:"w:txbxContent",children:$}),sV=({style:$,children:U,inset:Y})=>new B0({name:"v:textbox",attributes:{style:{key:"style",value:$},insetMode:{key:"insetmode",value:Y?"custom":"auto"},inset:{key:"inset",value:Y?`${Y.left}, ${Y.top}, ${Y.right}, ${Y.bottom}`:void 0}},children:[rV({children:U})]}),nV="#_x0000_t202",oV={flip:"flip",height:"height",left:"left",marginBottom:"margin-bottom",marginLeft:"margin-left",marginRight:"margin-right",marginTop:"margin-top",positionHorizontal:"mso-position-horizontal",positionHorizontalRelative:"mso-position-horizontal-relative",positionVertical:"mso-position-vertical",positionVerticalRelative:"mso-position-vertical-relative",wrapDistanceBottom:"mso-wrap-distance-bottom",wrapDistanceLeft:"mso-wrap-distance-left",wrapDistanceRight:"mso-wrap-distance-right",wrapDistanceTop:"mso-wrap-distance-top",wrapEdited:"mso-wrap-edited",wrapStyle:"mso-wrap-style",position:"position",rotation:"rotation",top:"top",visibility:"visibility",width:"width",zIndex:"z-index"},tV=($)=>$?Object.entries($).map(([U,Y])=>`${oV[U]}:${Y}`).join(";"):void 0,eV=({id:$,children:U,type:Y=nV,style:Z})=>new B0({name:"v:shape",attributes:{id:{key:"id",value:$},type:{key:"type",value:Y},style:{key:"style",value:tV(Z)}},children:[sV({style:"mso-fit-shape-to-text:t;",children:U})]});class G7 extends r2{constructor($){var U=$,{style:Y,children:Z}=U,J=oZ(U,["style","children"]);super("w:p");this.root.push(new Z2(J)),this.root.push(iV({shape:eV({children:Z,id:R1(),style:Y})}))}}var $B=m9();function y1($){throw Error('Could not dynamically require "'+$+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var I9={exports:{}},uZ;function UB(){if(uZ)return I9.exports;return uZ=1,function($,U){(function(Y){$.exports=Y()})(function(){return function Y(Z,J,G){function X(F,z){if(!J[F]){if(!Z[F]){var W=typeof y1=="function"&&y1;if(!z&&W)return W(F,!0);if(Q)return Q(F,!0);var k=Error("Cannot find module '"+F+"'");throw k.code="MODULE_NOT_FOUND",k}var D=J[F]={exports:{}};Z[F][0].call(D.exports,function(C){var H=Z[F][1][C];return X(H||C)},D,D.exports,Y,Z,J,G)}return J[F].exports}for(var Q=typeof y1=="function"&&y1,B=0;B>2,D=(3&F)<<4|z>>4,C=1>6:64,H=2>4,z=(15&k)<<4|(D=Q.indexOf(B.charAt(H++)))>>2,W=(3&D)<<6|(C=Q.indexOf(B.charAt(H++))),j[O++]=F,D!==64&&(j[O++]=z),C!==64&&(j[O++]=W);return j}},{"./support":30,"./utils":32}],2:[function(Y,Z,J){var G=Y("./external"),X=Y("./stream/DataWorker"),Q=Y("./stream/Crc32Probe"),B=Y("./stream/DataLengthProbe");function F(z,W,k,D,C){this.compressedSize=z,this.uncompressedSize=W,this.crc32=k,this.compression=D,this.compressedContent=C}F.prototype={getContentWorker:function(){var z=new X(G.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new B("data_length")),W=this;return z.on("end",function(){if(this.streamInfo.data_length!==W.uncompressedSize)throw Error("Bug : uncompressed data size mismatch")}),z},getCompressedWorker:function(){return new X(G.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},F.createWorkerFrom=function(z,W,k){return z.pipe(new Q).pipe(new B("uncompressedSize")).pipe(W.compressWorker(k)).pipe(new B("compressedSize")).withStreamInfo("compression",W)},Z.exports=F},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(Y,Z,J){var G=Y("./stream/GenericWorker");J.STORE={magic:"\x00\x00",compressWorker:function(){return new G("STORE compression")},uncompressWorker:function(){return new G("STORE decompression")}},J.DEFLATE=Y("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(Y,Z,J){var G=Y("./utils"),X=function(){for(var Q,B=[],F=0;F<256;F++){Q=F;for(var z=0;z<8;z++)Q=1&Q?3988292384^Q>>>1:Q>>>1;B[F]=Q}return B}();Z.exports=function(Q,B){return Q!==void 0&&Q.length?G.getTypeOf(Q)!=="string"?function(F,z,W,k){var D=X,C=k+W;F^=-1;for(var H=k;H>>8^D[255&(F^z[H])];return-1^F}(0|B,Q,Q.length,0):function(F,z,W,k){var D=X,C=k+W;F^=-1;for(var H=k;H>>8^D[255&(F^z.charCodeAt(H))];return-1^F}(0|B,Q,Q.length,0):0}},{"./utils":32}],5:[function(Y,Z,J){J.base64=!1,J.binary=!1,J.dir=!1,J.createFolders=!0,J.date=null,J.compression=null,J.compressionOptions=null,J.comment=null,J.unixPermissions=null,J.dosPermissions=null},{}],6:[function(Y,Z,J){var G=null;G=typeof Promise<"u"?Promise:Y("lie"),Z.exports={Promise:G}},{lie:37}],7:[function(Y,Z,J){var G=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Uint32Array<"u",X=Y("pako"),Q=Y("./utils"),B=Y("./stream/GenericWorker"),F=G?"uint8array":"array";function z(W,k){B.call(this,"FlateWorker/"+W),this._pako=null,this._pakoAction=W,this._pakoOptions=k,this.meta={}}J.magic="\b\x00",Q.inherits(z,B),z.prototype.processChunk=function(W){this.meta=W.meta,this._pako===null&&this._createPako(),this._pako.push(Q.transformTo(F,W.data),!1)},z.prototype.flush=function(){B.prototype.flush.call(this),this._pako===null&&this._createPako(),this._pako.push([],!0)},z.prototype.cleanUp=function(){B.prototype.cleanUp.call(this),this._pako=null},z.prototype._createPako=function(){this._pako=new X[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var W=this;this._pako.onData=function(k){W.push({data:k,meta:W.meta})}},J.compressWorker=function(W){return new z("Deflate",W)},J.uncompressWorker=function(){return new z("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(Y,Z,J){function G(D,C){var H,O="";for(H=0;H>>=8;return O}function X(D,C,H,O,V,j){var M,L,A=D.file,y=D.compression,g=j!==F.utf8encode,d=Q.transformTo("string",j(A.name)),E=Q.transformTo("string",F.utf8encode(A.name)),s=A.comment,V0=Q.transformTo("string",j(s)),S=Q.transformTo("string",F.utf8encode(s)),h=E.length!==A.name.length,N=S.length!==s.length,a="",$0="",m="",J0=A.dir,U0=A.date,L0={crc32:0,compressedSize:0,uncompressedSize:0};C&&!H||(L0.crc32=D.crc32,L0.compressedSize=D.compressedSize,L0.uncompressedSize=D.uncompressedSize);var i=0;C&&(i|=8),g||!h&&!N||(i|=2048);var _=0,r=0;J0&&(_|=16),V==="UNIX"?(r=798,_|=function(Z0,p){var P=Z0;return Z0||(P=p?16893:33204),(65535&P)<<16}(A.unixPermissions,J0)):(r=20,_|=function(Z0){return 63&(Z0||0)}(A.dosPermissions)),M=U0.getUTCHours(),M<<=6,M|=U0.getUTCMinutes(),M<<=5,M|=U0.getUTCSeconds()/2,L=U0.getUTCFullYear()-1980,L<<=4,L|=U0.getUTCMonth()+1,L<<=5,L|=U0.getUTCDate(),h&&($0=G(1,1)+G(z(d),4)+E,a+="up"+G($0.length,2)+$0),N&&(m=G(1,1)+G(z(V0),4)+S,a+="uc"+G(m.length,2)+m);var n="";return n+=` -\x00`,n+=G(i,2),n+=y.magic,n+=G(M,2),n+=G(L,2),n+=G(L0.crc32,4),n+=G(L0.compressedSize,4),n+=G(L0.uncompressedSize,4),n+=G(d.length,2),n+=G(a.length,2),{fileRecord:W.LOCAL_FILE_HEADER+n+d+a,dirRecord:W.CENTRAL_FILE_HEADER+G(r,2)+n+G(V0.length,2)+"\x00\x00\x00\x00"+G(_,4)+G(O,4)+d+a+V0}}var Q=Y("../utils"),B=Y("../stream/GenericWorker"),F=Y("../utf8"),z=Y("../crc32"),W=Y("../signature");function k(D,C,H,O){B.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=C,this.zipPlatform=H,this.encodeFileName=O,this.streamFiles=D,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}Q.inherits(k,B),k.prototype.push=function(D){var C=D.meta.percent||0,H=this.entriesCount,O=this._sources.length;this.accumulate?this.contentBuffer.push(D):(this.bytesWritten+=D.data.length,B.prototype.push.call(this,{data:D.data,meta:{currentFile:this.currentFile,percent:H?(C+100*(H-O-1))/H:100}}))},k.prototype.openedSource=function(D){this.currentSourceOffset=this.bytesWritten,this.currentFile=D.file.name;var C=this.streamFiles&&!D.file.dir;if(C){var H=X(D,C,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:H.fileRecord,meta:{percent:0}})}else this.accumulate=!0},k.prototype.closedSource=function(D){this.accumulate=!1;var C=this.streamFiles&&!D.file.dir,H=X(D,C,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(H.dirRecord),C)this.push({data:function(O){return W.DATA_DESCRIPTOR+G(O.crc32,4)+G(O.compressedSize,4)+G(O.uncompressedSize,4)}(D),meta:{percent:100}});else for(this.push({data:H.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},k.prototype.flush=function(){for(var D=this.bytesWritten,C=0;C=this.index;B--)F=(F<<8)+this.byteAt(B);return this.index+=Q,F},readString:function(Q){return G.transformTo("string",this.readData(Q))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var Q=this.readInt(4);return new Date(Date.UTC(1980+(Q>>25&127),(Q>>21&15)-1,Q>>16&31,Q>>11&31,Q>>5&63,(31&Q)<<1))}},Z.exports=X},{"../utils":32}],19:[function(Y,Z,J){var G=Y("./Uint8ArrayReader");function X(Q){G.call(this,Q)}Y("../utils").inherits(X,G),X.prototype.readData=function(Q){this.checkOffset(Q);var B=this.data.slice(this.zero+this.index,this.zero+this.index+Q);return this.index+=Q,B},Z.exports=X},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(Y,Z,J){var G=Y("./DataReader");function X(Q){G.call(this,Q)}Y("../utils").inherits(X,G),X.prototype.byteAt=function(Q){return this.data.charCodeAt(this.zero+Q)},X.prototype.lastIndexOfSignature=function(Q){return this.data.lastIndexOf(Q)-this.zero},X.prototype.readAndCheckSignature=function(Q){return Q===this.readData(4)},X.prototype.readData=function(Q){this.checkOffset(Q);var B=this.data.slice(this.zero+this.index,this.zero+this.index+Q);return this.index+=Q,B},Z.exports=X},{"../utils":32,"./DataReader":18}],21:[function(Y,Z,J){var G=Y("./ArrayReader");function X(Q){G.call(this,Q)}Y("../utils").inherits(X,G),X.prototype.readData=function(Q){if(this.checkOffset(Q),Q===0)return new Uint8Array(0);var B=this.data.subarray(this.zero+this.index,this.zero+this.index+Q);return this.index+=Q,B},Z.exports=X},{"../utils":32,"./ArrayReader":17}],22:[function(Y,Z,J){var G=Y("../utils"),X=Y("../support"),Q=Y("./ArrayReader"),B=Y("./StringReader"),F=Y("./NodeBufferReader"),z=Y("./Uint8ArrayReader");Z.exports=function(W){var k=G.getTypeOf(W);return G.checkSupport(k),k!=="string"||X.uint8array?k==="nodebuffer"?new F(W):X.uint8array?new z(G.transformTo("uint8array",W)):new Q(G.transformTo("array",W)):new B(W)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(Y,Z,J){J.LOCAL_FILE_HEADER="PK\x03\x04",J.CENTRAL_FILE_HEADER="PK\x01\x02",J.CENTRAL_DIRECTORY_END="PK\x05\x06",J.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK\x06\x07",J.ZIP64_CENTRAL_DIRECTORY_END="PK\x06\x06",J.DATA_DESCRIPTOR="PK\x07\b"},{}],24:[function(Y,Z,J){var G=Y("./GenericWorker"),X=Y("../utils");function Q(B){G.call(this,"ConvertWorker to "+B),this.destType=B}X.inherits(Q,G),Q.prototype.processChunk=function(B){this.push({data:X.transformTo(this.destType,B.data),meta:B.meta})},Z.exports=Q},{"../utils":32,"./GenericWorker":28}],25:[function(Y,Z,J){var G=Y("./GenericWorker"),X=Y("../crc32");function Q(){G.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}Y("../utils").inherits(Q,G),Q.prototype.processChunk=function(B){this.streamInfo.crc32=X(B.data,this.streamInfo.crc32||0),this.push(B)},Z.exports=Q},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(Y,Z,J){var G=Y("../utils"),X=Y("./GenericWorker");function Q(B){X.call(this,"DataLengthProbe for "+B),this.propName=B,this.withStreamInfo(B,0)}G.inherits(Q,X),Q.prototype.processChunk=function(B){if(B){var F=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=F+B.data.length}X.prototype.processChunk.call(this,B)},Z.exports=Q},{"../utils":32,"./GenericWorker":28}],27:[function(Y,Z,J){var G=Y("../utils"),X=Y("./GenericWorker");function Q(B){X.call(this,"DataWorker");var F=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,B.then(function(z){F.dataIsReady=!0,F.data=z,F.max=z&&z.length||0,F.type=G.getTypeOf(z),F.isPaused||F._tickAndRepeat()},function(z){F.error(z)})}G.inherits(Q,X),Q.prototype.cleanUp=function(){X.prototype.cleanUp.call(this),this.data=null},Q.prototype.resume=function(){return!!X.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,G.delay(this._tickAndRepeat,[],this)),!0)},Q.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(G.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},Q.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var B=null,F=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":B=this.data.substring(this.index,F);break;case"uint8array":B=this.data.subarray(this.index,F);break;case"array":case"nodebuffer":B=this.data.slice(this.index,F)}return this.index=F,this.push({data:B,meta:{percent:this.max?this.index/this.max*100:0}})},Z.exports=Q},{"../utils":32,"./GenericWorker":28}],28:[function(Y,Z,J){function G(X){this.name=X||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}G.prototype={push:function(X){this.emit("data",X)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(X){this.emit("error",X)}return!0},error:function(X){return!this.isFinished&&(this.isPaused?this.generatedError=X:(this.isFinished=!0,this.emit("error",X),this.previous&&this.previous.error(X),this.cleanUp()),!0)},on:function(X,Q){return this._listeners[X].push(Q),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(X,Q){if(this._listeners[X])for(var B=0;B "+X:X}},Z.exports=G},{}],29:[function(Y,Z,J){var G=Y("../utils"),X=Y("./ConvertWorker"),Q=Y("./GenericWorker"),B=Y("../base64"),F=Y("../support"),z=Y("../external"),W=null;if(F.nodestream)try{W=Y("../nodejs/NodejsStreamOutputAdapter")}catch(C){}function k(C,H){return new z.Promise(function(O,V){var j=[],M=C._internalType,L=C._outputType,A=C._mimeType;C.on("data",function(y,g){j.push(y),H&&H(g)}).on("error",function(y){j=[],V(y)}).on("end",function(){try{var y=function(g,d,E){switch(g){case"blob":return G.newBlob(G.transformTo("arraybuffer",d),E);case"base64":return B.encode(d);default:return G.transformTo(g,d)}}(L,function(g,d){var E,s=0,V0=null,S=0;for(E=0;E"u")J.blob=!1;else{var G=new ArrayBuffer(0);try{J.blob=new Blob([G],{type:"application/zip"}).size===0}catch(Q){try{var X=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);X.append(G),J.blob=X.getBlob("application/zip").size===0}catch(B){J.blob=!1}}}try{J.nodestream=!!Y("readable-stream").Readable}catch(Q){J.nodestream=!1}},{"readable-stream":16}],31:[function(Y,Z,J){for(var G=Y("./utils"),X=Y("./support"),Q=Y("./nodejsUtils"),B=Y("./stream/GenericWorker"),F=Array(256),z=0;z<256;z++)F[z]=252<=z?6:248<=z?5:240<=z?4:224<=z?3:192<=z?2:1;F[254]=F[254]=1;function W(){B.call(this,"utf-8 decode"),this.leftOver=null}function k(){B.call(this,"utf-8 encode")}J.utf8encode=function(D){return X.nodebuffer?Q.newBufferFrom(D,"utf-8"):function(C){var H,O,V,j,M,L=C.length,A=0;for(j=0;j>>6:(O<65536?H[M++]=224|O>>>12:(H[M++]=240|O>>>18,H[M++]=128|O>>>12&63),H[M++]=128|O>>>6&63),H[M++]=128|63&O);return H}(D)},J.utf8decode=function(D){return X.nodebuffer?G.transformTo("nodebuffer",D).toString("utf-8"):function(C){var H,O,V,j,M=C.length,L=Array(2*M);for(H=O=0;H>10&1023,L[O++]=56320|1023&V)}return L.length!==O&&(L.subarray?L=L.subarray(0,O):L.length=O),G.applyFromCharCode(L)}(D=G.transformTo(X.uint8array?"uint8array":"array",D))},G.inherits(W,B),W.prototype.processChunk=function(D){var C=G.transformTo(X.uint8array?"uint8array":"array",D.data);if(this.leftOver&&this.leftOver.length){if(X.uint8array){var H=C;(C=new Uint8Array(H.length+this.leftOver.length)).set(this.leftOver,0),C.set(H,this.leftOver.length)}else C=this.leftOver.concat(C);this.leftOver=null}var O=function(j,M){var L;for((M=M||j.length)>j.length&&(M=j.length),L=M-1;0<=L&&(192&j[L])==128;)L--;return L<0?M:L===0?M:L+F[j[L]]>M?L:M}(C),V=C;O!==C.length&&(X.uint8array?(V=C.subarray(0,O),this.leftOver=C.subarray(O,C.length)):(V=C.slice(0,O),this.leftOver=C.slice(O,C.length))),this.push({data:J.utf8decode(V),meta:D.meta})},W.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:J.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},J.Utf8DecodeWorker=W,G.inherits(k,B),k.prototype.processChunk=function(D){this.push({data:J.utf8encode(D.data),meta:D.meta})},J.Utf8EncodeWorker=k},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(Y,Z,J){var G=Y("./support"),X=Y("./base64"),Q=Y("./nodejsUtils"),B=Y("./external");function F(H){return H}function z(H,O){for(var V=0;V>8;this.dir=!!(16&this.externalFileAttributes),D==0&&(this.dosPermissions=63&this.externalFileAttributes),D==3&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||this.fileNameStr.slice(-1)!=="/"||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var D=G(this.extraFields[1].value);this.uncompressedSize===X.MAX_VALUE_32BITS&&(this.uncompressedSize=D.readInt(8)),this.compressedSize===X.MAX_VALUE_32BITS&&(this.compressedSize=D.readInt(8)),this.localHeaderOffset===X.MAX_VALUE_32BITS&&(this.localHeaderOffset=D.readInt(8)),this.diskNumberStart===X.MAX_VALUE_32BITS&&(this.diskNumberStart=D.readInt(4))}},readExtraFields:function(D){var C,H,O,V=D.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});D.index+4>>6:(D<65536?k[O++]=224|D>>>12:(k[O++]=240|D>>>18,k[O++]=128|D>>>12&63),k[O++]=128|D>>>6&63),k[O++]=128|63&D);return k},J.buf2binstring=function(W){return z(W,W.length)},J.binstring2buf=function(W){for(var k=new G.Buf8(W.length),D=0,C=k.length;D>10&1023,j[C++]=56320|1023&H)}return z(j,C)},J.utf8border=function(W,k){var D;for((k=k||W.length)>W.length&&(k=W.length),D=k-1;0<=D&&(192&W[D])==128;)D--;return D<0?k:D===0?k:D+B[W[D]]>k?D:k}},{"./common":41}],43:[function(Y,Z,J){Z.exports=function(G,X,Q,B){for(var F=65535&G|0,z=G>>>16&65535|0,W=0;Q!==0;){for(Q-=W=2000>>1:X>>>1;Q[B]=X}return Q}();Z.exports=function(X,Q,B,F){var z=G,W=F+B;X^=-1;for(var k=F;k>>8^z[255&(X^Q[k])];return-1^X}},{}],46:[function(Y,Z,J){var G,X=Y("../utils/common"),Q=Y("./trees"),B=Y("./adler32"),F=Y("./crc32"),z=Y("./messages"),W=0,k=4,D=0,C=-2,H=-1,O=4,V=2,j=8,M=9,L=286,A=30,y=19,g=2*L+1,d=15,E=3,s=258,V0=s+E+1,S=42,h=113,N=1,a=2,$0=3,m=4;function J0(I,t){return I.msg=z[t],t}function U0(I){return(I<<1)-(4I.avail_out&&(T=I.avail_out),T!==0&&(X.arraySet(I.output,t.pending_buf,t.pending_out,T,I.next_out),I.next_out+=T,t.pending_out+=T,I.total_out+=T,I.avail_out-=T,t.pending-=T,t.pending===0&&(t.pending_out=0))}function _(I,t){Q._tr_flush_block(I,0<=I.block_start?I.block_start:-1,I.strstart-I.block_start,t),I.block_start=I.strstart,i(I.strm)}function r(I,t){I.pending_buf[I.pending++]=t}function n(I,t){I.pending_buf[I.pending++]=t>>>8&255,I.pending_buf[I.pending++]=255&t}function Z0(I,t){var T,K,q=I.max_chain_length,w=I.strstart,x=I.prev_length,l=I.nice_match,u=I.strstart>I.w_size-V0?I.strstart-(I.w_size-V0):0,Q0=I.window,q0=I.w_mask,K0=I.prev,M0=I.strstart+s,w0=Q0[w+x-1],H0=Q0[w+x];I.prev_length>=I.good_match&&(q>>=2),l>I.lookahead&&(l=I.lookahead);do if(Q0[(T=t)+x]===H0&&Q0[T+x-1]===w0&&Q0[T]===Q0[w]&&Q0[++T]===Q0[w+1]){w+=2,T++;do;while(Q0[++w]===Q0[++T]&&Q0[++w]===Q0[++T]&&Q0[++w]===Q0[++T]&&Q0[++w]===Q0[++T]&&Q0[++w]===Q0[++T]&&Q0[++w]===Q0[++T]&&Q0[++w]===Q0[++T]&&Q0[++w]===Q0[++T]&&wu&&--q!=0);return x<=I.lookahead?x:I.lookahead}function p(I){var t,T,K,q,w,x,l,u,Q0,q0,K0=I.w_size;do{if(q=I.window_size-I.lookahead-I.strstart,I.strstart>=K0+(K0-V0)){for(X.arraySet(I.window,I.window,K0,K0,0),I.match_start-=K0,I.strstart-=K0,I.block_start-=K0,t=T=I.hash_size;K=I.head[--t],I.head[t]=K0<=K?K-K0:0,--T;);for(t=T=K0;K=I.prev[--t],I.prev[t]=K0<=K?K-K0:0,--T;);q+=K0}if(I.strm.avail_in===0)break;if(x=I.strm,l=I.window,u=I.strstart+I.lookahead,Q0=q,q0=void 0,q0=x.avail_in,Q0=E)for(w=I.strstart-I.insert,I.ins_h=I.window[w],I.ins_h=(I.ins_h<=E&&(I.ins_h=(I.ins_h<=E)if(K=Q._tr_tally(I,I.strstart-I.match_start,I.match_length-E),I.lookahead-=I.match_length,I.match_length<=I.max_lazy_match&&I.lookahead>=E){for(I.match_length--;I.strstart++,I.ins_h=(I.ins_h<=E&&(I.ins_h=(I.ins_h<=E&&I.match_length<=I.prev_length){for(q=I.strstart+I.lookahead-E,K=Q._tr_tally(I,I.strstart-1-I.prev_match,I.prev_length-E),I.lookahead-=I.prev_length-1,I.prev_length-=2;++I.strstart<=q&&(I.ins_h=(I.ins_h<I.pending_buf_size-5&&(T=I.pending_buf_size-5);;){if(I.lookahead<=1){if(p(I),I.lookahead===0&&t===W)return N;if(I.lookahead===0)break}I.strstart+=I.lookahead,I.lookahead=0;var K=I.block_start+T;if((I.strstart===0||I.strstart>=K)&&(I.lookahead=I.strstart-K,I.strstart=K,_(I,!1),I.strm.avail_out===0))return N;if(I.strstart-I.block_start>=I.w_size-V0&&(_(I,!1),I.strm.avail_out===0))return N}return I.insert=0,t===k?(_(I,!0),I.strm.avail_out===0?$0:m):(I.strstart>I.block_start&&(_(I,!1),I.strm.avail_out),N)}),new c(4,4,8,4,P),new c(4,5,16,8,P),new c(4,6,32,32,P),new c(4,4,16,16,R),new c(8,16,32,32,R),new c(8,16,128,128,R),new c(8,32,128,256,R),new c(32,128,258,1024,R),new c(32,258,258,4096,R)],J.deflateInit=function(I,t){return e(I,t,j,15,8,0)},J.deflateInit2=e,J.deflateReset=b,J.deflateResetKeep=v,J.deflateSetHeader=function(I,t){return I&&I.state?I.state.wrap!==2?C:(I.state.gzhead=t,D):C},J.deflate=function(I,t){var T,K,q,w;if(!I||!I.state||5>8&255),r(K,K.gzhead.time>>16&255),r(K,K.gzhead.time>>24&255),r(K,K.level===9?2:2<=K.strategy||K.level<2?4:0),r(K,255&K.gzhead.os),K.gzhead.extra&&K.gzhead.extra.length&&(r(K,255&K.gzhead.extra.length),r(K,K.gzhead.extra.length>>8&255)),K.gzhead.hcrc&&(I.adler=F(I.adler,K.pending_buf,K.pending,0)),K.gzindex=0,K.status=69):(r(K,0),r(K,0),r(K,0),r(K,0),r(K,0),r(K,K.level===9?2:2<=K.strategy||K.level<2?4:0),r(K,3),K.status=h);else{var x=j+(K.w_bits-8<<4)<<8;x|=(2<=K.strategy||K.level<2?0:K.level<6?1:K.level===6?2:3)<<6,K.strstart!==0&&(x|=32),x+=31-x%31,K.status=h,n(K,x),K.strstart!==0&&(n(K,I.adler>>>16),n(K,65535&I.adler)),I.adler=1}if(K.status===69)if(K.gzhead.extra){for(q=K.pending;K.gzindex<(65535&K.gzhead.extra.length)&&(K.pending!==K.pending_buf_size||(K.gzhead.hcrc&&K.pending>q&&(I.adler=F(I.adler,K.pending_buf,K.pending-q,q)),i(I),q=K.pending,K.pending!==K.pending_buf_size));)r(K,255&K.gzhead.extra[K.gzindex]),K.gzindex++;K.gzhead.hcrc&&K.pending>q&&(I.adler=F(I.adler,K.pending_buf,K.pending-q,q)),K.gzindex===K.gzhead.extra.length&&(K.gzindex=0,K.status=73)}else K.status=73;if(K.status===73)if(K.gzhead.name){q=K.pending;do{if(K.pending===K.pending_buf_size&&(K.gzhead.hcrc&&K.pending>q&&(I.adler=F(I.adler,K.pending_buf,K.pending-q,q)),i(I),q=K.pending,K.pending===K.pending_buf_size)){w=1;break}w=K.gzindexq&&(I.adler=F(I.adler,K.pending_buf,K.pending-q,q)),w===0&&(K.gzindex=0,K.status=91)}else K.status=91;if(K.status===91)if(K.gzhead.comment){q=K.pending;do{if(K.pending===K.pending_buf_size&&(K.gzhead.hcrc&&K.pending>q&&(I.adler=F(I.adler,K.pending_buf,K.pending-q,q)),i(I),q=K.pending,K.pending===K.pending_buf_size)){w=1;break}w=K.gzindexq&&(I.adler=F(I.adler,K.pending_buf,K.pending-q,q)),w===0&&(K.status=103)}else K.status=103;if(K.status===103&&(K.gzhead.hcrc?(K.pending+2>K.pending_buf_size&&i(I),K.pending+2<=K.pending_buf_size&&(r(K,255&I.adler),r(K,I.adler>>8&255),I.adler=0,K.status=h)):K.status=h),K.pending!==0){if(i(I),I.avail_out===0)return K.last_flush=-1,D}else if(I.avail_in===0&&U0(t)<=U0(T)&&t!==k)return J0(I,-5);if(K.status===666&&I.avail_in!==0)return J0(I,-5);if(I.avail_in!==0||K.lookahead!==0||t!==W&&K.status!==666){var l=K.strategy===2?function(u,Q0){for(var q0;;){if(u.lookahead===0&&(p(u),u.lookahead===0)){if(Q0===W)return N;break}if(u.match_length=0,q0=Q._tr_tally(u,0,u.window[u.strstart]),u.lookahead--,u.strstart++,q0&&(_(u,!1),u.strm.avail_out===0))return N}return u.insert=0,Q0===k?(_(u,!0),u.strm.avail_out===0?$0:m):u.last_lit&&(_(u,!1),u.strm.avail_out===0)?N:a}(K,t):K.strategy===3?function(u,Q0){for(var q0,K0,M0,w0,H0=u.window;;){if(u.lookahead<=s){if(p(u),u.lookahead<=s&&Q0===W)return N;if(u.lookahead===0)break}if(u.match_length=0,u.lookahead>=E&&0u.lookahead&&(u.match_length=u.lookahead)}if(u.match_length>=E?(q0=Q._tr_tally(u,1,u.match_length-E),u.lookahead-=u.match_length,u.strstart+=u.match_length,u.match_length=0):(q0=Q._tr_tally(u,0,u.window[u.strstart]),u.lookahead--,u.strstart++),q0&&(_(u,!1),u.strm.avail_out===0))return N}return u.insert=0,Q0===k?(_(u,!0),u.strm.avail_out===0?$0:m):u.last_lit&&(_(u,!1),u.strm.avail_out===0)?N:a}(K,t):G[K.level].func(K,t);if(l!==$0&&l!==m||(K.status=666),l===N||l===$0)return I.avail_out===0&&(K.last_flush=-1),D;if(l===a&&(t===1?Q._tr_align(K):t!==5&&(Q._tr_stored_block(K,0,0,!1),t===3&&(L0(K.head),K.lookahead===0&&(K.strstart=0,K.block_start=0,K.insert=0))),i(I),I.avail_out===0))return K.last_flush=-1,D}return t!==k?D:K.wrap<=0?1:(K.wrap===2?(r(K,255&I.adler),r(K,I.adler>>8&255),r(K,I.adler>>16&255),r(K,I.adler>>24&255),r(K,255&I.total_in),r(K,I.total_in>>8&255),r(K,I.total_in>>16&255),r(K,I.total_in>>24&255)):(n(K,I.adler>>>16),n(K,65535&I.adler)),i(I),0=T.w_size&&(w===0&&(L0(T.head),T.strstart=0,T.block_start=0,T.insert=0),Q0=new X.Buf8(T.w_size),X.arraySet(Q0,t,q0-T.w_size,T.w_size,0),t=Q0,q0=T.w_size),x=I.avail_in,l=I.next_in,u=I.input,I.avail_in=q0,I.next_in=0,I.input=t,p(T);T.lookahead>=E;){for(K=T.strstart,q=T.lookahead-(E-1);T.ins_h=(T.ins_h<>>=E=d>>>24,M-=E,(E=d>>>16&255)===0)a[z++]=65535&d;else{if(!(16&E)){if((64&E)==0){d=L[(65535&d)+(j&(1<>>=E,M-=E),M<15&&(j+=N[B++]<>>=E=d>>>24,M-=E,!(16&(E=d>>>16&255))){if((64&E)==0){d=A[(65535&d)+(j&(1<>>=E,M-=E,(E=z-W)>3,j&=(1<<(M-=s<<3))-1,G.next_in=B,G.next_out=z,G.avail_in=B>>24&255)+(S>>>8&65280)+((65280&S)<<8)+((255&S)<<24)}function j(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new G.Buf16(320),this.work=new G.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function M(S){var h;return S&&S.state?(h=S.state,S.total_in=S.total_out=h.total=0,S.msg="",h.wrap&&(S.adler=1&h.wrap),h.mode=C,h.last=0,h.havedict=0,h.dmax=32768,h.head=null,h.hold=0,h.bits=0,h.lencode=h.lendyn=new G.Buf32(H),h.distcode=h.distdyn=new G.Buf32(O),h.sane=1,h.back=-1,k):D}function L(S){var h;return S&&S.state?((h=S.state).wsize=0,h.whave=0,h.wnext=0,M(S)):D}function A(S,h){var N,a;return S&&S.state?(a=S.state,h<0?(N=0,h=-h):(N=1+(h>>4),h<48&&(h&=15)),h&&(h<8||15=m.wsize?(G.arraySet(m.window,h,N-m.wsize,m.wsize,0),m.wnext=0,m.whave=m.wsize):(a<($0=m.wsize-m.wnext)&&($0=a),G.arraySet(m.window,h,N-a,$0,m.wnext),(a-=$0)?(G.arraySet(m.window,h,N-a,a,0),m.wnext=a,m.whave=m.wsize):(m.wnext+=$0,m.wnext===m.wsize&&(m.wnext=0),m.whave>>8&255,N.check=Q(N.check,w,2,0),_=i=0,N.mode=2;break}if(N.flags=0,N.head&&(N.head.done=!1),!(1&N.wrap)||(((255&i)<<8)+(i>>8))%31){S.msg="incorrect header check",N.mode=30;break}if((15&i)!=8){S.msg="unknown compression method",N.mode=30;break}if(_-=4,I=8+(15&(i>>>=4)),N.wbits===0)N.wbits=I;else if(I>N.wbits){S.msg="invalid window size",N.mode=30;break}N.dmax=1<>8&1),512&N.flags&&(w[0]=255&i,w[1]=i>>>8&255,N.check=Q(N.check,w,2,0)),_=i=0,N.mode=3;case 3:for(;_<32;){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}N.head&&(N.head.time=i),512&N.flags&&(w[0]=255&i,w[1]=i>>>8&255,w[2]=i>>>16&255,w[3]=i>>>24&255,N.check=Q(N.check,w,4,0)),_=i=0,N.mode=4;case 4:for(;_<16;){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}N.head&&(N.head.xflags=255&i,N.head.os=i>>8),512&N.flags&&(w[0]=255&i,w[1]=i>>>8&255,N.check=Q(N.check,w,2,0)),_=i=0,N.mode=5;case 5:if(1024&N.flags){for(;_<16;){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}N.length=i,N.head&&(N.head.extra_len=i),512&N.flags&&(w[0]=255&i,w[1]=i>>>8&255,N.check=Q(N.check,w,2,0)),_=i=0}else N.head&&(N.head.extra=null);N.mode=6;case 6:if(1024&N.flags&&(U0<(Z0=N.length)&&(Z0=U0),Z0&&(N.head&&(I=N.head.extra_len-N.length,N.head.extra||(N.head.extra=Array(N.head.extra_len)),G.arraySet(N.head.extra,a,m,Z0,I)),512&N.flags&&(N.check=Q(N.check,a,Z0,m)),U0-=Z0,m+=Z0,N.length-=Z0),N.length))break $;N.length=0,N.mode=7;case 7:if(2048&N.flags){if(U0===0)break $;for(Z0=0;I=a[m+Z0++],N.head&&I&&N.length<65536&&(N.head.name+=String.fromCharCode(I)),I&&Z0>9&1,N.head.done=!0),S.adler=N.check=0,N.mode=12;break;case 10:for(;_<32;){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}S.adler=N.check=V(i),_=i=0,N.mode=11;case 11:if(N.havedict===0)return S.next_out=J0,S.avail_out=L0,S.next_in=m,S.avail_in=U0,N.hold=i,N.bits=_,2;S.adler=N.check=1,N.mode=12;case 12:if(h===5||h===6)break $;case 13:if(N.last){i>>>=7&_,_-=7&_,N.mode=27;break}for(;_<3;){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}switch(N.last=1&i,_-=1,3&(i>>>=1)){case 0:N.mode=14;break;case 1:if(s(N),N.mode=20,h!==6)break;i>>>=2,_-=2;break $;case 2:N.mode=17;break;case 3:S.msg="invalid block type",N.mode=30}i>>>=2,_-=2;break;case 14:for(i>>>=7&_,_-=7&_;_<32;){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}if((65535&i)!=(i>>>16^65535)){S.msg="invalid stored block lengths",N.mode=30;break}if(N.length=65535&i,_=i=0,N.mode=15,h===6)break $;case 15:N.mode=16;case 16:if(Z0=N.length){if(U0>>=5,_-=5,N.ndist=1+(31&i),i>>>=5,_-=5,N.ncode=4+(15&i),i>>>=4,_-=4,286>>=3,_-=3}for(;N.have<19;)N.lens[x[N.have++]]=0;if(N.lencode=N.lendyn,N.lenbits=7,T={bits:N.lenbits},t=F(0,N.lens,0,19,N.lencode,0,N.work,T),N.lenbits=T.bits,t){S.msg="invalid code lengths set",N.mode=30;break}N.have=0,N.mode=19;case 19:for(;N.have>>16&255,f=65535&q,!((R=q>>>24)<=_);){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}if(f<16)i>>>=R,_-=R,N.lens[N.have++]=f;else{if(f===16){for(K=R+2;_>>=R,_-=R,N.have===0){S.msg="invalid bit length repeat",N.mode=30;break}I=N.lens[N.have-1],Z0=3+(3&i),i>>>=2,_-=2}else if(f===17){for(K=R+3;_>>=R)),i>>>=3,_-=3}else{for(K=R+7;_>>=R)),i>>>=7,_-=7}if(N.have+Z0>N.nlen+N.ndist){S.msg="invalid bit length repeat",N.mode=30;break}for(;Z0--;)N.lens[N.have++]=I}}if(N.mode===30)break;if(N.lens[256]===0){S.msg="invalid code -- missing end-of-block",N.mode=30;break}if(N.lenbits=9,T={bits:N.lenbits},t=F(z,N.lens,0,N.nlen,N.lencode,0,N.work,T),N.lenbits=T.bits,t){S.msg="invalid literal/lengths set",N.mode=30;break}if(N.distbits=6,N.distcode=N.distdyn,T={bits:N.distbits},t=F(W,N.lens,N.nlen,N.ndist,N.distcode,0,N.work,T),N.distbits=T.bits,t){S.msg="invalid distances set",N.mode=30;break}if(N.mode=20,h===6)break $;case 20:N.mode=21;case 21:if(6<=U0&&258<=L0){S.next_out=J0,S.avail_out=L0,S.next_in=m,S.avail_in=U0,N.hold=i,N.bits=_,B(S,n),J0=S.next_out,$0=S.output,L0=S.avail_out,m=S.next_in,a=S.input,U0=S.avail_in,i=N.hold,_=N.bits,N.mode===12&&(N.back=-1);break}for(N.back=0;c=(q=N.lencode[i&(1<>>16&255,f=65535&q,!((R=q>>>24)<=_);){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}if(c&&(240&c)==0){for(v=R,b=c,e=f;c=(q=N.lencode[e+((i&(1<>v)])>>>16&255,f=65535&q,!(v+(R=q>>>24)<=_);){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}i>>>=v,_-=v,N.back+=v}if(i>>>=R,_-=R,N.back+=R,N.length=f,c===0){N.mode=26;break}if(32&c){N.back=-1,N.mode=12;break}if(64&c){S.msg="invalid literal/length code",N.mode=30;break}N.extra=15&c,N.mode=22;case 22:if(N.extra){for(K=N.extra;_>>=N.extra,_-=N.extra,N.back+=N.extra}N.was=N.length,N.mode=23;case 23:for(;c=(q=N.distcode[i&(1<>>16&255,f=65535&q,!((R=q>>>24)<=_);){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}if((240&c)==0){for(v=R,b=c,e=f;c=(q=N.distcode[e+((i&(1<>v)])>>>16&255,f=65535&q,!(v+(R=q>>>24)<=_);){if(U0===0)break $;U0--,i+=a[m++]<<_,_+=8}i>>>=v,_-=v,N.back+=v}if(i>>>=R,_-=R,N.back+=R,64&c){S.msg="invalid distance code",N.mode=30;break}N.offset=f,N.extra=15&c,N.mode=24;case 24:if(N.extra){for(K=N.extra;_>>=N.extra,_-=N.extra,N.back+=N.extra}if(N.offset>N.dmax){S.msg="invalid distance too far back",N.mode=30;break}N.mode=25;case 25:if(L0===0)break $;if(Z0=n-L0,N.offset>Z0){if((Z0=N.offset-Z0)>N.whave&&N.sane){S.msg="invalid distance too far back",N.mode=30;break}p=Z0>N.wnext?(Z0-=N.wnext,N.wsize-Z0):N.wnext-Z0,Z0>N.length&&(Z0=N.length),P=N.window}else P=$0,p=J0-N.offset,Z0=N.length;for(L0g?(E=p[P+O[h]],_[r+O[h]]):(E=96,0),j=1<>J0)+(M-=j)]=d<<24|E<<16|s|0,M!==0;);for(j=1<>=1;if(j!==0?(i&=j-1,i+=j):i=0,h++,--n[S]==0){if(S===a)break;S=W[k+O[h]]}if($0>>7)]}function r(q,w){q.pending_buf[q.pending++]=255&w,q.pending_buf[q.pending++]=w>>>8&255}function n(q,w,x){q.bi_valid>V-x?(q.bi_buf|=w<>V-q.bi_valid,q.bi_valid+=x-V):(q.bi_buf|=w<>>=1,x<<=1,0<--w;);return x>>>1}function P(q,w,x){var l,u,Q0=Array(O+1),q0=0;for(l=1;l<=O;l++)Q0[l]=q0=q0+x[l-1]<<1;for(u=0;u<=w;u++){var K0=q[2*u+1];K0!==0&&(q[2*u]=p(Q0[K0]++,K0))}}function R(q){var w;for(w=0;w>1;1<=x;x--)v(q,Q0,x);for(u=M0;x=q.heap[1],q.heap[1]=q.heap[q.heap_len--],v(q,Q0,1),l=q.heap[1],q.heap[--q.heap_max]=x,q.heap[--q.heap_max]=l,Q0[2*u]=Q0[2*x]+Q0[2*l],q.depth[u]=(q.depth[x]>=q.depth[l]?q.depth[x]:q.depth[l])+1,Q0[2*x+1]=Q0[2*l+1]=u,q.heap[1]=u++,v(q,Q0,1),2<=q.heap_len;);q.heap[--q.heap_max]=q.heap[1],function(H0,v0){var j2,l0,t2,D0,A1,z8,K2=v0.dyn_tree,NU=v0.max_code,H7=v0.stat_desc.static_tree,j7=v0.stat_desc.has_stree,z7=v0.stat_desc.extra_bits,RU=v0.stat_desc.extra_base,e2=v0.stat_desc.max_length,P1=0;for(D0=0;D0<=O;D0++)H0.bl_count[D0]=0;for(K2[2*H0.heap[H0.heap_max]+1]=0,j2=H0.heap_max+1;j2>=7;u>>=1)if(1&w0&&K0.dyn_ltree[2*M0]!==0)return X;if(K0.dyn_ltree[18]!==0||K0.dyn_ltree[20]!==0||K0.dyn_ltree[26]!==0)return Q;for(M0=32;M0>>3,(Q0=q.static_len+3+7>>>3)<=u&&(u=Q0)):u=Q0=x+5,x+4<=u&&w!==-1?K(q,w,x,l):q.strategy===4||Q0===u?(n(q,2+(l?1:0),3),b(q,V0,S)):(n(q,4+(l?1:0),3),function(K0,M0,w0,H0){var v0;for(n(K0,M0-257,5),n(K0,w0-1,5),n(K0,H0-4,4),v0=0;v0>>8&255,q.pending_buf[q.d_buf+2*q.last_lit+1]=255&w,q.pending_buf[q.l_buf+q.last_lit]=255&x,q.last_lit++,w===0?q.dyn_ltree[2*x]++:(q.matches++,w--,q.dyn_ltree[2*(N[x]+W+1)]++,q.dyn_dtree[2*_(w)]++),q.last_lit===q.lit_bufsize-1},J._tr_align=function(q){n(q,2,3),Z0(q,M,V0),function(w){w.bi_valid===16?(r(w,w.bi_buf),w.bi_buf=0,w.bi_valid=0):8<=w.bi_valid&&(w.pending_buf[w.pending++]=255&w.bi_buf,w.bi_buf>>=8,w.bi_valid-=8)}(q)}},{"../utils/common":41}],53:[function(Y,Z,J){Z.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(Y,Z,J){(function(G){(function(X,Q){if(!X.setImmediate){var B,F,z,W,k=1,D={},C=!1,H=X.document,O=Object.getPrototypeOf&&Object.getPrototypeOf(X);O=O&&O.setTimeout?O:X,B={}.toString.call(X.process)==="[object process]"?function(L){j0.nextTick(function(){j(L)})}:function(){if(X.postMessage&&!X.importScripts){var L=!0,A=X.onmessage;return X.onmessage=function(){L=!1},X.postMessage("","*"),X.onmessage=A,L}}()?(W="setImmediate$"+Math.random()+"$",X.addEventListener?X.addEventListener("message",M,!1):X.attachEvent("onmessage",M),function(L){X.postMessage(W+L,"*")}):X.MessageChannel?((z=new MessageChannel).port1.onmessage=function(L){j(L.data)},function(L){z.port2.postMessage(L)}):H&&("onreadystatechange"in H.createElement("script"))?(F=H.documentElement,function(L){var A=H.createElement("script");A.onreadystatechange=function(){j(L),A.onreadystatechange=null,F.removeChild(A),A=null},F.appendChild(A)}):function(L){setTimeout(j,0,L)},O.setImmediate=function(L){typeof L!="function"&&(L=Function(""+L));for(var A=Array(arguments.length-1),y=0;y"u"?G===void 0?this:G:self)}).call(this,typeof c0<"u"?c0:typeof self<"u"?self:typeof window<"u"?window:{})},{}]},{},[10])(10)})}(I9),I9.exports}var YB=UB(),c2=g9(YB),Z1={exports:{}},w9,dZ;function ZB(){if(dZ)return w9;dZ=1;var $={"&":"&",'"':""","'":"'","<":"<",">":">"};function U(Y){return Y&&Y.replace?Y.replace(/([&"<>'])/g,function(Z,J){return $[J]}):Y}return w9=U,w9}var cZ;function QB(){if(cZ)return Z1.exports;cZ=1;var $=ZB(),U=m9().Stream,Y=" ";function Z(F,z){if(typeof z!=="object")z={indent:z};var W=z.stream?new U:null,k="",D=!1,C=!z.indent?"":z.indent===!0?Y:z.indent,H=!0;function O(A){if(!H)A();else j0.nextTick(A)}function V(A,y){if(y!==void 0)k+=y;if(A&&!D)W=W||new U,D=!0;if(A&&D){var g=k;O(function(){W.emit("data",g)}),k=""}}function j(A,y){Q(V,X(A,C,C?1:0),y)}function M(){if(W){var A=k;O(function(){W.emit("data",A),W.emit("end"),W.readable=!1,W.emit("close")})}}function L(A){var y=A.encoding||"UTF-8",g={version:"1.0",encoding:y};if(A.standalone)g.standalone=A.standalone;j({"?xml":{_attr:g}}),k=k.replace("/>","?>")}if(O(function(){H=!1}),z.declaration)L(z.declaration);if(F&&F.forEach)F.forEach(function(A,y){var g;if(y+1===F.length)g=M;j(A,g)});else j(F,M);if(W)return W.readable=!0,W;return k}function J(){var F=Array.prototype.slice.call(arguments),z={_elem:X(F)};return z.push=function(W){if(!this.append)throw Error("not assigned to a parent!");var k=this,D=this._elem.indent;Q(this.append,X(W,D,this._elem.icount+(D?1:0)),function(){k.append(!0)})},z.close=function(W){if(W!==void 0)this.push(W);if(this.end)this.end()},z}function G(F,z){return Array(z||0).join(F||"")}function X(F,z,W){W=W||0;var k=G(z,W),D,C=F,H=!1;if(typeof F==="object"){var O=Object.keys(F);if(D=O[0],C=F[D],C&&C._elem)return C._elem.name=D,C._elem.icount=W,C._elem.indent=z,C._elem.indents=k,C._elem.interrupt=C,C._elem}var V=[],j=[],M;function L(A){var y=Object.keys(A);y.forEach(function(g){V.push(B(g,A[g]))})}switch(typeof C){case"object":if(C===null)break;if(C._attr)L(C._attr);if(C._cdata)j.push(("/g,"]]]]>")+"]]>");if(C.forEach){if(M=!1,j.push(""),C.forEach(function(A){if(typeof A=="object"){var y=Object.keys(A)[0];if(y=="_attr")L(A._attr);else j.push(X(A,z,W+1))}else j.pop(),M=!0,j.push($(A))}),!M)j.push("")}break;default:j.push($(C))}return{name:D,interrupt:H,attributes:V,content:j,icount:W,indents:k,indent:z}}function Q(F,z,W){if(typeof z!="object")return F(!1,z);var k=z.interrupt?1:z.content.length;function D(){while(z.content.length){var H=z.content.shift();if(H===void 0)continue;if(C(H))return;Q(F,H)}if(F(!1,(k>1?z.indents:"")+(z.name?"":"")+(z.indent&&!W?` -`:"")),W)W()}function C(H){if(H.interrupt)return H.interrupt.append=F,H.interrupt.end=D,H.interrupt=!1,F(!0),!0;return!1}if(F(!1,z.indents+(z.name?"<"+z.name:"")+(z.attributes.length?" "+z.attributes.join(" "):"")+(k?z.name?">":"":z.name?"/>":"")+(z.indent&&k>1?` -`:"")),!k)return F(!1,z.indent?` -`:"");if(!C(z))D()}function B(F,z){return F+'="'+$(z)+'"'}return Z1.exports=Z,Z1.exports.element=Z1.exports.Element=J,Z1.exports}var JB=QB(),F0=g9(JB),Q1=0,W9=32,GB=32,KB=($,U)=>{let Y=U.replace(/-/g,"");if(Y.length!==GB)throw Error(`Error: Cannot extract GUID from font filename: ${U}`);let J=Y.replace(/(..)/g,"$1 ").trim().split(" ").map((B)=>parseInt(B,16));J.reverse();let X=$.slice(Q1,W9).map((B,F)=>B^J[F%J.length]),Q=new Uint8Array(Q1+X.length+Math.max(0,$.length-W9));return Q.set($.slice(0,Q1)),Q.set(X,Q1),Q.set($.slice(W9),Q1+X.length),Q};class H8{format($,U={stack:[]}){let Y=$.prepForXml(U);if(Y)return Y;else throw Error("XMLComponent did not format correctly")}}class jU{replace($,U,Y){let Z=$;return U.forEach((J,G)=>{Z=Z.replace(new RegExp(`{${J.fileName}}`,"g"),(Y+G).toString())}),Z}getMediaData($,U){return U.Array.filter((Y)=>$.search(`{${Y.fileName}}`)>0)}}class K7{replace($,U){let Y=$;for(let Z of U)Y=Y.replace(new RegExp(`{${Z.reference}-${Z.instance}}`,"g"),Z.numId.toString());return Y}}class q7{constructor(){Y0(this,"formatter"),Y0(this,"imageReplacer"),Y0(this,"numberingReplacer"),this.formatter=new H8,this.imageReplacer=new jU,this.numberingReplacer=new K7}compile($,U,Y=[]){let Z=new c2,J=this.xmlifyFile($,U),G=new Map(Object.entries(J));for(let[,X]of G)if(Array.isArray(X))for(let Q of X)Z.file(Q.path,X1(Q.data));else Z.file(X.path,X1(X.data));for(let X of Y)Z.file(X.path,X1(X.data));for(let X of $.Media.Array)if(X.type!=="svg")Z.file(`word/media/${X.fileName}`,X.data);else Z.file(`word/media/${X.fileName}`,X.data),Z.file(`word/media/${X.fallback.fileName}`,X.fallback.data);for(let{data:X,name:Q,fontKey:B}of $.FontTable.fontOptionsWithKey){let[F]=Q.split(".");Z.file(`word/fonts/${F}.odttf`,KB(X,B))}return Z}xmlifyFile($,U){let Y=$.Document.Relationships.RelationshipCount+1,Z=F0(this.formatter.format($.Document.View,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{standalone:"yes",encoding:"UTF-8"}}),J=$.Comments.Relationships.RelationshipCount+1,G=F0(this.formatter.format($.Comments,{viewWrapper:{View:$.Comments,Relationships:$.Comments.Relationships},file:$,stack:[]}),{indent:U,declaration:{standalone:"yes",encoding:"UTF-8"}}),X=$.FootNotes.Relationships.RelationshipCount+1,Q=F0(this.formatter.format($.FootNotes.View,{viewWrapper:$.FootNotes,file:$,stack:[]}),{indent:U,declaration:{standalone:"yes",encoding:"UTF-8"}}),B=this.imageReplacer.getMediaData(Z,$.Media),F=this.imageReplacer.getMediaData(G,$.Media),z=this.imageReplacer.getMediaData(Q,$.Media);return{Relationships:{data:(()=>{return B.forEach((W,k)=>{$.Document.Relationships.addRelationship(Y+k,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",`media/${W.fileName}`)}),$.Document.Relationships.addRelationship($.Document.Relationships.RelationshipCount+1,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable","fontTable.xml"),F0(this.formatter.format($.Document.Relationships,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}})})(),path:"word/_rels/document.xml.rels"},Document:{data:(()=>{let W=this.imageReplacer.replace(Z,B,Y);return this.numberingReplacer.replace(W,$.Numbering.ConcreteNumbering)})(),path:"word/document.xml"},Styles:{data:(()=>{let W=F0(this.formatter.format($.Styles,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{standalone:"yes",encoding:"UTF-8"}});return this.numberingReplacer.replace(W,$.Numbering.ConcreteNumbering)})(),path:"word/styles.xml"},Properties:{data:F0(this.formatter.format($.CoreProperties,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{standalone:"yes",encoding:"UTF-8"}}),path:"docProps/core.xml"},Numbering:{data:F0(this.formatter.format($.Numbering,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{standalone:"yes",encoding:"UTF-8"}}),path:"word/numbering.xml"},FileRelationships:{data:F0(this.formatter.format($.FileRelationships,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}}),path:"_rels/.rels"},HeaderRelationships:$.Headers.map((W,k)=>{let D=F0(this.formatter.format(W.View,{viewWrapper:W,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}});return this.imageReplacer.getMediaData(D,$.Media).forEach((H,O)=>{W.Relationships.addRelationship(O,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",`media/${H.fileName}`)}),{data:F0(this.formatter.format(W.Relationships,{viewWrapper:W,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}}),path:`word/_rels/header${k+1}.xml.rels`}}),FooterRelationships:$.Footers.map((W,k)=>{let D=F0(this.formatter.format(W.View,{viewWrapper:W,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}});return this.imageReplacer.getMediaData(D,$.Media).forEach((H,O)=>{W.Relationships.addRelationship(O,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",`media/${H.fileName}`)}),{data:F0(this.formatter.format(W.Relationships,{viewWrapper:W,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}}),path:`word/_rels/footer${k+1}.xml.rels`}}),Headers:$.Headers.map((W,k)=>{let D=F0(this.formatter.format(W.View,{viewWrapper:W,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}}),C=this.imageReplacer.getMediaData(D,$.Media),H=this.imageReplacer.replace(D,C,0);return{data:this.numberingReplacer.replace(H,$.Numbering.ConcreteNumbering),path:`word/header${k+1}.xml`}}),Footers:$.Footers.map((W,k)=>{let D=F0(this.formatter.format(W.View,{viewWrapper:W,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}}),C=this.imageReplacer.getMediaData(D,$.Media),H=this.imageReplacer.replace(D,C,0);return{data:this.numberingReplacer.replace(H,$.Numbering.ConcreteNumbering),path:`word/footer${k+1}.xml`}}),ContentTypes:{data:F0(this.formatter.format($.ContentTypes,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}}),path:"[Content_Types].xml"},CustomProperties:{data:F0(this.formatter.format($.CustomProperties,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{standalone:"yes",encoding:"UTF-8"}}),path:"docProps/custom.xml"},AppProperties:{data:F0(this.formatter.format($.AppProperties,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{standalone:"yes",encoding:"UTF-8"}}),path:"docProps/app.xml"},FootNotes:{data:(()=>{let W=this.imageReplacer.replace(Q,z,X);return this.numberingReplacer.replace(W,$.Numbering.ConcreteNumbering)})(),path:"word/footnotes.xml"},FootNotesRelationships:{data:(()=>{return z.forEach((W,k)=>{$.FootNotes.Relationships.addRelationship(X+k,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",`media/${W.fileName}`)}),F0(this.formatter.format($.FootNotes.Relationships,{viewWrapper:$.FootNotes,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}})})(),path:"word/_rels/footnotes.xml.rels"},Endnotes:{data:F0(this.formatter.format($.Endnotes.View,{viewWrapper:$.Endnotes,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}}),path:"word/endnotes.xml"},EndnotesRelationships:{data:F0(this.formatter.format($.Endnotes.Relationships,{viewWrapper:$.Endnotes,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}}),path:"word/_rels/endnotes.xml.rels"},Settings:{data:F0(this.formatter.format($.Settings,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{standalone:"yes",encoding:"UTF-8"}}),path:"word/settings.xml"},Comments:{data:(()=>{let W=this.imageReplacer.replace(G,F,J);return this.numberingReplacer.replace(W,$.Numbering.ConcreteNumbering)})(),path:"word/comments.xml"},CommentsRelationships:{data:(()=>{return F.forEach((W,k)=>{$.Comments.Relationships.addRelationship(J+k,"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",`media/${W.fileName}`)}),F0(this.formatter.format($.Comments.Relationships,{viewWrapper:{View:$.Comments,Relationships:$.Comments.Relationships},file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}})})(),path:"word/_rels/comments.xml.rels"},FontTable:{data:F0(this.formatter.format($.FontTable.View,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{standalone:"yes",encoding:"UTF-8"}}),path:"word/fontTable.xml"},FontTableRelationships:{data:(()=>F0(this.formatter.format($.FontTable.Relationships,{viewWrapper:$.Document,file:$,stack:[]}),{indent:U,declaration:{encoding:"UTF-8"}}))(),path:"word/_rels/fontTable.xml.rels"}}}}var X7={NONE:"",WITH_2_BLANKS:" ",WITH_4_BLANKS:" ",WITH_TAB:"\t"},mZ=($)=>$===!0?X7.WITH_2_BLANKS:$===!1?void 0:$,V7=class ${static pack(U,Y,Z){return b9(this,arguments,function*(J,G,X,Q=[]){return this.compiler.compile(J,mZ(X),Q).generateAsync({type:G,mimeType:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",compression:"DEFLATE"})})}static toString(U,Y,Z=[]){return $.pack(U,"string",Y,Z)}static toBuffer(U,Y,Z=[]){return $.pack(U,"nodebuffer",Y,Z)}static toBase64String(U,Y,Z=[]){return $.pack(U,"base64",Y,Z)}static toBlob(U,Y,Z=[]){return $.pack(U,"blob",Y,Z)}static toArrayBuffer(U,Y,Z=[]){return $.pack(U,"arraybuffer",Y,Z)}static toStream(U,Y,Z=[]){let J=new $B.Stream;return this.compiler.compile(U,mZ(Y),Z).generateAsync({type:"nodebuffer",mimeType:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",compression:"DEFLATE"}).then((X)=>{J.emit("data",X),J.emit("end")}),J}};Y0(V7,"compiler",new q7);var qB=V7,XB=new H8,j8=($)=>{return $8.xml2js($,{compact:!1,captureSpacesBetweenElements:!0})},B7=($)=>{var U;return(U=j8(F0(XB.format(new a2({text:$})))).elements[0].elements)!=null?U:[]},L7=($)=>R0(W0({},$),{attributes:{"xml:space":"preserve"}}),zU=($,U)=>{var Y,Z;return(Z=(Y=$.elements)==null?void 0:Y.filter((J)=>J.name===U)[0].elements)!=null?Z:[]},h2=($,U,Y)=>{let Z=zU($,"Types");if(Z.some((G)=>{var X,Q;return G.type==="element"&&G.name==="Default"&&((X=G==null?void 0:G.attributes)==null?void 0:X.ContentType)===U&&((Q=G==null?void 0:G.attributes)==null?void 0:Q.Extension)===Y}))return;Z.push({attributes:{ContentType:U,Extension:Y},name:"Default",type:"element"})},VB=($)=>{let U=parseInt($.substring(3),10);return isNaN(U)?0:U},BB=($)=>{return zU($,"Relationships").map((Y)=>{var Z,J,G;return VB((G=(J=(Z=Y.attributes)==null?void 0:Z.Id)==null?void 0:J.toString())!=null?G:"")}).reduce((Y,Z)=>Math.max(Y,Z),0)+1},lZ=($,U,Y,Z,J)=>{let G=zU($,"Relationships");return G.push({attributes:{Id:`rId${U}`,Type:Y,Target:Z,TargetMode:J},name:"Relationship",type:"element"}),G};class M7 extends Error{constructor($){super(`Token ${$} not found`);this.name="TokenNotFoundError"}}var LB=($,U)=>{var Y,Z,J,G;for(let X=0;X<((Y=$.elements)!=null?Y:[]).length;X++){let Q=$.elements[X];if(Q.type==="element"&&Q.name==="w:r"){let B=((Z=Q.elements)!=null?Z:[]).filter((F)=>F.type==="element"&&F.name==="w:t");for(let F of B){if(!((J=F.elements)==null?void 0:J[0]))continue;if((G=F.elements[0].text)==null?void 0:G.includes(U))return X}}}throw new M7(U)},MB=($,U)=>{var Y,Z;let J=-1,G=(Z=(Y=$.elements)==null?void 0:Y.map((B,F)=>{var z,W,k;if(J!==-1)return B;if(B.type==="element"&&B.name==="w:t"){let C=((k=(W=(z=B.elements)==null?void 0:z[0])==null?void 0:W.text)!=null?k:"").split(U),H=C.map((O)=>R0(W0(W0({},B),L7(B)),{elements:B7(O)}));if(C.length>1)J=F;return H}else return B}).flat())!=null?Z:[],X=R0(W0({},JSON.parse(JSON.stringify($))),{elements:G.slice(0,J+1)}),Q=R0(W0({},JSON.parse(JSON.stringify($))),{elements:G.slice(J+1)});return{left:X,right:Q}},J1={START:0,MIDDLE:1,END:2},IB=({paragraphElement:$,renderedParagraph:U,originalText:Y,replacementText:Z})=>{let J=U.text.indexOf(Y),G=J+Y.length-1,X=J1.START;for(let Q of U.runs)for(let{text:B,index:F,start:z,end:W}of Q.parts)switch(X){case J1.START:if(J>=z&&J<=W){let k=J-z,D=Math.min(G,W)-z,C=Q.text.substring(k,D+1);if(C==="")continue;let H=B.replace(C,Z);H9($.elements[Q.index].elements[F],H),X=J1.MIDDLE;continue}break;case J1.MIDDLE:if(G<=W){let k=B.substring(G-z+1);H9($.elements[Q.index].elements[F],k);let D=$.elements[Q.index].elements[F];$.elements[Q.index].elements[F]=L7(D),X=J1.END}else H9($.elements[Q.index].elements[F],"");break}return $},H9=($,U)=>{return $.elements=B7(U),$},wB=($)=>{if($.element.name!=="w:p")throw Error(`Invalid node type: ${$.element.name}`);if(!$.element.elements)return{text:"",runs:[],index:-1,pathToParagraph:[]};let U=0,Y=$.element.elements.map((J,G)=>({element:J,i:G})).filter(({element:J})=>J.name==="w:r").map(({element:J,i:G})=>{let X=WB(J,G,U);return U+=X.text.length,X}).filter((J)=>!!J);return{text:Y.reduce((J,G)=>J+G.text,""),runs:Y,index:$.index,pathToParagraph:I7($)}},WB=($,U,Y)=>{if(!$.elements)return{text:"",parts:[],index:-1,start:Y,end:Y};let Z=Y,J=$.elements.map((X,Q)=>{var B,F;return X.name==="w:t"&&X.elements&&X.elements.length>0?{text:(F=(B=X.elements[0].text)==null?void 0:B.toString())!=null?F:"",index:Q,start:Z,end:(()=>{var z,W;return Z+=((W=(z=X.elements[0].text)==null?void 0:z.toString())!=null?W:"").length-1,Z})()}:void 0}).filter((X)=>!!X).map((X)=>X);return{text:J.reduce((X,Q)=>X+Q.text,""),parts:J,index:U,start:Y,end:Z}},I7=($)=>$.parent?[...I7($.parent),$.index]:[$.index],aZ=($)=>{var U,Y;return(Y=(U=$.element.elements)==null?void 0:U.map((Z,J)=>({element:Z,index:J,parent:$})))!=null?Y:[]},w7=($)=>{let U=[],Y=[...aZ({element:$,index:0,parent:void 0})],Z;while(Y.length>0){if(Z=Y.shift(),Z.element.name==="w:p")U=[...U,wB(Z)];Y.push(...aZ(Z))}return U},HB=($,U)=>w7($).filter((Y)=>Y.text.includes(U)),jB=new H8,j9="ɵ",zB=({json:$,patch:U,patchText:Y,context:Z,keepOriginalStyles:J=!0})=>{let G=HB($,Y);if(G.length===0)return{element:$,didFindOccurrence:!1};for(let X of G){let Q=U.children.map((B)=>j8(F0(jB.format(B,Z)))).map((B)=>B.elements[0]);switch(U.type){case y9.DOCUMENT:{let B=FB($,X.pathToParagraph),F=NB(X.pathToParagraph);B.elements.splice(F,1,...Q);break}case y9.PARAGRAPH:default:{let B=W7($,X.pathToParagraph);IB({paragraphElement:B,renderedParagraph:X,originalText:Y,replacementText:j9});let F=LB(B,j9),z=B.elements[F],{left:W,right:k}=MB(z,j9),D=Q,C=k;if(J){let H=z.elements.filter((O)=>O.type==="element"&&O.name==="w:rPr");D=Q.map((O)=>{var V;return R0(W0({},O),{elements:[...H,...(V=O.elements)!=null?V:[]]})}),C=R0(W0({},k),{elements:[...H,...k.elements]})}B.elements.splice(F,1,W,...D,C);break}}}return{element:$,didFindOccurrence:!0}},W7=($,U)=>{let Y=$;for(let Z=1;ZW7($,U.slice(0,U.length-1)),NB=($)=>$[$.length-1],y9={DOCUMENT:"file",PARAGRAPH:"paragraph"},pZ=new jU,RB=new Uint8Array([255,254]),DB=new Uint8Array([254,255]),iZ=($,U)=>{if($.length!==U.length)return!1;for(let Y=0;Y<$.length;Y++)if($[Y]!==U[Y])return!1;return!0},AB=($)=>b9(null,[$],function*({outputType:U,data:Y,patches:Z,keepOriginalStyles:J,placeholderDelimiters:G={start:"{{",end:"}}"},recursive:X=!0}){var Q,B,F;let z=Y instanceof c2?Y:yield c2.loadAsync(Y),W=new Map,k={Media:new w8},D=new Map,C=[],H=[],O=!1,V=new Map;for(let[M,L]of Object.entries(z.files)){let A=yield L.async("uint8array"),y=A.slice(0,2);if(iZ(y,RB)||iZ(y,DB)){V.set(M,A);continue}if(!M.endsWith(".xml")&&!M.endsWith(".rels")){V.set(M,A);continue}let g=j8(yield L.async("text"));if(M==="word/document.xml"){let d=(Q=g.elements)==null?void 0:Q.find((E)=>E.name==="w:document");if(d&&d.attributes){for(let E of["mc","wp","r","w15","m"])d.attributes[`xmlns:${E}`]=p1[E];d.attributes["mc:Ignorable"]=`${d.attributes["mc:Ignorable"]||""} w15`.trim()}}if(M.startsWith("word/")&&!M.endsWith(".xml.rels")){let d={file:k,viewWrapper:{Relationships:{addRelationship:(S,h,N,a)=>{H.push({key:M,hyperlink:{id:S,link:N}})}}},stack:[]};if(W.set(M,d),!(G==null?void 0:G.start.trim())||!(G==null?void 0:G.end.trim()))throw Error("Both start and end delimiters must be non-empty strings.");let{start:E,end:s}=G;for(let[S,h]of Object.entries(Z)){let N=`${E}${S}${s}`;while(!0){let{didFindOccurrence:a}=zB({json:g,patch:R0(W0({},h),{children:h.children.map(($0)=>{if($0 instanceof K8){let m=new _2($0.options.children,R1());return H.push({key:M,hyperlink:{id:m.linkId,link:$0.options.link}}),m}else return $0})}),patchText:N,context:d,keepOriginalStyles:J});if(!X||!a)break}}let V0=pZ.getMediaData(JSON.stringify(g),d.file.Media);if(V0.length>0)O=!0,C.push({key:M,mediaDatas:V0})}D.set(M,g)}for(let{key:M,mediaDatas:L}of C){let A=`word/_rels/${M.split("/").pop()}.rels`,y=(B=D.get(A))!=null?B:rZ();D.set(A,y);let g=BB(y),d=pZ.replace(JSON.stringify(D.get(M)),L,g);D.set(M,JSON.parse(d));for(let E=0;E{return $8.js2xml($,{attributeValueFn:(Y)=>String(Y).replace(/&(?!amp;|lt;|gt;|quot;|apos;)/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")})},rZ=()=>({declaration:{attributes:{version:"1.0",encoding:"UTF-8",standalone:"yes"}},elements:[{type:"element",name:"Relationships",attributes:{xmlns:"http://schemas.openxmlformats.org/package/2006/relationships"},elements:[]}]}),TB=($)=>b9(null,[$],function*({data:U}){let Y=U instanceof c2?U:yield c2.loadAsync(U),Z=new Set;for(let[J,G]of Object.entries(Y.files)){if(!J.endsWith(".xml")&&!J.endsWith(".rels"))continue;if(J.startsWith("word/")&&!J.endsWith(".xml.rels")){let X=j8(yield G.async("text"));w7(X).forEach((Q)=>CB(Q.text).forEach((B)=>Z.add(B)))}}return Array.from(Z)}),CB=($)=>{var U;let Y=new RegExp("(?<=\\{\\{).+?(?=\\}\\})","gs");return(U=$.match(Y))!=null?U:[]};if(typeof globalThis.Buffer>"u")globalThis.Buffer=G0;if(typeof globalThis.process>"u")globalThis.process=OB;globalThis.__bundles=globalThis.__bundles||{};globalThis.__bundles.docx=FU;})(); diff --git a/apps/sim/lib/execution/sandbox/bundles/pdf-lib.cjs b/apps/sim/lib/execution/sandbox/bundles/pdf-lib.cjs deleted file mode 100644 index f56f8e9699a..00000000000 --- a/apps/sim/lib/execution/sandbox/bundles/pdf-lib.cjs +++ /dev/null @@ -1,55 +0,0 @@ -// sandbox bundle: pdf-lib -// generated by apps/sim/lib/execution/sandbox/bundles/build.ts -// do not edit by hand. run `bun run build:sandbox-bundles` to regenerate. -(()=>{var dK=Object.create;var{getPrototypeOf:nK,defineProperty:fq,getOwnPropertyNames:rK}=Object;var iK=Object.prototype.hasOwnProperty;function aK(q){return this[q]}var oK,sK,$8=(q,X,V)=>{var K=q!=null&&typeof q==="object";if(K){var Q=X?oK??=new WeakMap:sK??=new WeakMap,Y=Q.get(q);if(Y)return Y}V=q!=null?dK(nK(q)):{};let J=X||!q||!q.__esModule?fq(V,"default",{value:q,enumerable:!0}):V;for(let G of rK(q))if(!iK.call(J,G))fq(J,G,{get:aK.bind(q,G),enumerable:!0});if(K)Q.set(q,J);return J};var g0=(q,X)=>()=>(X||q((X={exports:{}}).exports,X),X.exports);var tK=(q)=>q;function eK(q,X){this[q]=tK.bind(null,X)}var qQ=(q,X)=>{for(var V in X)fq(q,V,{get:X[V],enumerable:!0,configurable:!0,set:eK.bind(X,V)})};var gX=g0((b3,uX)=>{var A0=uX.exports={},F2,P2;function sq(){throw Error("setTimeout has not been defined")}function tq(){throw Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function")F2=setTimeout;else F2=sq}catch(q){F2=sq}try{if(typeof clearTimeout==="function")P2=clearTimeout;else P2=tq}catch(q){P2=tq}})();function FX(q){if(F2===setTimeout)return setTimeout(q,0);if((F2===sq||!F2)&&setTimeout)return F2=setTimeout,setTimeout(q,0);try{return F2(q,0)}catch(X){try{return F2.call(null,q,0)}catch(V){return F2.call(this,q,0)}}}function FQ(q){if(P2===clearTimeout)return clearTimeout(q);if((P2===tq||!P2)&&clearTimeout)return P2=clearTimeout,clearTimeout(q);try{return P2(q)}catch(X){try{return P2.call(null,q)}catch(V){return P2.call(this,q)}}}var o2=[],$5=!1,d6,h1=-1;function PQ(){if(!$5||!d6)return;if($5=!1,d6.length)o2=d6.concat(o2);else h1=-1;if(o2.length)PX()}function PX(){if($5)return;var q=FX(PQ);$5=!0;var X=o2.length;while(X){d6=o2,o2=[];while(++h11)for(var V=1;V{var _Q=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Int32Array<"u";function cQ(q,X){return Object.prototype.hasOwnProperty.call(q,X)}r0.assign=function(q){var X=Array.prototype.slice.call(arguments,1);while(X.length){var V=X.shift();if(!V)continue;if(typeof V!=="object")throw TypeError(V+"must be non-object");for(var K in V)if(cQ(V,K))q[K]=V[K]}return q};r0.shrinkBuf=function(q,X){if(q.length===X)return q;if(q.subarray)return q.subarray(0,X);return q.length=X,q};var pQ={arraySet:function(q,X,V,K,Q){if(X.subarray&&q.subarray){q.set(X.subarray(V,V+K),Q);return}for(var Y=0;Y{var nQ=t2(),rQ=4,pX=0,dX=1,iQ=2;function u5(q){var X=q.length;while(--X>=0)q[X]=0}var aQ=0,sX=1,oQ=2,sQ=3,tQ=258,N4=29,p8=256,f8=p8+1+N4,D5=30,S4=19,tX=2*f8+1,i6=15,T4=16,eQ=7,y4=256,eX=16,qV=17,XV=18,w4=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],g1=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],qY=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],VV=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],XY=512,e2=Array((f8+2)*2);u5(e2);var m8=Array(D5*2);u5(m8);var l8=Array(XY);u5(l8);var _8=Array(tQ-sQ+1);u5(_8);var $4=Array(N4);u5($4);var x1=Array(D5);u5(x1);function v4(q,X,V,K,Q){this.static_tree=q,this.extra_bits=X,this.extra_base=V,this.elems=K,this.max_length=Q,this.has_stree=q&&q.length}var KV,QV,YV;function R4(q,X){this.dyn_tree=q,this.max_code=0,this.stat_desc=X}function JV(q){return q<256?l8[q]:l8[256+(q>>>7)]}function c8(q,X){q.pending_buf[q.pending++]=X&255,q.pending_buf[q.pending++]=X>>>8&255}function q2(q,X,V){if(q.bi_valid>T4-V)q.bi_buf|=X<>T4-q.bi_valid,q.bi_valid+=V-T4;else q.bi_buf|=X<>>=1,V<<=1;while(--X>0);return V>>>1}function VY(q){if(q.bi_valid===16)c8(q,q.bi_buf),q.bi_buf=0,q.bi_valid=0;else if(q.bi_valid>=8)q.pending_buf[q.pending++]=q.bi_buf&255,q.bi_buf>>=8,q.bi_valid-=8}function KY(q,X){var{dyn_tree:V,max_code:K}=X,Q=X.stat_desc.static_tree,Y=X.stat_desc.has_stree,J=X.stat_desc.extra_bits,G=X.stat_desc.extra_base,W=X.stat_desc.max_length,Z,H,U,z,k,M,j=0;for(z=0;z<=i6;z++)q.bl_count[z]=0;V[q.heap[q.heap_max]*2+1]=0;for(Z=q.heap_max+1;ZW)z=W,j++;if(V[H*2+1]=z,H>K)continue;if(q.bl_count[z]++,k=0,H>=G)k=J[H-G];if(M=V[H*2],q.opt_len+=M*(z+k),Y)q.static_len+=M*(Q[H*2+1]+k)}if(j===0)return;do{z=W-1;while(q.bl_count[z]===0)z--;q.bl_count[z]--,q.bl_count[z+1]+=2,q.bl_count[W]--,j-=2}while(j>0);for(z=W;z!==0;z--){H=q.bl_count[z];while(H!==0){if(U=q.heap[--Z],U>K)continue;if(V[U*2+1]!==z)q.opt_len+=(z-V[U*2+1])*V[U*2],V[U*2+1]=z;H--}}}function ZV(q,X,V){var K=Array(i6+1),Q=0,Y,J;for(Y=1;Y<=i6;Y++)K[Y]=Q=Q+V[Y-1]<<1;for(J=0;J<=X;J++){var G=q[J*2+1];if(G===0)continue;q[J*2]=GV(K[G]++,G)}}function QY(){var q,X,V,K,Q,Y=Array(i6+1);V=0;for(K=0;K>=7;for(;K8)c8(q,q.bi_buf);else if(q.bi_valid>0)q.pending_buf[q.pending++]=q.bi_buf;q.bi_buf=0,q.bi_valid=0}function YY(q,X,V,K){if(HV(q),K)c8(q,V),c8(q,~V);nQ.arraySet(q.pending_buf,q.window,X,V,q.pending),q.pending+=V}function nX(q,X,V,K){var Q=X*2,Y=V*2;return q[Q]>1;J>=1;J--)O4(q,V,J);Z=Y;do J=q.heap[1],q.heap[1]=q.heap[q.heap_len--],O4(q,V,1),G=q.heap[1],q.heap[--q.heap_max]=J,q.heap[--q.heap_max]=G,V[Z*2]=V[J*2]+V[G*2],q.depth[Z]=(q.depth[J]>=q.depth[G]?q.depth[J]:q.depth[G])+1,V[J*2+1]=V[G*2+1]=Z,q.heap[1]=Z++,O4(q,V,1);while(q.heap_len>=2);q.heap[--q.heap_max]=q.heap[1],KY(q,X),ZV(V,W,q.bl_count)}function iX(q,X,V){var K,Q=-1,Y,J=X[1],G=0,W=7,Z=4;if(J===0)W=138,Z=3;X[(V+1)*2+1]=65535;for(K=0;K<=V;K++){if(Y=J,J=X[(K+1)*2+1],++G=3;X--)if(q.bl_tree[VV[X]*2+1]!==0)break;return q.opt_len+=3*(X+1)+5+5+4,X}function GY(q,X,V,K){var Q;q2(q,X-257,5),q2(q,V-1,5),q2(q,K-4,4);for(Q=0;Q>>=1)if(X&1&&q.dyn_ltree[V*2]!==0)return pX;if(q.dyn_ltree[18]!==0||q.dyn_ltree[20]!==0||q.dyn_ltree[26]!==0)return dX;for(V=32;V0){if(q.strm.data_type===iQ)q.strm.data_type=ZY(q);if(A4(q,q.l_desc),A4(q,q.d_desc),J=JY(q),Q=q.opt_len+3+7>>>3,Y=q.static_len+3+7>>>3,Y<=Q)Q=Y}else Q=Y=V+5;if(V+4<=Q&&X!==-1)UV(q,X,V,K);else if(q.strategy===rQ||Y===Q)q2(q,(sX<<1)+(K?1:0),3),rX(q,e2,m8);else q2(q,(oQ<<1)+(K?1:0),3),GY(q,q.l_desc.max_code+1,q.d_desc.max_code+1,J+1),rX(q,q.dyn_ltree,q.dyn_dtree);if(WV(q),K)HV(q)}function zY(q,X,V){if(q.pending_buf[q.d_buf+q.last_lit*2]=X>>>8&255,q.pending_buf[q.d_buf+q.last_lit*2+1]=X&255,q.pending_buf[q.l_buf+q.last_lit]=V&255,q.last_lit++,X===0)q.dyn_ltree[V*2]++;else q.matches++,X--,q.dyn_ltree[(_8[V]+p8+1)*2]++,q.dyn_dtree[JV(X)*2]++;return q.last_lit===q.lit_bufsize-1}g5._tr_init=WY;g5._tr_stored_block=UV;g5._tr_flush_block=UY;g5._tr_tally=zY;g5._tr_align=HY});var C4=g0((t3,MV)=>{function MY(q,X,V,K){var Q=q&65535|0,Y=q>>>16&65535|0,J=0;while(V!==0){J=V>2000?2000:V,V-=J;do Q=Q+X[K++]|0,Y=Y+Q|0;while(--J);Q%=65521,Y%=65521}return Q|Y<<16|0}MV.exports=MY});var h4=g0((e3,kV)=>{function kY(){var q,X=[];for(var V=0;V<256;V++){q=V;for(var K=0;K<8;K++)q=q&1?3988292384^q>>>1:q>>>1;X[V]=q}return X}var IY=kY();function EY(q,X,V,K){var Q=IY,Y=K+V;q^=-1;for(var J=K;J>>8^Q[(q^X[J])&255];return q^-1}kV.exports=EY});var b1=g0((qW,IV)=>{IV.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}});var wV=g0((m2)=>{var i0=t2(),H2=zV(),BV=C4(),B6=h4(),jY=b1(),t6=0,LY=1,BY=3,w6=4,EV=5,b2=0,jV=1,U2=-2,TY=-3,F4=-5,vY=-1,RY=1,m1=2,OY=3,wY=4,AY=0,NY=2,c1=8,SY=9,yY=15,$Y=8,CY=29,hY=256,D4=hY+1+CY,FY=30,PY=19,DY=2*D4+1,uY=15,H0=3,R6=258,O2=R6+H0+1,gY=32,p1=42,u4=69,f1=73,l1=91,_1=103,a6=113,n8=666,h0=1,r8=2,o6=3,m5=4,xY=3;function O6(q,X){return q.msg=jY[X],X}function LV(q){return(q<<1)-(q>4?9:0)}function v6(q){var X=q.length;while(--X>=0)q[X]=0}function T6(q){var X=q.state,V=X.pending;if(V>q.avail_out)V=q.avail_out;if(V===0)return;if(i0.arraySet(q.output,X.pending_buf,X.pending_out,V,q.next_out),q.next_out+=V,X.pending_out+=V,q.total_out+=V,q.avail_out-=V,X.pending-=V,X.pending===0)X.pending_out=0}function x0(q,X){H2._tr_flush_block(q,q.block_start>=0?q.block_start:-1,q.strstart-q.block_start,X),q.block_start=q.strstart,T6(q.strm)}function U0(q,X){q.pending_buf[q.pending++]=X}function d8(q,X){q.pending_buf[q.pending++]=X>>>8&255,q.pending_buf[q.pending++]=X&255}function bY(q,X,V,K){var Q=q.avail_in;if(Q>K)Q=K;if(Q===0)return 0;if(q.avail_in-=Q,i0.arraySet(X,q.input,q.next_in,Q,V),q.state.wrap===1)q.adler=BV(q.adler,X,Q,V);else if(q.state.wrap===2)q.adler=B6(q.adler,X,Q,V);return q.next_in+=Q,q.total_in+=Q,Q}function TV(q,X){var{max_chain_length:V,strstart:K}=q,Q,Y,J=q.prev_length,G=q.nice_match,W=q.strstart>q.w_size-O2?q.strstart-(q.w_size-O2):0,Z=q.window,H=q.w_mask,U=q.prev,z=q.strstart+R6,k=Z[K+J-1],M=Z[K+J];if(q.prev_length>=q.good_match)V>>=2;if(G>q.lookahead)G=q.lookahead;do{if(Q=X,Z[Q+J]!==M||Z[Q+J-1]!==k||Z[Q]!==Z[K]||Z[++Q]!==Z[K+1])continue;K+=2,Q++;do;while(Z[++K]===Z[++Q]&&Z[++K]===Z[++Q]&&Z[++K]===Z[++Q]&&Z[++K]===Z[++Q]&&Z[++K]===Z[++Q]&&Z[++K]===Z[++Q]&&Z[++K]===Z[++Q]&&Z[++K]===Z[++Q]&&KJ){if(q.match_start=X,J=Y,Y>=G)break;k=Z[K+J-1],M=Z[K+J]}}while((X=U[X&H])>W&&--V!==0);if(J<=q.lookahead)return J;return q.lookahead}function s6(q){var X=q.w_size,V,K,Q,Y,J;do{if(Y=q.window_size-q.lookahead-q.strstart,q.strstart>=X+(X-O2)){i0.arraySet(q.window,q.window,X,X,0),q.match_start-=X,q.strstart-=X,q.block_start-=X,K=q.hash_size,V=K;do Q=q.head[--V],q.head[V]=Q>=X?Q-X:0;while(--K);K=X,V=K;do Q=q.prev[--V],q.prev[V]=Q>=X?Q-X:0;while(--K);Y+=X}if(q.strm.avail_in===0)break;if(K=bY(q.strm,q.window,q.strstart+q.lookahead,Y),q.lookahead+=K,q.lookahead+q.insert>=H0){J=q.strstart-q.insert,q.ins_h=q.window[J],q.ins_h=(q.ins_h<q.pending_buf_size-5)V=q.pending_buf_size-5;for(;;){if(q.lookahead<=1){if(s6(q),q.lookahead===0&&X===t6)return h0;if(q.lookahead===0)break}q.strstart+=q.lookahead,q.lookahead=0;var K=q.block_start+V;if(q.strstart===0||q.strstart>=K){if(q.lookahead=q.strstart-K,q.strstart=K,x0(q,!1),q.strm.avail_out===0)return h0}if(q.strstart-q.block_start>=q.w_size-O2){if(x0(q,!1),q.strm.avail_out===0)return h0}}if(q.insert=0,X===w6){if(x0(q,!0),q.strm.avail_out===0)return o6;return m5}if(q.strstart>q.block_start){if(x0(q,!1),q.strm.avail_out===0)return h0}return h0}function P4(q,X){var V,K;for(;;){if(q.lookahead=H0)q.ins_h=(q.ins_h<=H0)if(K=H2._tr_tally(q,q.strstart-q.match_start,q.match_length-H0),q.lookahead-=q.match_length,q.match_length<=q.max_lazy_match&&q.lookahead>=H0){q.match_length--;do q.strstart++,q.ins_h=(q.ins_h<=H0)q.ins_h=(q.ins_h<4096))q.match_length=H0-1}if(q.prev_length>=H0&&q.match_length<=q.prev_length){Q=q.strstart+q.lookahead-H0,K=H2._tr_tally(q,q.strstart-1-q.prev_match,q.prev_length-H0),q.lookahead-=q.prev_length-1,q.prev_length-=2;do if(++q.strstart<=Q)q.ins_h=(q.ins_h<=H0&&q.strstart>0){if(Q=q.strstart-1,K=J[Q],K===J[++Q]&&K===J[++Q]&&K===J[++Q]){Y=q.strstart+R6;do;while(K===J[++Q]&&K===J[++Q]&&K===J[++Q]&&K===J[++Q]&&K===J[++Q]&&K===J[++Q]&&K===J[++Q]&&K===J[++Q]&&Qq.lookahead)q.match_length=q.lookahead}}if(q.match_length>=H0)V=H2._tr_tally(q,1,q.match_length-H0),q.lookahead-=q.match_length,q.strstart+=q.match_length,q.match_length=0;else V=H2._tr_tally(q,0,q.window[q.strstart]),q.lookahead--,q.strstart++;if(V){if(x0(q,!1),q.strm.avail_out===0)return h0}}if(q.insert=0,X===w6){if(x0(q,!0),q.strm.avail_out===0)return o6;return m5}if(q.last_lit){if(x0(q,!1),q.strm.avail_out===0)return h0}return r8}function lY(q,X){var V;for(;;){if(q.lookahead===0){if(s6(q),q.lookahead===0){if(X===t6)return h0;break}}if(q.match_length=0,V=H2._tr_tally(q,0,q.window[q.strstart]),q.lookahead--,q.strstart++,V){if(x0(q,!1),q.strm.avail_out===0)return h0}}if(q.insert=0,X===w6){if(x0(q,!0),q.strm.avail_out===0)return o6;return m5}if(q.last_lit){if(x0(q,!1),q.strm.avail_out===0)return h0}return r8}function x2(q,X,V,K,Q){this.good_length=q,this.max_lazy=X,this.nice_length=V,this.max_chain=K,this.func=Q}var b5;b5=[new x2(0,0,0,0,mY),new x2(4,4,8,4,P4),new x2(4,5,16,8,P4),new x2(4,6,32,32,P4),new x2(4,4,16,16,x5),new x2(8,16,32,32,x5),new x2(8,16,128,128,x5),new x2(8,32,128,256,x5),new x2(32,128,258,1024,x5),new x2(32,258,258,4096,x5)];function _Y(q){q.window_size=2*q.w_size,v6(q.head),q.max_lazy_match=b5[q.level].max_lazy,q.good_match=b5[q.level].good_length,q.nice_match=b5[q.level].nice_length,q.max_chain_length=b5[q.level].max_chain,q.strstart=0,q.block_start=0,q.lookahead=0,q.insert=0,q.match_length=q.prev_length=H0-1,q.match_available=0,q.ins_h=0}function cY(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=c1,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new i0.Buf16(DY*2),this.dyn_dtree=new i0.Buf16((2*FY+1)*2),this.bl_tree=new i0.Buf16((2*PY+1)*2),v6(this.dyn_ltree),v6(this.dyn_dtree),v6(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new i0.Buf16(uY+1),this.heap=new i0.Buf16(2*D4+1),v6(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new i0.Buf16(2*D4+1),v6(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function vV(q){var X;if(!q||!q.state)return O6(q,U2);if(q.total_in=q.total_out=0,q.data_type=NY,X=q.state,X.pending=0,X.pending_out=0,X.wrap<0)X.wrap=-X.wrap;return X.status=X.wrap?p1:a6,q.adler=X.wrap===2?0:1,X.last_flush=t6,H2._tr_init(X),b2}function RV(q){var X=vV(q);if(X===b2)_Y(q.state);return X}function pY(q,X){if(!q||!q.state)return U2;if(q.state.wrap!==2)return U2;return q.state.gzhead=X,b2}function OV(q,X,V,K,Q,Y){if(!q)return U2;var J=1;if(X===vY)X=6;if(K<0)J=0,K=-K;else if(K>15)J=2,K-=16;if(Q<1||Q>SY||V!==c1||K<8||K>15||X<0||X>9||Y<0||Y>wY)return O6(q,U2);if(K===8)K=9;var G=new cY;return q.state=G,G.strm=q,G.wrap=J,G.gzhead=null,G.w_bits=K,G.w_size=1<EV||X<0)return q?O6(q,U2):U2;if(K=q.state,!q.output||!q.input&&q.avail_in!==0||K.status===n8&&X!==w6)return O6(q,q.avail_out===0?F4:U2);if(K.strm=q,V=K.last_flush,K.last_flush=X,K.status===p1)if(K.wrap===2)if(q.adler=0,U0(K,31),U0(K,139),U0(K,8),!K.gzhead)U0(K,0),U0(K,0),U0(K,0),U0(K,0),U0(K,0),U0(K,K.level===9?2:K.strategy>=m1||K.level<2?4:0),U0(K,xY),K.status=a6;else{if(U0(K,(K.gzhead.text?1:0)+(K.gzhead.hcrc?2:0)+(!K.gzhead.extra?0:4)+(!K.gzhead.name?0:8)+(!K.gzhead.comment?0:16)),U0(K,K.gzhead.time&255),U0(K,K.gzhead.time>>8&255),U0(K,K.gzhead.time>>16&255),U0(K,K.gzhead.time>>24&255),U0(K,K.level===9?2:K.strategy>=m1||K.level<2?4:0),U0(K,K.gzhead.os&255),K.gzhead.extra&&K.gzhead.extra.length)U0(K,K.gzhead.extra.length&255),U0(K,K.gzhead.extra.length>>8&255);if(K.gzhead.hcrc)q.adler=B6(q.adler,K.pending_buf,K.pending,0);K.gzindex=0,K.status=u4}else{var J=c1+(K.w_bits-8<<4)<<8,G=-1;if(K.strategy>=m1||K.level<2)G=0;else if(K.level<6)G=1;else if(K.level===6)G=2;else G=3;if(J|=G<<6,K.strstart!==0)J|=gY;if(J+=31-J%31,K.status=a6,d8(K,J),K.strstart!==0)d8(K,q.adler>>>16),d8(K,q.adler&65535);q.adler=1}if(K.status===u4)if(K.gzhead.extra){Q=K.pending;while(K.gzindex<(K.gzhead.extra.length&65535)){if(K.pending===K.pending_buf_size){if(K.gzhead.hcrc&&K.pending>Q)q.adler=B6(q.adler,K.pending_buf,K.pending-Q,Q);if(T6(q),Q=K.pending,K.pending===K.pending_buf_size)break}U0(K,K.gzhead.extra[K.gzindex]&255),K.gzindex++}if(K.gzhead.hcrc&&K.pending>Q)q.adler=B6(q.adler,K.pending_buf,K.pending-Q,Q);if(K.gzindex===K.gzhead.extra.length)K.gzindex=0,K.status=f1}else K.status=f1;if(K.status===f1)if(K.gzhead.name){Q=K.pending;do{if(K.pending===K.pending_buf_size){if(K.gzhead.hcrc&&K.pending>Q)q.adler=B6(q.adler,K.pending_buf,K.pending-Q,Q);if(T6(q),Q=K.pending,K.pending===K.pending_buf_size){Y=1;break}}if(K.gzindexQ)q.adler=B6(q.adler,K.pending_buf,K.pending-Q,Q);if(Y===0)K.gzindex=0,K.status=l1}else K.status=l1;if(K.status===l1)if(K.gzhead.comment){Q=K.pending;do{if(K.pending===K.pending_buf_size){if(K.gzhead.hcrc&&K.pending>Q)q.adler=B6(q.adler,K.pending_buf,K.pending-Q,Q);if(T6(q),Q=K.pending,K.pending===K.pending_buf_size){Y=1;break}}if(K.gzindexQ)q.adler=B6(q.adler,K.pending_buf,K.pending-Q,Q);if(Y===0)K.status=_1}else K.status=_1;if(K.status===_1)if(K.gzhead.hcrc){if(K.pending+2>K.pending_buf_size)T6(q);if(K.pending+2<=K.pending_buf_size)U0(K,q.adler&255),U0(K,q.adler>>8&255),q.adler=0,K.status=a6}else K.status=a6;if(K.pending!==0){if(T6(q),q.avail_out===0)return K.last_flush=-1,b2}else if(q.avail_in===0&&LV(X)<=LV(V)&&X!==w6)return O6(q,F4);if(K.status===n8&&q.avail_in!==0)return O6(q,F4);if(q.avail_in!==0||K.lookahead!==0||X!==t6&&K.status!==n8){var W=K.strategy===m1?lY(K,X):K.strategy===OY?fY(K,X):b5[K.level].func(K,X);if(W===o6||W===m5)K.status=n8;if(W===h0||W===o6){if(q.avail_out===0)K.last_flush=-1;return b2}if(W===r8){if(X===LY)H2._tr_align(K);else if(X!==EV){if(H2._tr_stored_block(K,0,0,!1),X===BY){if(v6(K.head),K.lookahead===0)K.strstart=0,K.block_start=0,K.insert=0}}if(T6(q),q.avail_out===0)return K.last_flush=-1,b2}}if(X!==w6)return b2;if(K.wrap<=0)return jV;if(K.wrap===2)U0(K,q.adler&255),U0(K,q.adler>>8&255),U0(K,q.adler>>16&255),U0(K,q.adler>>24&255),U0(K,q.total_in&255),U0(K,q.total_in>>8&255),U0(K,q.total_in>>16&255),U0(K,q.total_in>>24&255);else d8(K,q.adler>>>16),d8(K,q.adler&65535);if(T6(q),K.wrap>0)K.wrap=-K.wrap;return K.pending!==0?b2:jV}function rY(q){var X;if(!q||!q.state)return U2;if(X=q.state.status,X!==p1&&X!==u4&&X!==f1&&X!==l1&&X!==_1&&X!==a6&&X!==n8)return O6(q,U2);return q.state=null,X===a6?O6(q,TY):b2}function iY(q,X){var V=X.length,K,Q,Y,J,G,W,Z,H;if(!q||!q.state)return U2;if(K=q.state,J=K.wrap,J===2||J===1&&K.status!==p1||K.lookahead)return U2;if(J===1)q.adler=BV(q.adler,X,V,0);if(K.wrap=0,V>=K.w_size){if(J===0)v6(K.head),K.strstart=0,K.block_start=0,K.insert=0;H=new i0.Buf8(K.w_size),i0.arraySet(H,X,V-K.w_size,K.w_size,0),X=H,V=K.w_size}G=q.avail_in,W=q.next_in,Z=q.input,q.avail_in=V,q.next_in=0,q.input=X,s6(K);while(K.lookahead>=H0){Q=K.strstart,Y=K.lookahead-(H0-1);do K.ins_h=(K.ins_h<{var d1=t2(),AV=!0,NV=!0;try{String.fromCharCode.apply(null,[0])}catch(q){AV=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(q){NV=!1}var i8=new d1.Buf8(256);for(f2=0;f2<256;f2++)i8[f2]=f2>=252?6:f2>=248?5:f2>=240?4:f2>=224?3:f2>=192?2:1;var f2;i8[254]=i8[254]=1;f5.string2buf=function(q){var X,V,K,Q,Y,J=q.length,G=0;for(Q=0;Q>>6,X[Y++]=128|V&63;else if(V<65536)X[Y++]=224|V>>>12,X[Y++]=128|V>>>6&63,X[Y++]=128|V&63;else X[Y++]=240|V>>>18,X[Y++]=128|V>>>12&63,X[Y++]=128|V>>>6&63,X[Y++]=128|V&63}return X};function SV(q,X){if(X<65534){if(q.subarray&&NV||!q.subarray&&AV)return String.fromCharCode.apply(null,d1.shrinkBuf(q,X))}var V="";for(var K=0;K4){G[K++]=65533,V+=Y-1;continue}Q&=Y===2?31:Y===3?15:7;while(Y>1&&V1){G[K++]=65533;continue}if(Q<65536)G[K++]=Q;else Q-=65536,G[K++]=55296|Q>>10&1023,G[K++]=56320|Q&1023}return SV(G,K)};f5.utf8border=function(q,X){var V;if(X=X||q.length,X>q.length)X=q.length;V=X-1;while(V>=0&&(q[V]&192)===128)V--;if(V<0)return X;if(V===0)return X;return V+i8[q[V]]>X?V:X}});var x4=g0((KW,yV)=>{function aY(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}yV.exports=aY});var FV=g0((s8)=>{var a8=wV(),o8=t2(),m4=g4(),f4=b1(),oY=x4(),hV=Object.prototype.toString,sY=0,b4=4,l5=0,$V=1,CV=2,tY=-1,eY=0,qJ=8;function e6(q){if(!(this instanceof e6))return new e6(q);this.options=o8.assign({level:tY,method:qJ,chunkSize:16384,windowBits:15,memLevel:8,strategy:eY,to:""},q||{});var X=this.options;if(X.raw&&X.windowBits>0)X.windowBits=-X.windowBits;else if(X.gzip&&X.windowBits>0&&X.windowBits<16)X.windowBits+=16;this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new oY,this.strm.avail_out=0;var V=a8.deflateInit2(this.strm,X.level,X.method,X.windowBits,X.memLevel,X.strategy);if(V!==l5)throw Error(f4[V]);if(X.header)a8.deflateSetHeader(this.strm,X.header);if(X.dictionary){var K;if(typeof X.dictionary==="string")K=m4.string2buf(X.dictionary);else if(hV.call(X.dictionary)==="[object ArrayBuffer]")K=new Uint8Array(X.dictionary);else K=X.dictionary;if(V=a8.deflateSetDictionary(this.strm,K),V!==l5)throw Error(f4[V]);this._dict_set=!0}}e6.prototype.push=function(q,X){var V=this.strm,K=this.options.chunkSize,Q,Y;if(this.ended)return!1;if(Y=X===~~X?X:X===!0?b4:sY,typeof q==="string")V.input=m4.string2buf(q);else if(hV.call(q)==="[object ArrayBuffer]")V.input=new Uint8Array(q);else V.input=q;V.next_in=0,V.avail_in=V.input.length;do{if(V.avail_out===0)V.output=new o8.Buf8(K),V.next_out=0,V.avail_out=K;if(Q=a8.deflate(V,Y),Q!==$V&&Q!==l5)return this.onEnd(Q),this.ended=!0,!1;if(V.avail_out===0||V.avail_in===0&&(Y===b4||Y===CV))if(this.options.to==="string")this.onData(m4.buf2binstring(o8.shrinkBuf(V.output,V.next_out)));else this.onData(o8.shrinkBuf(V.output,V.next_out))}while((V.avail_in>0||V.avail_out===0)&&Q!==$V);if(Y===b4)return Q=a8.deflateEnd(this.strm),this.onEnd(Q),this.ended=!0,Q===l5;if(Y===CV)return this.onEnd(l5),V.avail_out=0,!0;return!0};e6.prototype.onData=function(q){this.chunks.push(q)};e6.prototype.onEnd=function(q){if(q===l5)if(this.options.to==="string")this.result=this.chunks.join("");else this.result=o8.flattenChunks(this.chunks);this.chunks=[],this.err=q,this.msg=this.strm.msg};function l4(q,X){var V=new e6(X);if(V.push(q,!0),V.err)throw V.msg||f4[V.err];return V.result}function XJ(q,X){return X=X||{},X.raw=!0,l4(q,X)}function VJ(q,X){return X=X||{},X.gzip=!0,l4(q,X)}s8.Deflate=e6;s8.deflate=l4;s8.deflateRaw=XJ;s8.gzip=VJ});var DV=g0((YW,PV)=>{var n1=30,KJ=12;PV.exports=function(X,V){var K,Q,Y,J,G,W,Z,H,U,z,k,M,j,B,L,O,N,R,v,w,$,S,h,b,C;K=X.state,Q=X.next_in,b=X.input,Y=Q+(X.avail_in-5),J=X.next_out,C=X.output,G=J-(V-X.avail_out),W=J+(X.avail_out-257),Z=K.dmax,H=K.wsize,U=K.whave,z=K.wnext,k=K.window,M=K.hold,j=K.bits,B=K.lencode,L=K.distcode,O=(1<>>24,M>>>=v,j-=v,v=R>>>16&255,v===0)C[J++]=R&65535;else if(v&16){if(w=R&65535,v&=15,v){if(j>>=v,j-=v}if(j<15)M+=b[Q++]<>>24,M>>>=v,j-=v,v=R>>>16&255,v&16){if($=R&65535,v&=15,jZ){X.msg="invalid distance too far back",K.mode=n1;break q}if(M>>>=v,j-=v,v=J-G,$>v){if(v=$-v,v>U){if(K.sane){X.msg="invalid distance too far back",K.mode=n1;break q}}if(S=0,h=k,z===0){if(S+=H-v,v2)C[J++]=h[S++],C[J++]=h[S++],C[J++]=h[S++],w-=3;if(w){if(C[J++]=h[S++],w>1)C[J++]=h[S++]}}else{S=J-$;do C[J++]=C[S++],C[J++]=C[S++],C[J++]=C[S++],w-=3;while(w>2);if(w){if(C[J++]=C[S++],w>1)C[J++]=C[S++]}}}else if((v&64)===0){R=L[(R&65535)+(M&(1<>3,Q-=w,j-=w<<3,M&=(1<{var uV=t2(),_5=15,gV=852,xV=592,bV=0,_4=1,mV=2,QJ=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],YJ=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],JJ=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],GJ=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];fV.exports=function(X,V,K,Q,Y,J,G,W){var Z=W.bits,H=0,U=0,z=0,k=0,M=0,j=0,B=0,L=0,O=0,N=0,R,v,w,$,S,h=null,b=0,C,D=new uV.Buf16(_5+1),l=new uV.Buf16(_5+1),u=null,q0=0,J0,r,I0;for(H=0;H<=_5;H++)D[H]=0;for(U=0;U=1;k--)if(D[k]!==0)break;if(M>k)M=k;if(k===0)return Y[J++]=20971520,Y[J++]=20971520,W.bits=1,0;for(z=1;z0&&(X===bV||k!==1))return-1;l[1]=0;for(H=1;H<_5;H++)l[H+1]=l[H]+D[H];for(U=0;UgV||X===mV&&O>xV)return 1;for(;;){if(J0=H-B,G[U]C)r=u[q0+G[U]],I0=h[b+G[U]];else r=96,I0=0;R=1<>B)+v]=J0<<24|r<<16|I0|0;while(v!==0);R=1<>=1;if(R!==0)N&=R-1,N+=R;else N=0;if(U++,--D[H]===0){if(H===k)break;H=V[K+G[U]]}if(H>M&&(N&$)!==w){if(B===0)B=M;S+=z,j=H-B,L=1<gV||X===mV&&O>xV)return 1;w=N&$,Y[w]=M<<24|j<<16|S-J|0}}if(N!==0)Y[S+N]=H-B<<24|4194304|0;return W.bits=M,0}});var R9=g0((w2)=>{var Q2=t2(),i4=C4(),l2=h4(),ZJ=DV(),t8=lV(),WJ=0,M9=1,k9=2,_V=4,HJ=5,r1=6,q5=0,UJ=1,zJ=2,z2=-2,I9=-3,a4=-4,MJ=-5,cV=8,E9=1,pV=2,dV=3,nV=4,rV=5,iV=6,aV=7,oV=8,sV=9,tV=10,o1=11,q6=12,c4=13,eV=14,p4=15,q9=16,X9=17,V9=18,K9=19,i1=20,a1=21,Q9=22,Y9=23,J9=24,G9=25,Z9=26,d4=27,W9=28,H9=29,L0=30,o4=31,kJ=32,IJ=852,EJ=592,jJ=15,LJ=jJ;function U9(q){return(q>>>24&255)+(q>>>8&65280)+((q&65280)<<8)+((q&255)<<24)}function BJ(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Q2.Buf16(320),this.work=new Q2.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function j9(q){var X;if(!q||!q.state)return z2;if(X=q.state,q.total_in=q.total_out=X.total=0,q.msg="",X.wrap)q.adler=X.wrap&1;return X.mode=E9,X.last=0,X.havedict=0,X.dmax=32768,X.head=null,X.hold=0,X.bits=0,X.lencode=X.lendyn=new Q2.Buf32(IJ),X.distcode=X.distdyn=new Q2.Buf32(EJ),X.sane=1,X.back=-1,q5}function L9(q){var X;if(!q||!q.state)return z2;return X=q.state,X.wsize=0,X.whave=0,X.wnext=0,j9(q)}function B9(q,X){var V,K;if(!q||!q.state)return z2;if(K=q.state,X<0)V=0,X=-X;else if(V=(X>>4)+1,X<48)X&=15;if(X&&(X<8||X>15))return z2;if(K.window!==null&&K.wbits!==X)K.window=null;return K.wrap=V,K.wbits=X,L9(q)}function T9(q,X){var V,K;if(!q)return z2;if(K=new BJ,q.state=K,K.window=null,V=B9(q,X),V!==q5)q.state=null;return V}function TJ(q){return T9(q,LJ)}var z9=!0,n4,r4;function vJ(q){if(z9){var X;n4=new Q2.Buf32(512),r4=new Q2.Buf32(32),X=0;while(X<144)q.lens[X++]=8;while(X<256)q.lens[X++]=9;while(X<280)q.lens[X++]=7;while(X<288)q.lens[X++]=8;t8(M9,q.lens,0,288,n4,0,q.work,{bits:9}),X=0;while(X<32)q.lens[X++]=5;t8(k9,q.lens,0,32,r4,0,q.work,{bits:5}),z9=!1}q.lencode=n4,q.lenbits=9,q.distcode=r4,q.distbits=5}function v9(q,X,V,K){var Q,Y=q.state;if(Y.window===null)Y.wsize=1<=Y.wsize)Q2.arraySet(Y.window,X,V-Y.wsize,Y.wsize,0),Y.wnext=0,Y.whave=Y.wsize;else{if(Q=Y.wsize-Y.wnext,Q>K)Q=K;if(Q2.arraySet(Y.window,X,V-K,Q,Y.wnext),K-=Q,K)Q2.arraySet(Y.window,X,V-K,K,0),Y.wnext=K,Y.whave=Y.wsize;else{if(Y.wnext+=Q,Y.wnext===Y.wsize)Y.wnext=0;if(Y.whave>>8&255,V.check=l2(V.check,h,2,0),Z=0,H=0,V.mode=pV;break}if(V.flags=0,V.head)V.head.done=!1;if(!(V.wrap&1)||(((Z&255)<<8)+(Z>>8))%31){q.msg="incorrect header check",V.mode=L0;break}if((Z&15)!==cV){q.msg="unknown compression method",V.mode=L0;break}if(Z>>>=4,H-=4,$=(Z&15)+8,V.wbits===0)V.wbits=$;else if($>V.wbits){q.msg="invalid window size",V.mode=L0;break}V.dmax=1<<$,q.adler=V.check=1,V.mode=Z&512?tV:q6,Z=0,H=0;break;case pV:while(H<16){if(G===0)break q;G--,Z+=K[Y++]<>8&1;if(V.flags&512)h[0]=Z&255,h[1]=Z>>>8&255,V.check=l2(V.check,h,2,0);Z=0,H=0,V.mode=dV;case dV:while(H<32){if(G===0)break q;G--,Z+=K[Y++]<>>8&255,h[2]=Z>>>16&255,h[3]=Z>>>24&255,V.check=l2(V.check,h,4,0);Z=0,H=0,V.mode=nV;case nV:while(H<16){if(G===0)break q;G--,Z+=K[Y++]<>8;if(V.flags&512)h[0]=Z&255,h[1]=Z>>>8&255,V.check=l2(V.check,h,2,0);Z=0,H=0,V.mode=rV;case rV:if(V.flags&1024){while(H<16){if(G===0)break q;G--,Z+=K[Y++]<>>8&255,V.check=l2(V.check,h,2,0);Z=0,H=0}else if(V.head)V.head.extra=null;V.mode=iV;case iV:if(V.flags&1024){if(k=V.length,k>G)k=G;if(k){if(V.head){if($=V.head.extra_len-V.length,!V.head.extra)V.head.extra=Array(V.head.extra_len);Q2.arraySet(V.head.extra,K,Y,k,$)}if(V.flags&512)V.check=l2(V.check,K,k,Y);G-=k,Y+=k,V.length-=k}if(V.length)break q}V.length=0,V.mode=aV;case aV:if(V.flags&2048){if(G===0)break q;k=0;do if($=K[Y+k++],V.head&&$&&V.length<65536)V.head.name+=String.fromCharCode($);while($&&k>9&1,V.head.done=!0;q.adler=V.check=0,V.mode=q6;break;case tV:while(H<32){if(G===0)break q;G--,Z+=K[Y++]<>>=H&7,H-=H&7,V.mode=d4;break}while(H<3){if(G===0)break q;G--,Z+=K[Y++]<>>=1,H-=1,Z&3){case 0:V.mode=eV;break;case 1:if(vJ(V),V.mode=i1,X===r1){Z>>>=2,H-=2;break q}break;case 2:V.mode=X9;break;case 3:q.msg="invalid block type",V.mode=L0}Z>>>=2,H-=2;break;case eV:Z>>>=H&7,H-=H&7;while(H<32){if(G===0)break q;G--,Z+=K[Y++]<>>16^65535)){q.msg="invalid stored block lengths",V.mode=L0;break}if(V.length=Z&65535,Z=0,H=0,V.mode=p4,X===r1)break q;case p4:V.mode=q9;case q9:if(k=V.length,k){if(k>G)k=G;if(k>W)k=W;if(k===0)break q;Q2.arraySet(Q,K,Y,k,J),G-=k,Y+=k,W-=k,J+=k,V.length-=k;break}V.mode=q6;break;case X9:while(H<14){if(G===0)break q;G--,Z+=K[Y++]<>>=5,H-=5,V.ndist=(Z&31)+1,Z>>>=5,H-=5,V.ncode=(Z&15)+4,Z>>>=4,H-=4,V.nlen>286||V.ndist>30){q.msg="too many length or distance symbols",V.mode=L0;break}V.have=0,V.mode=V9;case V9:while(V.have>>=3,H-=3}while(V.have<19)V.lens[D[V.have++]]=0;if(V.lencode=V.lendyn,V.lenbits=7,b={bits:V.lenbits},S=t8(WJ,V.lens,0,19,V.lencode,0,V.work,b),V.lenbits=b.bits,S){q.msg="invalid code lengths set",V.mode=L0;break}V.have=0,V.mode=K9;case K9:while(V.have>>24,O=B>>>16&255,N=B&65535,L<=H)break;if(G===0)break q;G--,Z+=K[Y++]<>>=L,H-=L,V.lens[V.have++]=N;else{if(N===16){C=L+2;while(H>>=L,H-=L,V.have===0){q.msg="invalid bit length repeat",V.mode=L0;break}$=V.lens[V.have-1],k=3+(Z&3),Z>>>=2,H-=2}else if(N===17){C=L+3;while(H>>=L,H-=L,$=0,k=3+(Z&7),Z>>>=3,H-=3}else{C=L+7;while(H>>=L,H-=L,$=0,k=11+(Z&127),Z>>>=7,H-=7}if(V.have+k>V.nlen+V.ndist){q.msg="invalid bit length repeat",V.mode=L0;break}while(k--)V.lens[V.have++]=$}}if(V.mode===L0)break;if(V.lens[256]===0){q.msg="invalid code -- missing end-of-block",V.mode=L0;break}if(V.lenbits=9,b={bits:V.lenbits},S=t8(M9,V.lens,0,V.nlen,V.lencode,0,V.work,b),V.lenbits=b.bits,S){q.msg="invalid literal/lengths set",V.mode=L0;break}if(V.distbits=6,V.distcode=V.distdyn,b={bits:V.distbits},S=t8(k9,V.lens,V.nlen,V.ndist,V.distcode,0,V.work,b),V.distbits=b.bits,S){q.msg="invalid distances set",V.mode=L0;break}if(V.mode=i1,X===r1)break q;case i1:V.mode=a1;case a1:if(G>=6&&W>=258){if(q.next_out=J,q.avail_out=W,q.next_in=Y,q.avail_in=G,V.hold=Z,V.bits=H,ZJ(q,z),J=q.next_out,Q=q.output,W=q.avail_out,Y=q.next_in,K=q.input,G=q.avail_in,Z=V.hold,H=V.bits,V.mode===q6)V.back=-1;break}V.back=0;for(;;){if(B=V.lencode[Z&(1<>>24,O=B>>>16&255,N=B&65535,L<=H)break;if(G===0)break q;G--,Z+=K[Y++]<>R)],L=B>>>24,O=B>>>16&255,N=B&65535,R+L<=H)break;if(G===0)break q;G--,Z+=K[Y++]<>>=R,H-=R,V.back+=R}if(Z>>>=L,H-=L,V.back+=L,V.length=N,O===0){V.mode=Z9;break}if(O&32){V.back=-1,V.mode=q6;break}if(O&64){q.msg="invalid literal/length code",V.mode=L0;break}V.extra=O&15,V.mode=Q9;case Q9:if(V.extra){C=V.extra;while(H>>=V.extra,H-=V.extra,V.back+=V.extra}V.was=V.length,V.mode=Y9;case Y9:for(;;){if(B=V.distcode[Z&(1<>>24,O=B>>>16&255,N=B&65535,L<=H)break;if(G===0)break q;G--,Z+=K[Y++]<>R)],L=B>>>24,O=B>>>16&255,N=B&65535,R+L<=H)break;if(G===0)break q;G--,Z+=K[Y++]<>>=R,H-=R,V.back+=R}if(Z>>>=L,H-=L,V.back+=L,O&64){q.msg="invalid distance code",V.mode=L0;break}V.offset=N,V.extra=O&15,V.mode=J9;case J9:if(V.extra){C=V.extra;while(H>>=V.extra,H-=V.extra,V.back+=V.extra}if(V.offset>V.dmax){q.msg="invalid distance too far back",V.mode=L0;break}V.mode=G9;case G9:if(W===0)break q;if(k=z-W,V.offset>k){if(k=V.offset-k,k>V.whave){if(V.sane){q.msg="invalid distance too far back",V.mode=L0;break}}if(k>V.wnext)k-=V.wnext,M=V.wsize-k;else M=V.wnext-k;if(k>V.length)k=V.length;j=V.window}else j=Q,M=J-V.offset,k=V.length;if(k>W)k=W;W-=k,V.length-=k;do Q[J++]=j[M++];while(--k);if(V.length===0)V.mode=a1;break;case Z9:if(W===0)break q;Q[J++]=V.length,W--,V.mode=a1;break;case d4:if(V.wrap){while(H<32){if(G===0)break q;G--,Z|=K[Y++]<{O9.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}});var A9=g0((WW,w9)=>{function NJ(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}w9.exports=NJ});var S9=g0((q1)=>{var c5=R9(),e8=t2(),s1=g4(),N0=s4(),t4=b1(),SJ=x4(),yJ=A9(),N9=Object.prototype.toString;function X5(q){if(!(this instanceof X5))return new X5(q);this.options=e8.assign({chunkSize:16384,windowBits:0,to:""},q||{});var X=this.options;if(X.raw&&X.windowBits>=0&&X.windowBits<16){if(X.windowBits=-X.windowBits,X.windowBits===0)X.windowBits=-15}if(X.windowBits>=0&&X.windowBits<16&&!(q&&q.windowBits))X.windowBits+=32;if(X.windowBits>15&&X.windowBits<48){if((X.windowBits&15)===0)X.windowBits|=15}this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new SJ,this.strm.avail_out=0;var V=c5.inflateInit2(this.strm,X.windowBits);if(V!==N0.Z_OK)throw Error(t4[V]);if(this.header=new yJ,c5.inflateGetHeader(this.strm,this.header),X.dictionary){if(typeof X.dictionary==="string")X.dictionary=s1.string2buf(X.dictionary);else if(N9.call(X.dictionary)==="[object ArrayBuffer]")X.dictionary=new Uint8Array(X.dictionary);if(X.raw){if(V=c5.inflateSetDictionary(this.strm,X.dictionary),V!==N0.Z_OK)throw Error(t4[V])}}}X5.prototype.push=function(q,X){var V=this.strm,K=this.options.chunkSize,Q=this.options.dictionary,Y,J,G,W,Z,H=!1;if(this.ended)return!1;if(J=X===~~X?X:X===!0?N0.Z_FINISH:N0.Z_NO_FLUSH,typeof q==="string")V.input=s1.binstring2buf(q);else if(N9.call(q)==="[object ArrayBuffer]")V.input=new Uint8Array(q);else V.input=q;V.next_in=0,V.avail_in=V.input.length;do{if(V.avail_out===0)V.output=new e8.Buf8(K),V.next_out=0,V.avail_out=K;if(Y=c5.inflate(V,N0.Z_NO_FLUSH),Y===N0.Z_NEED_DICT&&Q)Y=c5.inflateSetDictionary(this.strm,Q);if(Y===N0.Z_BUF_ERROR&&H===!0)Y=N0.Z_OK,H=!1;if(Y!==N0.Z_STREAM_END&&Y!==N0.Z_OK)return this.onEnd(Y),this.ended=!0,!1;if(V.next_out){if(V.avail_out===0||Y===N0.Z_STREAM_END||V.avail_in===0&&(J===N0.Z_FINISH||J===N0.Z_SYNC_FLUSH))if(this.options.to==="string"){if(G=s1.utf8border(V.output,V.next_out),W=V.next_out-G,Z=s1.buf2string(V.output,G),V.next_out=W,V.avail_out=K-W,W)e8.arraySet(V.output,V.output,G,W,0);this.onData(Z)}else this.onData(e8.shrinkBuf(V.output,V.next_out))}if(V.avail_in===0&&V.avail_out===0)H=!0}while((V.avail_in>0||V.avail_out===0)&&Y!==N0.Z_STREAM_END);if(Y===N0.Z_STREAM_END)J=N0.Z_FINISH;if(J===N0.Z_FINISH)return Y=c5.inflateEnd(this.strm),this.onEnd(Y),this.ended=!0,Y===N0.Z_OK;if(J===N0.Z_SYNC_FLUSH)return this.onEnd(N0.Z_OK),V.avail_out=0,!0;return!0};X5.prototype.onData=function(q){this.chunks.push(q)};X5.prototype.onEnd=function(q){if(q===N0.Z_OK)if(this.options.to==="string")this.result=this.chunks.join("");else this.result=e8.flattenChunks(this.chunks);this.chunks=[],this.err=q,this.msg=this.strm.msg};function e4(q,X){var V=new X5(X);if(V.push(q,!0),V.err)throw V.msg||t4[V.err];return V.result}function $J(q,X){return X=X||{},X.raw=!0,e4(q,X)}q1.Inflate=X5;q1.inflate=e4;q1.inflateRaw=$J;q1.ungzip=e4});var X1=g0((UW,$9)=>{var CJ=t2().assign,hJ=FV(),FJ=S9(),PJ=s4(),y9={};CJ(y9,hJ,FJ,PJ);$9.exports=y9});var zX=globalThis;if(typeof zX.global>"u")zX.global=globalThis;var C2=[],W2=[],lq="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(c6=0,MX=lq.length;c60)throw Error("Invalid string. Length must be a multiple of 4");var V=q.indexOf("=");if(V===-1)V=X;var K=V===X?0:4-V%4;return[V,K]}function VQ(q,X){return(q+X)*3/4-X}function KQ(q){var X,V=XQ(q),K=V[0],Q=V[1],Y=new Uint8Array(VQ(K,Q)),J=0,G=Q>0?K-4:K,W;for(W=0;W>16&255,Y[J++]=X>>8&255,Y[J++]=X&255;if(Q===2)X=W2[q.charCodeAt(W)]<<2|W2[q.charCodeAt(W+1)]>>4,Y[J++]=X&255;if(Q===1)X=W2[q.charCodeAt(W)]<<10|W2[q.charCodeAt(W+1)]<<4|W2[q.charCodeAt(W+2)]>>2,Y[J++]=X>>8&255,Y[J++]=X&255;return Y}function QQ(q){return C2[q>>18&63]+C2[q>>12&63]+C2[q>>6&63]+C2[q&63]}function YQ(q,X,V){var K,Q=[];for(var Y=X;YG?G:J+Y));if(K===1)X=q[V-1],Q.push(C2[X>>2]+C2[X<<4&63]+"==");else if(K===2)X=(q[V-2]<<8)+q[V-1],Q.push(C2[X>>10]+C2[X>>4&63]+C2[X<<2&63]+"=");return Q.join("")}function $1(q,X,V,K,Q){var Y,J,G=Q*8-K-1,W=(1<>1,H=-7,U=V?Q-1:0,z=V?-1:1,k=q[X+U];U+=z,Y=k&(1<<-H)-1,k>>=-H,H+=G;for(;H>0;Y=Y*256+q[X+U],U+=z,H-=8);J=Y&(1<<-H)-1,Y>>=-H,H+=K;for(;H>0;J=J*256+q[X+U],U+=z,H-=8);if(Y===0)Y=1-Z;else if(Y===W)return J?NaN:(k?-1:1)*(1/0);else J=J+Math.pow(2,K),Y=Y-Z;return(k?-1:1)*J*Math.pow(2,Y-K)}function BX(q,X,V,K,Q,Y){var J,G,W,Z=Y*8-Q-1,H=(1<>1,z=Q===23?Math.pow(2,-24)-Math.pow(2,-77):0,k=K?0:Y-1,M=K?1:-1,j=X<0||X===0&&1/X<0?1:0;if(X=Math.abs(X),isNaN(X)||X===1/0)G=isNaN(X)?1:0,J=H;else{if(J=Math.floor(Math.log(X)/Math.LN2),X*(W=Math.pow(2,-J))<1)J--,W*=2;if(J+U>=1)X+=z/W;else X+=z*Math.pow(2,1-U);if(X*W>=2)J++,W/=2;if(J+U>=H)G=0,J=H;else if(J+U>=1)G=(X*W-1)*Math.pow(2,Q),J=J+U;else G=X*Math.pow(2,U-1)*Math.pow(2,Q),J=0}for(;Q>=8;q[V+k]=G&255,k+=M,G/=256,Q-=8);J=J<0;q[V+k]=J&255,k+=M,J/=256,Z-=8);q[V+k-M]|=j*128}var IX=typeof Symbol==="function"&&typeof Symbol.for==="function"?Symbol.for("nodejs.util.inspect.custom"):null,JQ=50,_q=2147483647;var{btoa:$3,atob:C3,File:h3,Blob:F3}=globalThis;function a2(q){if(q>_q)throw RangeError('The value "'+q+'" is invalid for option "size"');let X=new Uint8Array(q);return Object.setPrototypeOf(X,y.prototype),X}function rq(q,X,V){return class extends V{constructor(){super();Object.defineProperty(this,"message",{value:X.apply(this,arguments),writable:!0,configurable:!0}),this.name=`${this.name} [${q}]`,this.stack,delete this.name}get code(){return q}set code(K){Object.defineProperty(this,"code",{configurable:!0,enumerable:!0,value:K,writable:!0})}toString(){return`${this.name} [${q}]: ${this.message}`}}}var GQ=rq("ERR_BUFFER_OUT_OF_BOUNDS",function(q){if(q)return`${q} is outside of buffer bounds`;return"Attempt to access memory outside buffer bounds"},RangeError),ZQ=rq("ERR_INVALID_ARG_TYPE",function(q,X){return`The "${q}" argument must be of type number. Received type ${typeof X}`},TypeError),cq=rq("ERR_OUT_OF_RANGE",function(q,X,V){let K=`The value of "${q}" is out of range.`,Q=V;if(Number.isInteger(V)&&Math.abs(V)>4294967296)Q=LX(String(V));else if(typeof V==="bigint"){if(Q=String(V),V>BigInt(2)**BigInt(32)||V<-(BigInt(2)**BigInt(32)))Q=LX(Q);Q+="n"}return K+=` It must be ${X}. Received ${Q}`,K},RangeError);function y(q,X,V){if(typeof q==="number"){if(typeof X==="string")throw TypeError('The "string" argument must be of type string. Received type number');return iq(q)}return TX(q,X,V)}Object.defineProperty(y.prototype,"parent",{enumerable:!0,get:function(){if(!y.isBuffer(this))return;return this.buffer}});Object.defineProperty(y.prototype,"offset",{enumerable:!0,get:function(){if(!y.isBuffer(this))return;return this.byteOffset}});y.poolSize=8192;function TX(q,X,V){if(typeof q==="string")return HQ(q,X);if(ArrayBuffer.isView(q))return UQ(q);if(q==null)throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof q);if(h2(q,ArrayBuffer)||q&&h2(q.buffer,ArrayBuffer))return dq(q,X,V);if(typeof SharedArrayBuffer<"u"&&(h2(q,SharedArrayBuffer)||q&&h2(q.buffer,SharedArrayBuffer)))return dq(q,X,V);if(typeof q==="number")throw TypeError('The "value" argument must not be of type number. Received type number');let K=q.valueOf&&q.valueOf();if(K!=null&&K!==q)return y.from(K,X,V);let Q=zQ(q);if(Q)return Q;if(typeof Symbol<"u"&&Symbol.toPrimitive!=null&&typeof q[Symbol.toPrimitive]==="function")return y.from(q[Symbol.toPrimitive]("string"),X,V);throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof q)}y.from=function(q,X,V){return TX(q,X,V)};Object.setPrototypeOf(y.prototype,Uint8Array.prototype);Object.setPrototypeOf(y,Uint8Array);function vX(q){if(typeof q!=="number")throw TypeError('"size" argument must be of type number');else if(q<0)throw RangeError('The value "'+q+'" is invalid for option "size"')}function WQ(q,X,V){if(vX(q),q<=0)return a2(q);if(X!==void 0)return typeof V==="string"?a2(q).fill(X,V):a2(q).fill(X);return a2(q)}y.alloc=function(q,X,V){return WQ(q,X,V)};function iq(q){return vX(q),a2(q<0?0:aq(q)|0)}y.allocUnsafe=function(q){return iq(q)};y.allocUnsafeSlow=function(q){return iq(q)};function HQ(q,X){if(typeof X!=="string"||X==="")X="utf8";if(!y.isEncoding(X))throw TypeError("Unknown encoding: "+X);let V=RX(q,X)|0,K=a2(V),Q=K.write(q,X);if(Q!==V)K=K.slice(0,Q);return K}function pq(q){let X=q.length<0?0:aq(q.length)|0,V=a2(X);for(let K=0;K=_q)throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+_q.toString(16)+" bytes");return q|0}y.isBuffer=function(q){return q!=null&&q._isBuffer===!0&&q!==y.prototype};y.compare=function(q,X){if(h2(q,Uint8Array))q=y.from(q,q.offset,q.byteLength);if(h2(X,Uint8Array))X=y.from(X,X.offset,X.byteLength);if(!y.isBuffer(q)||!y.isBuffer(X))throw TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(q===X)return 0;let V=q.length,K=X.length;for(let Q=0,Y=Math.min(V,K);QK.length){if(!y.isBuffer(Y))Y=y.from(Y);Y.copy(K,Q)}else Uint8Array.prototype.set.call(K,Y,Q);else if(!y.isBuffer(Y))throw TypeError('"list" argument must be an Array of Buffers');else Y.copy(K,Q);Q+=Y.length}return K};function RX(q,X){if(y.isBuffer(q))return q.length;if(ArrayBuffer.isView(q)||h2(q,ArrayBuffer))return q.byteLength;if(typeof q!=="string")throw TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof q);let V=q.length,K=arguments.length>2&&arguments[2]===!0;if(!K&&V===0)return 0;let Q=!1;for(;;)switch(X){case"ascii":case"latin1":case"binary":return V;case"utf8":case"utf-8":return nq(q).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return V*2;case"hex":return V>>>1;case"base64":return hX(q).length;default:if(Q)return K?-1:nq(q).length;X=(""+X).toLowerCase(),Q=!0}}y.byteLength=RX;function MQ(q,X,V){let K=!1;if(X===void 0||X<0)X=0;if(X>this.length)return"";if(V===void 0||V>this.length)V=this.length;if(V<=0)return"";if(V>>>=0,X>>>=0,V<=X)return"";if(!q)q="utf8";while(!0)switch(q){case"hex":return OQ(this,X,V);case"utf8":case"utf-8":return wX(this,X,V);case"ascii":return vQ(this,X,V);case"latin1":case"binary":return RQ(this,X,V);case"base64":return BQ(this,X,V);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return wQ(this,X,V);default:if(K)throw TypeError("Unknown encoding: "+q);q=(q+"").toLowerCase(),K=!0}}y.prototype._isBuffer=!0;function p6(q,X,V){let K=q[X];q[X]=q[V],q[V]=K}y.prototype.swap16=function(){let q=this.length;if(q%2!==0)throw RangeError("Buffer size must be a multiple of 16-bits");for(let X=0;XX)q+=" ... ";return""};if(IX)y.prototype[IX]=y.prototype.inspect;y.prototype.compare=function(q,X,V,K,Q){if(h2(q,Uint8Array))q=y.from(q,q.offset,q.byteLength);if(!y.isBuffer(q))throw TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof q);if(X===void 0)X=0;if(V===void 0)V=q?q.length:0;if(K===void 0)K=0;if(Q===void 0)Q=this.length;if(X<0||V>q.length||K<0||Q>this.length)throw RangeError("out of range index");if(K>=Q&&X>=V)return 0;if(K>=Q)return-1;if(X>=V)return 1;if(X>>>=0,V>>>=0,K>>>=0,Q>>>=0,this===q)return 0;let Y=Q-K,J=V-X,G=Math.min(Y,J),W=this.slice(K,Q),Z=q.slice(X,V);for(let H=0;H2147483647)V=2147483647;else if(V<-2147483648)V=-2147483648;if(V=+V,Number.isNaN(V))V=Q?0:q.length-1;if(V<0)V=q.length+V;if(V>=q.length)if(Q)return-1;else V=q.length-1;else if(V<0)if(Q)V=0;else return-1;if(typeof X==="string")X=y.from(X,K);if(y.isBuffer(X)){if(X.length===0)return-1;return EX(q,X,V,K,Q)}else if(typeof X==="number"){if(X=X&255,typeof Uint8Array.prototype.indexOf==="function")if(Q)return Uint8Array.prototype.indexOf.call(q,X,V);else return Uint8Array.prototype.lastIndexOf.call(q,X,V);return EX(q,[X],V,K,Q)}throw TypeError("val must be string, number or Buffer")}function EX(q,X,V,K,Q){let Y=1,J=q.length,G=X.length;if(K!==void 0){if(K=String(K).toLowerCase(),K==="ucs2"||K==="ucs-2"||K==="utf16le"||K==="utf-16le"){if(q.length<2||X.length<2)return-1;Y=2,J/=2,G/=2,V/=2}}function W(H,U){if(Y===1)return H[U];else return H.readUInt16BE(U*Y)}let Z;if(Q){let H=-1;for(Z=V;ZJ)V=J-G;for(Z=V;Z>=0;Z--){let H=!0;for(let U=0;UQ)K=Q;let Y=X.length;if(K>Y/2)K=Y/2;let J;for(J=0;J>>0,isFinite(V)){if(V=V>>>0,K===void 0)K="utf8"}else K=V,V=void 0;else throw Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");let Q=this.length-X;if(V===void 0||V>Q)V=Q;if(q.length>0&&(V<0||X<0)||X>this.length)throw RangeError("Attempt to write outside buffer bounds");if(!K)K="utf8";let Y=!1;for(;;)switch(K){case"hex":return kQ(this,q,X,V);case"utf8":case"utf-8":return IQ(this,q,X,V);case"ascii":case"latin1":case"binary":return EQ(this,q,X,V);case"base64":return jQ(this,q,X,V);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return LQ(this,q,X,V);default:if(Y)throw TypeError("Unknown encoding: "+K);K=(""+K).toLowerCase(),Y=!0}};y.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function BQ(q,X,V){if(X===0&&V===q.length)return kX(q);else return kX(q.slice(X,V))}function wX(q,X,V){V=Math.min(q.length,V);let K=[],Q=X;while(Q239?4:Y>223?3:Y>191?2:1;if(Q+G<=V){let W,Z,H,U;switch(G){case 1:if(Y<128)J=Y;break;case 2:if(W=q[Q+1],(W&192)===128){if(U=(Y&31)<<6|W&63,U>127)J=U}break;case 3:if(W=q[Q+1],Z=q[Q+2],(W&192)===128&&(Z&192)===128){if(U=(Y&15)<<12|(W&63)<<6|Z&63,U>2047&&(U<55296||U>57343))J=U}break;case 4:if(W=q[Q+1],Z=q[Q+2],H=q[Q+3],(W&192)===128&&(Z&192)===128&&(H&192)===128){if(U=(Y&15)<<18|(W&63)<<12|(Z&63)<<6|H&63,U>65535&&U<1114112)J=U}}}if(J===null)J=65533,G=1;else if(J>65535)J-=65536,K.push(J>>>10&1023|55296),J=56320|J&1023;K.push(J),Q+=G}return TQ(K)}var jX=4096;function TQ(q){let X=q.length;if(X<=jX)return String.fromCharCode.apply(String,q);let V="",K=0;while(KK)V=K;let Q="";for(let Y=X;YV)q=V;if(X<0){if(X+=V,X<0)X=0}else if(X>V)X=V;if(XV)throw RangeError("Trying to access beyond buffer length")}y.prototype.readUintLE=y.prototype.readUIntLE=function(q,X,V){if(q=q>>>0,X=X>>>0,!V)D0(q,X,this.length);let K=this[q],Q=1,Y=0;while(++Y>>0,X=X>>>0,!V)D0(q,X,this.length);let K=this[q+--X],Q=1;while(X>0&&(Q*=256))K+=this[q+--X]*Q;return K};y.prototype.readUint8=y.prototype.readUInt8=function(q,X){if(q=q>>>0,!X)D0(q,1,this.length);return this[q]};y.prototype.readUint16LE=y.prototype.readUInt16LE=function(q,X){if(q=q>>>0,!X)D0(q,2,this.length);return this[q]|this[q+1]<<8};y.prototype.readUint16BE=y.prototype.readUInt16BE=function(q,X){if(q=q>>>0,!X)D0(q,2,this.length);return this[q]<<8|this[q+1]};y.prototype.readUint32LE=y.prototype.readUInt32LE=function(q,X){if(q=q>>>0,!X)D0(q,4,this.length);return(this[q]|this[q+1]<<8|this[q+2]<<16)+this[q+3]*16777216};y.prototype.readUint32BE=y.prototype.readUInt32BE=function(q,X){if(q=q>>>0,!X)D0(q,4,this.length);return this[q]*16777216+(this[q+1]<<16|this[q+2]<<8|this[q+3])};y.prototype.readBigUInt64LE=M6(function(q){q=q>>>0,y5(q,"offset");let X=this[q],V=this[q+7];if(X===void 0||V===void 0)C8(q,this.length-8);let K=X+this[++q]*256+this[++q]*65536+this[++q]*16777216,Q=this[++q]+this[++q]*256+this[++q]*65536+V*16777216;return BigInt(K)+(BigInt(Q)<>>0,y5(q,"offset");let X=this[q],V=this[q+7];if(X===void 0||V===void 0)C8(q,this.length-8);let K=X*16777216+this[++q]*65536+this[++q]*256+this[++q],Q=this[++q]*16777216+this[++q]*65536+this[++q]*256+V;return(BigInt(K)<>>0,X=X>>>0,!V)D0(q,X,this.length);let K=this[q],Q=1,Y=0;while(++Y=Q)K-=Math.pow(2,8*X);return K};y.prototype.readIntBE=function(q,X,V){if(q=q>>>0,X=X>>>0,!V)D0(q,X,this.length);let K=X,Q=1,Y=this[q+--K];while(K>0&&(Q*=256))Y+=this[q+--K]*Q;if(Q*=128,Y>=Q)Y-=Math.pow(2,8*X);return Y};y.prototype.readInt8=function(q,X){if(q=q>>>0,!X)D0(q,1,this.length);if(!(this[q]&128))return this[q];return(255-this[q]+1)*-1};y.prototype.readInt16LE=function(q,X){if(q=q>>>0,!X)D0(q,2,this.length);let V=this[q]|this[q+1]<<8;return V&32768?V|4294901760:V};y.prototype.readInt16BE=function(q,X){if(q=q>>>0,!X)D0(q,2,this.length);let V=this[q+1]|this[q]<<8;return V&32768?V|4294901760:V};y.prototype.readInt32LE=function(q,X){if(q=q>>>0,!X)D0(q,4,this.length);return this[q]|this[q+1]<<8|this[q+2]<<16|this[q+3]<<24};y.prototype.readInt32BE=function(q,X){if(q=q>>>0,!X)D0(q,4,this.length);return this[q]<<24|this[q+1]<<16|this[q+2]<<8|this[q+3]};y.prototype.readBigInt64LE=M6(function(q){q=q>>>0,y5(q,"offset");let X=this[q],V=this[q+7];if(X===void 0||V===void 0)C8(q,this.length-8);let K=this[q+4]+this[q+5]*256+this[q+6]*65536+(V<<24);return(BigInt(K)<>>0,y5(q,"offset");let X=this[q],V=this[q+7];if(X===void 0||V===void 0)C8(q,this.length-8);let K=(X<<24)+this[++q]*65536+this[++q]*256+this[++q];return(BigInt(K)<>>0,!X)D0(q,4,this.length);return $1(this,q,!0,23,4)};y.prototype.readFloatBE=function(q,X){if(q=q>>>0,!X)D0(q,4,this.length);return $1(this,q,!1,23,4)};y.prototype.readDoubleLE=function(q,X){if(q=q>>>0,!X)D0(q,8,this.length);return $1(this,q,!0,52,8)};y.prototype.readDoubleBE=function(q,X){if(q=q>>>0,!X)D0(q,8,this.length);return $1(this,q,!1,52,8)};function s0(q,X,V,K,Q,Y){if(!y.isBuffer(q))throw TypeError('"buffer" argument must be a Buffer instance');if(X>Q||Xq.length)throw RangeError("Index out of range")}y.prototype.writeUintLE=y.prototype.writeUIntLE=function(q,X,V,K){if(q=+q,X=X>>>0,V=V>>>0,!K){let J=Math.pow(2,8*V)-1;s0(this,q,X,V,J,0)}let Q=1,Y=0;this[X]=q&255;while(++Y>>0,V=V>>>0,!K){let J=Math.pow(2,8*V)-1;s0(this,q,X,V,J,0)}let Q=V-1,Y=1;this[X+Q]=q&255;while(--Q>=0&&(Y*=256))this[X+Q]=q/Y&255;return X+V};y.prototype.writeUint8=y.prototype.writeUInt8=function(q,X,V){if(q=+q,X=X>>>0,!V)s0(this,q,X,1,255,0);return this[X]=q&255,X+1};y.prototype.writeUint16LE=y.prototype.writeUInt16LE=function(q,X,V){if(q=+q,X=X>>>0,!V)s0(this,q,X,2,65535,0);return this[X]=q&255,this[X+1]=q>>>8,X+2};y.prototype.writeUint16BE=y.prototype.writeUInt16BE=function(q,X,V){if(q=+q,X=X>>>0,!V)s0(this,q,X,2,65535,0);return this[X]=q>>>8,this[X+1]=q&255,X+2};y.prototype.writeUint32LE=y.prototype.writeUInt32LE=function(q,X,V){if(q=+q,X=X>>>0,!V)s0(this,q,X,4,4294967295,0);return this[X+3]=q>>>24,this[X+2]=q>>>16,this[X+1]=q>>>8,this[X]=q&255,X+4};y.prototype.writeUint32BE=y.prototype.writeUInt32BE=function(q,X,V){if(q=+q,X=X>>>0,!V)s0(this,q,X,4,4294967295,0);return this[X]=q>>>24,this[X+1]=q>>>16,this[X+2]=q>>>8,this[X+3]=q&255,X+4};function AX(q,X,V,K,Q){CX(X,K,Q,q,V,7);let Y=Number(X&BigInt(4294967295));q[V++]=Y,Y=Y>>8,q[V++]=Y,Y=Y>>8,q[V++]=Y,Y=Y>>8,q[V++]=Y;let J=Number(X>>BigInt(32)&BigInt(4294967295));return q[V++]=J,J=J>>8,q[V++]=J,J=J>>8,q[V++]=J,J=J>>8,q[V++]=J,V}function NX(q,X,V,K,Q){CX(X,K,Q,q,V,7);let Y=Number(X&BigInt(4294967295));q[V+7]=Y,Y=Y>>8,q[V+6]=Y,Y=Y>>8,q[V+5]=Y,Y=Y>>8,q[V+4]=Y;let J=Number(X>>BigInt(32)&BigInt(4294967295));return q[V+3]=J,J=J>>8,q[V+2]=J,J=J>>8,q[V+1]=J,J=J>>8,q[V]=J,V+8}y.prototype.writeBigUInt64LE=M6(function(q,X=0){return AX(this,q,X,BigInt(0),BigInt("0xffffffffffffffff"))});y.prototype.writeBigUInt64BE=M6(function(q,X=0){return NX(this,q,X,BigInt(0),BigInt("0xffffffffffffffff"))});y.prototype.writeIntLE=function(q,X,V,K){if(q=+q,X=X>>>0,!K){let G=Math.pow(2,8*V-1);s0(this,q,X,V,G-1,-G)}let Q=0,Y=1,J=0;this[X]=q&255;while(++Q>0)-J&255}return X+V};y.prototype.writeIntBE=function(q,X,V,K){if(q=+q,X=X>>>0,!K){let G=Math.pow(2,8*V-1);s0(this,q,X,V,G-1,-G)}let Q=V-1,Y=1,J=0;this[X+Q]=q&255;while(--Q>=0&&(Y*=256)){if(q<0&&J===0&&this[X+Q+1]!==0)J=1;this[X+Q]=(q/Y>>0)-J&255}return X+V};y.prototype.writeInt8=function(q,X,V){if(q=+q,X=X>>>0,!V)s0(this,q,X,1,127,-128);if(q<0)q=255+q+1;return this[X]=q&255,X+1};y.prototype.writeInt16LE=function(q,X,V){if(q=+q,X=X>>>0,!V)s0(this,q,X,2,32767,-32768);return this[X]=q&255,this[X+1]=q>>>8,X+2};y.prototype.writeInt16BE=function(q,X,V){if(q=+q,X=X>>>0,!V)s0(this,q,X,2,32767,-32768);return this[X]=q>>>8,this[X+1]=q&255,X+2};y.prototype.writeInt32LE=function(q,X,V){if(q=+q,X=X>>>0,!V)s0(this,q,X,4,2147483647,-2147483648);return this[X]=q&255,this[X+1]=q>>>8,this[X+2]=q>>>16,this[X+3]=q>>>24,X+4};y.prototype.writeInt32BE=function(q,X,V){if(q=+q,X=X>>>0,!V)s0(this,q,X,4,2147483647,-2147483648);if(q<0)q=4294967295+q+1;return this[X]=q>>>24,this[X+1]=q>>>16,this[X+2]=q>>>8,this[X+3]=q&255,X+4};y.prototype.writeBigInt64LE=M6(function(q,X=0){return AX(this,q,X,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))});y.prototype.writeBigInt64BE=M6(function(q,X=0){return NX(this,q,X,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))});function SX(q,X,V,K,Q,Y){if(V+K>q.length)throw RangeError("Index out of range");if(V<0)throw RangeError("Index out of range")}function yX(q,X,V,K,Q){if(X=+X,V=V>>>0,!Q)SX(q,X,V,4,340282346638528860000000000000000000000,-340282346638528860000000000000000000000);return BX(q,X,V,K,23,4),V+4}y.prototype.writeFloatLE=function(q,X,V){return yX(this,q,X,!0,V)};y.prototype.writeFloatBE=function(q,X,V){return yX(this,q,X,!1,V)};function $X(q,X,V,K,Q){if(X=+X,V=V>>>0,!Q)SX(q,X,V,8,179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,-179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);return BX(q,X,V,K,52,8),V+8}y.prototype.writeDoubleLE=function(q,X,V){return $X(this,q,X,!0,V)};y.prototype.writeDoubleBE=function(q,X,V){return $X(this,q,X,!1,V)};y.prototype.copy=function(q,X,V,K){if(!y.isBuffer(q))throw TypeError("argument should be a Buffer");if(!V)V=0;if(!K&&K!==0)K=this.length;if(X>=q.length)X=q.length;if(!X)X=0;if(K>0&&K=this.length)throw RangeError("Index out of range");if(K<0)throw RangeError("sourceEnd out of bounds");if(K>this.length)K=this.length;if(q.length-X>>0,V=V===void 0?this.length:V>>>0,!q)q=0;let Q;if(typeof q==="number")for(Q=X;Q=K+4;V-=3)X=`_${q.slice(V-3,V)}${X}`;return`${q.slice(0,V)}${X}`}function AQ(q,X,V){if(y5(X,"offset"),q[X]===void 0||q[X+V]===void 0)C8(X,q.length-(V+1))}function CX(q,X,V,K,Q,Y){if(q>V||q3)if(X===0||X===BigInt(0))G=`>= 0${J} and < 2${J} ** ${(Y+1)*8}${J}`;else G=`>= -(2${J} ** ${(Y+1)*8-1}${J}) and < 2 ** ${(Y+1)*8-1}${J}`;else G=`>= ${X}${J} and <= ${V}${J}`;throw new cq("value",G,q)}AQ(K,Q,Y)}function y5(q,X){if(typeof q!=="number")throw new ZQ(X,"number",q)}function C8(q,X,V){if(Math.floor(q)!==q)throw y5(q,V),new cq(V||"offset","an integer",q);if(X<0)throw new GQ;throw new cq(V||"offset",`>= ${V?1:0} and <= ${X}`,q)}var NQ=/[^+/0-9A-Za-z-_]/g;function SQ(q){if(q=q.split("=")[0],q=q.trim().replace(NQ,""),q.length<2)return"";while(q.length%4!==0)q=q+"=";return q}function nq(q,X){X=X||1/0;let V,K=q.length,Q=null,Y=[];for(let J=0;J55295&&V<57344){if(!Q){if(V>56319){if((X-=3)>-1)Y.push(239,191,189);continue}else if(J+1===K){if((X-=3)>-1)Y.push(239,191,189);continue}Q=V;continue}if(V<56320){if((X-=3)>-1)Y.push(239,191,189);Q=V;continue}V=(Q-55296<<10|V-56320)+65536}else if(Q){if((X-=3)>-1)Y.push(239,191,189)}if(Q=null,V<128){if((X-=1)<0)break;Y.push(V)}else if(V<2048){if((X-=2)<0)break;Y.push(V>>6|192,V&63|128)}else if(V<65536){if((X-=3)<0)break;Y.push(V>>12|224,V>>6&63|128,V&63|128)}else if(V<1114112){if((X-=4)<0)break;Y.push(V>>18|240,V>>12&63|128,V>>6&63|128,V&63|128)}else throw Error("Invalid code point")}return Y}function yQ(q){let X=[];for(let V=0;V>8,Q=V%256,Y.push(Q),Y.push(K)}return Y}function hX(q){return KQ(SQ(q))}function C1(q,X,V,K){let Q;for(Q=0;Q=X.length||Q>=q.length)break;X[Q+V]=q[Q]}return Q}function h2(q,X){return q instanceof X||q!=null&&q.constructor!=null&&q.constructor.name!=null&&q.constructor.name===X.name}var CQ=function(){let q=Array(256);for(let X=0;X<16;++X){let V=X*16;for(let K=0;K<16;++K)q[V+K]="0123456789abcdef"[X]+"0123456789abcdef"[K]}return q}();function M6(q){return typeof BigInt>"u"?hQ:q}function hQ(){throw Error("BigInt not supported")}function oq(q){return()=>{throw Error(q+" is not implemented for node:buffer browser polyfill")}}var P3=oq("resolveObjectURL"),D3=oq("isUtf8");var u3=oq("transcode");var N3=$8(gX(),1);var UX={};qQ(UX,{waitForTick:()=>R2,values:()=>d5,utf8Encode:()=>mQ,utf16Encode:()=>E4,utf16Decode:()=>x8,typedArrayFor:()=>D8,translate:()=>c0,toUint8Array:()=>r6,toRadians:()=>O0,toHexStringOfMinLength:()=>D2,toHexString:()=>u2,toDegrees:()=>k1,toCodePoint:()=>K4,toCharCode:()=>s,sum:()=>z4,stroke:()=>B5,square:()=>lZ,sortedUniq:()=>U4,skewRadians:()=>k8,skewDegrees:()=>bZ,sizeInBytes:()=>P5,singleQuote:()=>t9,showText:()=>L1,setWordSpacing:()=>pZ,setTextRise:()=>nZ,setTextRenderingMode:()=>rZ,setTextMatrix:()=>FK,setStrokingRgbColor:()=>g7,setStrokingGrayscaleColor:()=>D7,setStrokingColor:()=>v5,setStrokingCmykColor:()=>b7,setLineWidth:()=>L5,setLineJoin:()=>fZ,setLineHeight:()=>F7,setLineCap:()=>I8,setGraphicsState:()=>i2,setFontAndSize:()=>T5,setFillingRgbColor:()=>u7,setFillingGrayscaleColor:()=>P7,setFillingColor:()=>E2,setFillingCmykColor:()=>x7,setDashPattern:()=>j5,setCharacterSqueeze:()=>dZ,setCharacterSpacing:()=>cZ,scale:()=>g6,rotateRectangle:()=>y7,rotateRadians:()=>x6,rotateInPlace:()=>j2,rotateDegrees:()=>M8,rotateAndSkewTextRadiansAndTranslate:()=>j8,rotateAndSkewTextDegreesAndTranslate:()=>iZ,rgb:()=>Y0,reverseArray:()=>I6,restoreDashPattern:()=>mZ,reduceRotation:()=>I2,rectanglesAreEqual:()=>n5,rectangle:()=>hK,range:()=>M4,radiansToDegrees:()=>CK,radians:()=>gZ,pushGraphicsState:()=>B0,popGraphicsState:()=>T0,pluckIndices:()=>k4,pdfDocEncodingDecode:()=>J1,parseDate:()=>P8,padStart:()=>e0,numberToString:()=>B4,normalizeAppearance:()=>G2,nextLine:()=>h7,newlineChars:()=>gQ,moveTo:()=>J2,moveText:()=>_Z,mergeUint8Arrays:()=>W4,mergeLines:()=>F1,mergeIntoTypedArray:()=>Z4,lowSurrogate:()=>u1,lineTo:()=>S0,lineSplit:()=>F8,layoutSinglelineText:()=>v8,layoutMultilineText:()=>uq,layoutCombedText:()=>KX,last:()=>n6,isWithinBMP:()=>j4,isType:()=>XK,isStandardFont:()=>e1,isNewlineChar:()=>Y4,highSurrogate:()=>D1,hasUtf16BOM:()=>b8,hasSurrogates:()=>L4,grayscale:()=>Sq,getType:()=>qK,findLastMatch:()=>F5,fillAndStroke:()=>j1,fill:()=>E1,escapedNewlineChars:()=>mX,escapeRegExp:()=>bX,error:()=>L6,endText:()=>T1,endPath:()=>wq,endMarkedContent:()=>Nq,encodeToBase64:()=>X4,drawTextLines:()=>Fq,drawTextField:()=>Pq,drawText:()=>eZ,drawSvgPath:()=>d7,drawRectangle:()=>b6,drawRadioButton:()=>T8,drawPage:()=>c7,drawOptionList:()=>n7,drawObject:()=>L8,drawLinesOfText:()=>_7,drawLine:()=>p7,drawImage:()=>w1,drawEllipsePath:()=>xK,drawEllipse:()=>O1,drawCheckMark:()=>bK,drawCheckBox:()=>B8,drawButton:()=>hq,degreesToRadians:()=>H6,degrees:()=>p,defaultTextFieldAppearanceProvider:()=>GX,defaultRadioGroupAppearanceProvider:()=>YX,defaultOptionListAppearanceProvider:()=>WX,defaultDropdownAppearanceProvider:()=>ZX,defaultCheckBoxAppearanceProvider:()=>QX,defaultButtonAppearanceProvider:()=>JX,decodePDFRawStream:()=>V8,decodeFromBase64DataUri:()=>V4,decodeFromBase64:()=>q4,createValueErrorMsg:()=>e9,createTypeErrorMsg:()=>VK,createPDFAcroFields:()=>Z8,createPDFAcroField:()=>kq,copyStringIntoBuffer:()=>k0,concatTransformationMatrix:()=>I1,componentsToColor:()=>l0,colorToComponents:()=>$q,cmyk:()=>yq,closePath:()=>N2,clipEvenOdd:()=>xZ,clip:()=>Oq,cleanText:()=>k6,charSplit:()=>J4,charFromHexCode:()=>Q4,charFromCode:()=>t0,charAtIndex:()=>P1,canBeConvertedToUint8Array:()=>I4,bytesFor:()=>j6,byAscendingId:()=>H4,breakTextIntoLines:()=>G4,beginText:()=>B1,beginMarkedContent:()=>Aq,backtick:()=>$0,assertRangeOrUndefined:()=>X2,assertRange:()=>b0,assertPositive:()=>X6,assertOrUndefined:()=>F,assertMultiple:()=>Y1,assertIsSubset:()=>V7,assertIsOneOfOrUndefined:()=>a0,assertIsOneOf:()=>M2,assertIs:()=>T,assertInteger:()=>K7,assertEachIs:()=>Q1,asPDFNumber:()=>f,asPDFName:()=>z8,asNumber:()=>t,arrayAsString:()=>u8,appendQuadraticCurve:()=>E8,appendBezierCurve:()=>p0,adjustDimsForRotation:()=>r2,addRandomSuffix:()=>uQ,ViewerPreferences:()=>W1,UnsupportedEncodingError:()=>Q7,UnrecognizedStreamTypeError:()=>J7,UnexpectedObjectTypeError:()=>A6,UnexpectedFieldTypeError:()=>z6,UnbalancedParenthesisError:()=>E7,TextRenderingMode:()=>C7,TextAlignment:()=>v0,StandardFonts:()=>N5,StandardFontValues:()=>o9,StandardFontEmbedder:()=>$6,StalledParserError:()=>j7,RotationTypes:()=>E5,RichTextFieldReadError:()=>e7,ReparseError:()=>Q5,RemovePageFromEmptyDocumentError:()=>o7,ReadingDirection:()=>U5,PrivateConstructorError:()=>K5,PrintScaling:()=>z5,PngEmbedder:()=>X8,ParseSpeeds:()=>A1,PageSizes:()=>HX,PageEmbeddingMismatchedContextError:()=>G7,PDFXRefStreamParser:()=>Lq,PDFWriter:()=>o5,PDFWidgetAnnotation:()=>M5,PDFTrailerDict:()=>Qq,PDFTrailer:()=>S6,PDFTextField:()=>A5,PDFString:()=>K0,PDFStreamWriter:()=>Jq,PDFStreamParsingError:()=>I7,PDFStream:()=>E0,PDFSignature:()=>O8,PDFRef:()=>a,PDFRawStream:()=>A2,PDFRadioGroup:()=>l6,PDFParsingError:()=>V6,PDFParser:()=>Bq,PDFPageTree:()=>H8,PDFPageLeaf:()=>_0,PDFPageEmbedder:()=>K8,PDFPage:()=>y0,PDFOptionList:()=>w5,PDFOperatorNames:()=>X0,PDFOperator:()=>e,PDFObjectStreamParser:()=>jq,PDFObjectStream:()=>a5,PDFObjectParsingError:()=>M7,PDFObjectParser:()=>U8,PDFObjectCopier:()=>Z1,PDFObject:()=>z0,PDFNumber:()=>x,PDFNull:()=>F0,PDFName:()=>I,PDFJavaScript:()=>xq,PDFInvalidObjectParsingError:()=>k7,PDFInvalidObject:()=>s5,PDFImage:()=>R5,PDFHexString:()=>g,PDFHeader:()=>_2,PDFForm:()=>gq,PDFFont:()=>w0,PDFFlateStream:()=>N6,PDFField:()=>d0,PDFEmbeddedPage:()=>R8,PDFDropdown:()=>O5,PDFDocument:()=>o0,PDFDict:()=>m,PDFCrossRefStream:()=>Yq,PDFCrossRefSection:()=>i5,PDFContext:()=>Z5,PDFContentStream:()=>p2,PDFCheckBox:()=>f6,PDFCatalog:()=>W8,PDFButton:()=>S5,PDFBool:()=>c2,PDFArrayIsNotRectangleError:()=>Z7,PDFArray:()=>i,PDFAnnotation:()=>Mq,PDFAcroText:()=>J6,PDFAcroTerminal:()=>K2,PDFAcroSignature:()=>F6,PDFAcroRadioButton:()=>Z6,PDFAcroPushButton:()=>G6,PDFAcroNonTerminal:()=>Y6,PDFAcroListBox:()=>W6,PDFAcroForm:()=>P6,PDFAcroField:()=>Y8,PDFAcroComboBox:()=>Q6,PDFAcroChoice:()=>G8,PDFAcroCheckBox:()=>K6,PDFAcroButton:()=>h6,NumberParsingError:()=>Vq,NonFullScreenPageMode:()=>H5,NoSuchFieldError:()=>s7,NextByteAssertionError:()=>z7,MultiSelectValueError:()=>W7,MissingTfOperatorError:()=>U7,MissingPageContentsEmbeddingError:()=>Y7,MissingPDFHeaderError:()=>L7,MissingOnValueCheckError:()=>X3,MissingKeywordError:()=>B7,MissingDAEntryError:()=>H7,MissingCatalogError:()=>qG,MethodNotImplementedError:()=>u0,LineJoinStyle:()=>$7,LineCapStyle:()=>u6,JpegEmbedder:()=>q8,InvalidTargetIndexError:()=>qq,InvalidPDFDateStringError:()=>G1,InvalidMaxLengthError:()=>VX,InvalidFieldNamePartError:()=>t7,InvalidAcroFieldValueError:()=>J5,IndexOutOfBoundsError:()=>Y5,ImageAlignment:()=>T2,ForeignPageError:()=>a7,FontkitNotRegisteredError:()=>i7,FileEmbedder:()=>Wq,FieldExistsAsNonTerminalError:()=>V3,FieldAlreadyExistsError:()=>Dq,ExceededMaxLengthError:()=>XX,EncryptedPDFError:()=>r7,Duplex:()=>Q8,CustomFontSubsetEmbedder:()=>Zq,CustomFontEmbedder:()=>C6,CorruptPageTreeError:()=>Xq,CombedTextLayoutError:()=>qX,ColorTypes:()=>U6,CharCodes:()=>E,Cache:()=>m0,BlendMode:()=>S2,AppearanceCharacteristics:()=>J8,AnnotationFlags:()=>I5,AcroTextFlags:()=>j0,AcroFieldFlags:()=>Y2,AcroChoiceFlags:()=>G0,AcroButtonFlags:()=>f0,AFRelationship:()=>t5});/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */var eq=function(q,X){return eq=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(V,K){V.__proto__=K}||function(V,K){for(var Q in K)if(K.hasOwnProperty(Q))V[Q]=K[Q]},eq(q,X)};function A(q,X){eq(q,X);function V(){this.constructor=q}q.prototype=X===null?Object.create(X):(V.prototype=X.prototype,new V)}var o=function(){return o=Object.assign||function(X){for(var V,K=1,Q=arguments.length;K0&&Y[Y.length-1]))&&(Z[0]===6||Z[0]===2)){V=0;continue}if(Z[0]===3&&(!Y||Z[1]>Y[0]&&Z[1]>2],X+=h5[(q[K]&3)<<4|q[K+1]>>4],X+=h5[(q[K+1]&15)<<2|q[K+2]>>6],X+=h5[q[K+2]&63];if(V%3===2)X=X.substring(0,X.length-1)+"=";else if(V%3===1)X=X.substring(0,X.length-2)+"==";return X},q4=function(q){var X=q.length*0.75,V=q.length,K,Q=0,Y,J,G,W;if(q[q.length-1]==="="){if(X--,q[q.length-2]==="=")X--}var Z=new Uint8Array(X);for(K=0;K>4,Z[Q++]=(J&15)<<4|G>>2,Z[Q++]=(G&3)<<6|W&63;return Z},DQ=/^(data)?:?([\w\/\+]+)?;?(charset=[\w-]+|base64)?.*,/i,V4=function(q){var X=q.trim(),V=X.substring(0,100),K=V.match(DQ);if(!K)return q4(X);var Q=K[0],Y=X.substring(Q.length);return q4(Y)};var s=function(q){return q.charCodeAt(0)},K4=function(q){return q.codePointAt(0)},D2=function(q,X){return e0(q.toString(16),X,"0").toUpperCase()},u2=function(q){return D2(q,2)},t0=function(q){return String.fromCharCode(q)},Q4=function(q){return t0(parseInt(q,16))},e0=function(q,X,V){var K="";for(var Q=0,Y=X-q.length;Q=55296&&V<=56319&&q.length>Q){if(K=q.charCodeAt(Q),K>=56320&&K<=57343)Y=2}return[q.slice(X,X+Y),Y]},J4=function(q){var X=[];for(var V=0,K=q.length;VV)Z();J+=z,G+=k}}return Z(),W},bQ=/^D:(\d\d\d\d)(\d\d)?(\d\d)?(\d\d)?(\d\d)?(\d\d)?([+\-Z])?(\d\d)?'?(\d\d)?'?$/,P8=function(q){var X=q.match(bQ);if(!X)return;var V=X[1],K=X[2],Q=K===void 0?"01":K,Y=X[3],J=Y===void 0?"01":Y,G=X[4],W=G===void 0?"00":G,Z=X[5],H=Z===void 0?"00":Z,U=X[6],z=U===void 0?"00":U,k=X[7],M=k===void 0?"Z":k,j=X[8],B=j===void 0?"00":j,L=X[9],O=L===void 0?"00":L,N=M==="Z"?"Z":""+M+B+":"+O,R=new Date(V+"-"+Q+"-"+J+"T"+W+":"+H+":"+z+N);return R},F5=function(q,X){var V,K=0,Q;while(K>6&31|192,G=Y&63|128;V.push(J,G),K+=1}else if(Y<65536){var J=Y>>12&15|224,G=Y>>6&63|128,W=Y&63|128;V.push(J,G,W),K+=1}else if(Y<1114112){var J=Y>>18&7|240,G=Y>>12&63|128,W=Y>>6&63|128,Z=Y>>0&63|128;V.push(J,G,W,Z),K+=2}else throw Error("Invalid code point: 0x"+u2(Y))}return new Uint8Array(V)},E4=function(q,X){if(X===void 0)X=!0;var V=[];if(X)V.push(65279);for(var K=0,Q=q.length;K=0&&q<=65535},L4=function(q){return q>=65536&&q<=1114111},D1=function(q){return Math.floor((q-65536)/1024)+55296},u1=function(q){return(q-65536)%1024+56320},E6;(function(q){q.BigEndian="BigEndian",q.LittleEndian="LittleEndian"})(E6||(E6={}));var g8="�".codePointAt(0),x8=function(q,X){if(X===void 0)X=!0;if(q.length<=1)return String.fromCodePoint(g8);var V=X?lQ(q):E6.BigEndian,K=X?2:0,Q=[];while(q.length-K>=2){var Y=lX(q[K++],q[K++],V);if(fQ(Y))if(q.length-K<2)Q.push(g8);else{var J=lX(q[K++],q[K++],V);if(fX(J))Q.push(Y,J);else Q.push(g8)}else if(fX(Y))K+=2,Q.push(g8);else Q.push(Y)}if(K=55296&&q<=56319},fX=function(q){return q>=56320&&q<=57343},lX=function(q,X,V){if(V===E6.LittleEndian)return X<<8|q;if(V===E6.BigEndian)return q<<8|X;throw Error("Invalid byteOrder: "+V)},lQ=function(q){return _X(q)?E6.BigEndian:cX(q)?E6.LittleEndian:E6.BigEndian},_X=function(q){return q[0]===254&&q[1]===255},cX=function(q){return q[0]===255&&q[1]===254},b8=function(q){return _X(q)||cX(q)};var B4=function(q){var X=String(q);if(Math.abs(q)<1){var V=parseInt(q.toString().split("e-")[1]);if(V){var K=q<0;if(K)q*=-1;if(q*=Math.pow(10,V-1),X="0."+Array(V).join("0")+q.toString().substring(2),K)X="-"+X}}else{var V=parseInt(q.toString().split("+")[1]);if(V>20)V-=20,q/=Math.pow(10,V),X=q.toString()+Array(V+1).join("0")}return X},P5=function(q){return Math.ceil(q.toString(2).length/8)},j6=function(q){var X=new Uint8Array(P5(q));for(var V=1;V<=X.length;V++)X[V-1]=q>>(X.length-V)*8;return X};var L6=function(q){throw Error(q)};var h9=$8(X1(),1),C9="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",V1=new Uint8Array(256);for(p5=0;p5>4,Z[Q++]=(J&15)<<4|G>>2,Z[Q++]=(G&3)<<6|W&63;return Z},uJ=function(q){var X="";for(var V=0;VK)throw Error($0(X)+" must be at least "+V+" and at most "+K+", but was actually "+q)},X2=function(q,X,V,K){if(T(q,X,["number","undefined"]),typeof q==="number")b0(q,X,V,K)},Y1=function(q,X,V){if(T(q,X,["number"]),q%V!==0)throw Error($0(X)+" must be a multiple of "+V+", but was actually "+q)},K7=function(q,X){if(!Number.isInteger(q))throw Error($0(X)+" must be an integer, but was actually "+q)},X6=function(q,X){if(![1,0].includes(Math.sign(q)))throw Error($0(X)+" must be a positive number or 0, but was actually "+q)};var V0=new Uint16Array(256);for(r5=0;r5<256;r5++)V0[r5]=r5;var r5;V0[22]=s("\x17");V0[24]=s("˘");V0[25]=s("ˇ");V0[26]=s("ˆ");V0[27]=s("˙");V0[28]=s("˝");V0[29]=s("˛");V0[30]=s("˚");V0[31]=s("˜");V0[127]=s("�");V0[128]=s("•");V0[129]=s("†");V0[130]=s("‡");V0[131]=s("…");V0[132]=s("—");V0[133]=s("–");V0[134]=s("ƒ");V0[135]=s("⁄");V0[136]=s("‹");V0[137]=s("›");V0[138]=s("−");V0[139]=s("‰");V0[140]=s("„");V0[141]=s("“");V0[142]=s("”");V0[143]=s("‘");V0[144]=s("’");V0[145]=s("‚");V0[146]=s("™");V0[147]=s("fi");V0[148]=s("fl");V0[149]=s("Ł");V0[150]=s("Œ");V0[151]=s("Š");V0[152]=s("Ÿ");V0[153]=s("Ž");V0[154]=s("ı");V0[155]=s("ł");V0[156]=s("œ");V0[157]=s("š");V0[158]=s("ž");V0[159]=s("�");V0[160]=s("€");V0[173]=s("�");var J1=function(q){var X=Array(q.length);for(var V=0,K=q.length;V=E.ExclamationPoint&&q<=E.Tilde&&!Kq[q]},KK={},QK=new Map,ZG=function(q){A(X,q);function X(V,K){var Q=this;if(V!==KK)throw new K5("PDFName");Q=q.call(this)||this;var Y="/";for(var J=0,G=K.length;J=E.Zero&&Z<=E.Nine||Z>=E.a&&Z<=E.f||Z>=E.A&&Z<=E.F){if(K+=W,K.length===2||!(H>="0"&&H<="9"||H>="a"&&H<="f"||H>="A"&&H<="F"))Y(parseInt(K,16)),K=""}else Y(Z)}return new Uint8Array(V)},X.prototype.decodeText=function(){var V=this.asBytes();return String.fromCharCode.apply(String,Array.from(V))},X.prototype.asString=function(){return this.encodedName},X.prototype.value=function(){return this.encodedName},X.prototype.clone=function(){return this},X.prototype.toString=function(){return this.encodedName},X.prototype.sizeInBytes=function(){return this.encodedName.length},X.prototype.copyBytesInto=function(V,K){return K+=k0(this.encodedName,V,K),this.encodedName.length},X.of=function(V){var K=JG(V),Q=QK.get(K);if(!Q)Q=new X(KK,K),QK.set(K,Q);return Q},X.Length=X.of("Length"),X.FlateDecode=X.of("FlateDecode"),X.Resources=X.of("Resources"),X.Font=X.of("Font"),X.XObject=X.of("XObject"),X.ExtGState=X.of("ExtGState"),X.Contents=X.of("Contents"),X.Type=X.of("Type"),X.Parent=X.of("Parent"),X.MediaBox=X.of("MediaBox"),X.Page=X.of("Page"),X.Annots=X.of("Annots"),X.TrimBox=X.of("TrimBox"),X.ArtBox=X.of("ArtBox"),X.BleedBox=X.of("BleedBox"),X.CropBox=X.of("CropBox"),X.Rotate=X.of("Rotate"),X.Title=X.of("Title"),X.Author=X.of("Author"),X.Subject=X.of("Subject"),X.Creator=X.of("Creator"),X.Keywords=X.of("Keywords"),X.Producer=X.of("Producer"),X.CreationDate=X.of("CreationDate"),X.ModDate=X.of("ModDate"),X}(z0),I=ZG;var WG=function(q){A(X,q);function X(){return q!==null&&q.apply(this,arguments)||this}return X.prototype.asNull=function(){return null},X.prototype.clone=function(){return this},X.prototype.toString=function(){return"null"},X.prototype.sizeInBytes=function(){return 4},X.prototype.copyBytesInto=function(V,K){return V[K++]=E.n,V[K++]=E.u,V[K++]=E.l,V[K++]=E.l,4},X}(z0),F0=new WG;var HG=function(q){A(X,q);function X(V,K){var Q=q.call(this)||this;return Q.dict=V,Q.context=K,Q}return X.prototype.keys=function(){return Array.from(this.dict.keys())},X.prototype.values=function(){return Array.from(this.dict.values())},X.prototype.entries=function(){return Array.from(this.dict.entries())},X.prototype.set=function(V,K){this.dict.set(V,K)},X.prototype.get=function(V,K){if(K===void 0)K=!1;var Q=this.dict.get(V);if(Q===F0&&!K)return;return Q},X.prototype.has=function(V){var K=this.dict.get(V);return K!==void 0&&K!==F0},X.prototype.lookupMaybe=function(V){var K,Q=[];for(var Y=1;Ythis.largestObjectNumber)this.largestObjectNumber=X.objectNumber},q.prototype.nextRef=function(){return this.largestObjectNumber+=1,a.of(this.largestObjectNumber)},q.prototype.register=function(X){var V=this.nextRef();return this.assign(V,X),V},q.prototype.delete=function(X){return this.indirectObjects.delete(X)},q.prototype.lookupMaybe=function(X){var V=[];for(var K=1;K1)this.subsections.push([X]),this.chunkIdx+=1,this.chunkLength=1;else V.push(X),this.chunkLength+=1},q.create=function(){return new q({ref:a.of(0,65535),offset:0,deleted:!0})},q.createEmpty=function(){return new q},q}(),i5=vG;var RG=function(){function q(X){this.lastXRefOffset=String(X)}return q.prototype.toString=function(){return`startxref -`+this.lastXRefOffset+` -%%EOF`},q.prototype.sizeInBytes=function(){return 16+this.lastXRefOffset.length},q.prototype.copyBytesInto=function(X,V){var K=V;return X[V++]=E.s,X[V++]=E.t,X[V++]=E.a,X[V++]=E.r,X[V++]=E.t,X[V++]=E.x,X[V++]=E.r,X[V++]=E.e,X[V++]=E.f,X[V++]=E.Newline,V+=k0(this.lastXRefOffset,X,V),X[V++]=E.Newline,X[V++]=E.Percent,X[V++]=E.Percent,X[V++]=E.E,X[V++]=E.O,X[V++]=E.F,V-K},q.forLastCrossRefSectionOffset=function(X){return new q(X)},q}(),S6=RG;var OG=function(){function q(X){this.dict=X}return q.prototype.toString=function(){return`trailer -`+this.dict.toString()},q.prototype.sizeInBytes=function(){return 8+this.dict.sizeInBytes()},q.prototype.copyBytesInto=function(X,V){var K=V;return X[V++]=E.t,X[V++]=E.r,X[V++]=E.a,X[V++]=E.i,X[V++]=E.l,X[V++]=E.e,X[V++]=E.r,X[V++]=E.Newline,V+=this.dict.copyBytesInto(X,V),V-K},q.of=function(X){return new q(X)},q}(),Qq=OG;var wG=function(q){A(X,q);function X(V,K,Q){if(Q===void 0)Q=!0;var Y=q.call(this,V.obj({}),Q)||this;return Y.objects=K,Y.offsets=Y.computeObjectOffsets(),Y.offsetsString=Y.computeOffsetsString(),Y.dict.set(I.of("Type"),I.of("ObjStm")),Y.dict.set(I.of("N"),x.of(Y.objects.length)),Y.dict.set(I.of("First"),x.of(Y.offsetsString.length)),Y}return X.prototype.getObjectsCount=function(){return this.objects.length},X.prototype.clone=function(V){return X.withContextAndObjects(V||this.dict.context,this.objects.slice(),this.encode)},X.prototype.getContentsString=function(){var V=this.offsetsString;for(var K=0,Q=this.objects.length;K1)J.push(G),J.push(H.ref.objectNumber),G=0;G+=1}return J.push(G),J},Y.computeEntryTuples=function(){var J=Array(Y.entries.length);for(var G=0,W=Y.entries.length;GG[0])G[0]=M;if(j>G[1])G[1]=j;if(B>G[2])G[2]=B}return G},Y.entries=K||[],Y.entryTuplesCache=m0.populatedBy(Y.computeEntryTuples),Y.maxByteWidthsCache=m0.populatedBy(Y.computeMaxEntryByteWidths),Y.indexCache=m0.populatedBy(Y.computeIndex),V.set(I.of("Type"),I.of("XRef")),Y}return X.prototype.addDeletedEntry=function(V,K){var Q=y6.Deleted;this.entries.push({type:Q,ref:V,nextFreeObjectNumber:K}),this.entryTuplesCache.invalidate(),this.maxByteWidthsCache.invalidate(),this.indexCache.invalidate(),this.contentsCache.invalidate()},X.prototype.addUncompressedEntry=function(V,K){var Q=y6.Uncompressed;this.entries.push({type:Q,ref:V,offset:K}),this.entryTuplesCache.invalidate(),this.maxByteWidthsCache.invalidate(),this.indexCache.invalidate(),this.contentsCache.invalidate()},X.prototype.addCompressedEntry=function(V,K,Q){var Y=y6.Compressed;this.entries.push({type:Y,ref:V,objectStreamRef:K,index:Q}),this.entryTuplesCache.invalidate(),this.maxByteWidthsCache.invalidate(),this.indexCache.invalidate(),this.contentsCache.invalidate()},X.prototype.clone=function(V){var K=this,Q=K.dict,Y=K.entries,J=K.encode;return X.of(Q.clone(V),Y.slice(),J)},X.prototype.getContentsString=function(){var V=this.entryTuplesCache.access(),K=this.maxByteWidthsCache.access(),Q="";for(var Y=0,J=V.length;Y=0;M--)Q+=(U[M]||0).toString(2);for(var M=K[1]-1;M>=0;M--)Q+=(z[M]||0).toString(2);for(var M=K[2]-1;M>=0;M--)Q+=(k[M]||0).toString(2)}return Q},X.prototype.getUnencodedContents=function(){var V=this.entryTuplesCache.access(),K=this.maxByteWidthsCache.access(),Q=new Uint8Array(this.getUnencodedContentsSize()),Y=0;for(var J=0,G=V.length;J=0;j--)Q[Y++]=z[j]||0;for(var j=K[1]-1;j>=0;j--)Q[Y++]=k[j]||0;for(var j=K[2]-1;j>=0;j--)Q[Y++]=M[j]||0}return Q},X.prototype.getUnencodedContentsSize=function(){var V=this.maxByteWidthsCache.access(),K=z4(V);return K*this.entries.length},X.prototype.updateDict=function(){q.prototype.updateDict.call(this);var V=this.maxByteWidthsCache.access(),K=this.indexCache.access(),Q=this.dict.context;this.dict.set(I.of("W"),Q.obj(V)),this.dict.set(I.of("Index"),Q.obj(K))},X.create=function(V,K){if(K===void 0)K=!0;var Q=new X(V,[],K);return Q.addDeletedEntry(a.of(0,65535),0),Q},X.of=function(V,K,Q){if(Q===void 0)Q=!0;return new X(V,K,Q)},X}(N6),Yq=SG;var yG=function(q){A(X,q);function X(V,K,Q,Y){var J=q.call(this,V,K)||this;return J.encodeStreams=Q,J.objectsPerStream=Y,J}return X.prototype.computeBufferSize=function(){return _(this,void 0,void 0,function(){var V,K,Q,Y,J,G,W,Z,M,j,H,L,U,z,B,k,M,j,B,L,O,N,R,v;return c(this,function(w){switch(w.label){case 0:V=this.context.largestObjectNumber+1,K=_2.forVersion(1,7),Q=K.sizeInBytes()+2,Y=Yq.create(this.createTrailerDict(),this.encodeStreams),J=[],G=[],W=[],Z=this.context.enumerateIndirectObjects(),M=0,j=Z.length,w.label=1;case 1:if(!(M"},X.prototype.sizeInBytes=function(){return this.value.length+2},X.prototype.copyBytesInto=function(V,K){return V[K++]=E.LessThan,K+=k0(this.value,V,K),V[K++]=E.GreaterThan,this.value.length+2},X.of=function(V){return new X(V)},X.fromText=function(V){var K=E4(V),Q="";for(var Y=0,J=K.length;Y> def -/CMapName /Adobe-Identity-UCS def -/CMapType 2 def -1 begincodespacerange -<0000> -endcodespacerange -`+q.length+` beginbfchar -`+q.map(function(X){var V=X[0],K=X[1];return V+" "+K}).join(` -`)+` -endbfchar -endcmap -CMapName currentdict /CMap defineresource pop -end -end`},HK=function(){var q=[];for(var X=0;X"},Gq=function(q){return D2(q,4)},FG=function(q){if(j4(q))return Gq(q);if(L4(q)){var X=D1(q),V=u1(q);return""+Gq(X)+Gq(V)}var K=u2(q),Q="0x"+K+" is not a valid UTF-8 or UTF-16 codepoint.";throw Error(Q)};var PG=function(q){var X=0,V=function(K){X|=1<=E.Zero&&Z<=E.Seven){if(K+=W,K.length===3||!(H>="0"&&H<="7"))Y(parseInt(K,8)),K=""}else Y(Z)}return new Uint8Array(V)},X.prototype.decodeText=function(){var V=this.asBytes();if(b8(V))return x8(V);return J1(V)},X.prototype.decodeDate=function(){var V=this.decodeText(),K=P8(V);if(!K)throw new G1(V);return K},X.prototype.asString=function(){return this.value},X.prototype.clone=function(){return X.of(this.value)},X.prototype.toString=function(){return"("+this.value+")"},X.prototype.sizeInBytes=function(){return this.value.length+2},X.prototype.copyBytesInto=function(V,K){return V[K++]=E.LeftParen,K+=k0(this.value,V,K),V[K++]=E.RightParen,this.value.length+2},X.of=function(V){return new X(V)},X.fromDate=function(V){var K=e0(String(V.getUTCFullYear()),4,"0"),Q=e0(String(V.getUTCMonth()+1),2,"0"),Y=e0(String(V.getUTCDate()),2,"0"),J=e0(String(V.getUTCHours()),2,"0"),G=e0(String(V.getUTCMinutes()),2,"0"),W=e0(String(V.getUTCSeconds()),2,"0");return new X("D:"+K+Q+Y+J+G+W+"Z")},X}(z0),K0=DG;var uG=function(){function q(X,V,K,Q){var Y=this;this.allGlyphsInFontSortedById=function(){var J=Array(Y.font.characterSet.length);for(var G=0,W=J.length;G>3)]>>7-((M&7)<<0)&1,D=3*C;G[R]=v[D],G[R+1]=v[D+1],G[R+2]=v[D+2],G[R+3]=C<$?w[C]:255}}if(H==2)for(var S=0;S>2)]>>6-((M&3)<<1)&3,D=3*C;G[R]=v[D],G[R+1]=v[D+1],G[R+2]=v[D+2],G[R+3]=C<$?w[C]:255}}if(H==4)for(var S=0;S>1)]>>4-((M&1)<<2)&15,D=3*C;G[R]=v[D],G[R+1]=v[D+1],G[R+2]=v[D+2],G[R+3]=C<$?w[C]:255}}if(H==8)for(var M=0;M>>3)]>>>7-(r&7)&1),I0=u==L*255?0:255;W[J0+r]=I0<<24|u<<16|u<<8|u}else if(H==2)for(var r=0;r>>2)]>>>6-((r&3)<<1)&3),I0=u==L*85?0:255;W[J0+r]=I0<<24|u<<16|u<<8|u}else if(H==4)for(var r=0;r>>1)]>>>4-((r&1)<<2)&15),I0=u==L*17?0:255;W[J0+r]=I0<<24|u<<16|u<<8|u}else if(H==8)for(var r=0;r>>2<<3);while(Q==0){if(Q=B(X,z,1),Y=B(X,z+1,2),z+=3,Y==0){if((z&7)!=0)z+=8-(z&7);var S=(z>>>3)+4,h=X[S-4]|X[S-3]<<8;if($)V=q.H.W(V,U+h);V.set(new K(X.buffer,X.byteOffset+S,h),U),z=S+h<<3,U+=h;continue}if($)V=q.H.W(V,U+131072);if(Y==1)k=w.J,M=w.h,Z=511,H=31;if(Y==2){J=L(X,z,5)+257,G=L(X,z+5,5)+1,W=L(X,z+10,4)+4,z+=14;var b=z,C=1;for(var D=0;D<38;D+=2)w.Q[D]=0,w.Q[D+1]=0;for(var D=0;DC)C=l}z+=3*W,N(w.Q,C),R(w.Q,C,w.u),k=w.w,M=w.d,z=O(w.u,(1<>>4;if(r>>>8==0)V[U++]=r;else if(r==256)break;else{var I0=U+r-254;if(r>264){var n0=w.q[r-257];I0=U+(n0>>>3)+L(X,z,n0&7),z+=n0&7}var N8=M[v(X,z)&H];z+=N8&15;var S8=N8>>>4,y2=w.c[S8],Z2=(y2>>>4)+B(X,z,y2&15);z+=y2&15;while(U>>4;if(U<=15)J[Z]=U,Z++;else{var z=0,k=0;if(U==16)k=3+G(Q,Y,2),Y+=2,z=J[Z-1];else if(U==17)k=3+G(Q,Y,3),Y+=3;else if(U==18)k=11+G(Q,Y,7),Y+=7;var M=Z+k;while(Z>>1;while(JY)Y=W;J++}while(J>1,Z=X[G+1],H=W<<4|Z,U=V-Z,z=X[G]<>>15-V;K[M]=H,z++}}},q.H.l=function(X,V){var K=q.H.m.r,Q=15-V;for(var Y=0;Y>>Q}},q.H.M=function(X,V,K){K=K<<(V&7);var Q=V>>>3;X[Q]|=K,X[Q+1]|=K>>>8},q.H.I=function(X,V,K){K=K<<(V&7);var Q=V>>>3;X[Q]|=K,X[Q+1]|=K>>>8,X[Q+2]|=K>>>16},q.H.e=function(X,V,K){return(X[V>>>3]|X[(V>>>3)+1]<<8)>>>(V&7)&(1<>>3]|X[(V>>>3)+1]<<8|X[(V>>>3)+2]<<16)>>>(V&7)&(1<>>3]|X[(V>>>3)+1]<<8|X[(V>>>3)+2]<<16)>>>(V&7)},q.H.i=function(X,V){return(X[V>>>3]|X[(V>>>3)+1]<<8|X[(V>>>3)+2]<<16|X[(V>>>3)+3]<<24)>>>(V&7)},q.H.m=function(){var X=Uint16Array,V=Uint32Array;return{K:new X(16),j:new X(16),X:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],S:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],T:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],q:new X(32),p:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],z:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],c:new V(32),J:new X(512),_:[],h:new X(32),$:[],w:new X(32768),C:[],v:[],d:new X(32768),D:[],u:new X(512),Q:[],r:new X(32768),s:new V(286),Y:new V(30),a:new V(19),t:new V(15000),k:new X(65536),g:new X(32768)}}(),function(){var X=q.H.m,V=32768;for(var K=0;K>>1|(Q&1431655765)<<1,Q=(Q&3435973836)>>>2|(Q&858993459)<<2,Q=(Q&4042322160)>>>4|(Q&252645135)<<4,Q=(Q&4278255360)>>>8|(Q&16711935)<<8,X.r[K]=(Q>>>16|Q<<16)>>>17}function Y(J,G,W){while(G--!=0)J.push(0,W)}for(var K=0;K<32;K++)X.q[K]=X.S[K]<<3|X.T[K],X.c[K]=X.p[K]<<4|X.z[K];Y(X._,144,8),Y(X._,112,9),Y(X._,24,7),Y(X._,8,8),q.H.n(X._,9),q.H.A(X._,9,X.J),q.H.l(X._,9),Y(X.$,32,5),q.H.n(X.$,5),q.H.A(X.$,5,X.h),q.H.l(X.$,5),Y(X.Q,19,0),Y(X.C,286,0),Y(X.D,30,0),Y(X.v,320,0)}(),q.H.N}();P.decode._readInterlace=function(q,X){var{width:V,height:K}=X,Q=P.decode._getBPP(X),Y=Q>>3,J=Math.ceil(V*Q/8),G=new Uint8Array(K*J),W=0,Z=[0,0,4,0,2,0,1],H=[0,4,0,2,0,1,0],U=[8,8,8,4,4,2,2],z=[8,8,4,4,2,2,1],k=0;while(k<7){var M=U[k],j=z[k],B=0,L=0,O=Z[k];while(O>3];h=h>>7-(S&7)&1,G[w*J+($>>3)]|=h<<7-(($&7)<<0)}if(Q==2){var h=q[S>>3];h=h>>6-(S&7)&3,G[w*J+($>>2)]|=h<<6-(($&3)<<1)}if(Q==4){var h=q[S>>3];h=h>>4-(S&7)&15,G[w*J+($>>1)]|=h<<4-(($&1)<<2)}if(Q>=8){var b=w*J+$*Y;for(var C=0;C>3)+C]}S+=Q,$+=j}v++,w+=M}if(B*L!=0)W+=L*(1+R);k=k+1}return G};P.decode._getBPP=function(q){var X=[1,null,3,1,2,null,4][q.ctype];return X*q.depth};P.decode._filterZero=function(q,X,V,K,Q){var Y=P.decode._getBPP(X),J=Math.ceil(K*Y/8),G=P.decode._paeth;Y=Math.ceil(Y/8);var W=0,Z=1,H=q[V],U=0;if(H>1)q[V]=[0,0,1][H-2];if(H==3)for(U=Y;U>>1)&255;for(var z=0;z>>1);for(;U>>1)}else{for(;U>8&255,q[X+1]=V&255},readUint:function(q,X){return q[X]*16777216+(q[X+1]<<16|q[X+2]<<8|q[X+3])},writeUint:function(q,X,V){q[X]=V>>24&255,q[X+1]=V>>16&255,q[X+2]=V>>8&255,q[X+3]=V&255},readASCII:function(q,X,V){var K="";for(var Q=0;Q=0&&G>=0)U=k*X+M<<2,z=(G+k)*Q+J+M<<2;else U=(-G+k)*X-J+M<<2,z=k*Q+M<<2;if(W==0)K[z]=q[U],K[z+1]=q[U+1],K[z+2]=q[U+2],K[z+3]=q[U+3];else if(W==1){var j=q[U+3]*0.00392156862745098,B=q[U]*j,L=q[U+1]*j,O=q[U+2]*j,N=K[z+3]*0.00392156862745098,R=K[z]*N,v=K[z+1]*N,w=K[z+2]*N,$=1-j,S=j+N*$,h=S==0?0:1/S;K[z+3]=255*S,K[z+0]=(B+R*$)*h,K[z+1]=(L+v*$)*h,K[z+2]=(O+w*$)*h}else if(W==2){var j=q[U+3],B=q[U],L=q[U+1],O=q[U+2],N=K[z+3],R=K[z],v=K[z+1],w=K[z+2];if(j==N&&B==R&&L==v&&O==w)K[z]=0,K[z+1]=0,K[z+2]=0,K[z+3]=0;else K[z]=B,K[z+1]=L,K[z+2]=O,K[z+3]=j}else if(W==3){var j=q[U+3],B=q[U],L=q[U+1],O=q[U+2],N=K[z+3],R=K[z],v=K[z+1],w=K[z+2];if(j==N&&B==R&&L==v&&O==w)continue;if(j<220&&N>20)return!1}}return!0};P.encode=function(q,X,V,K,Q,Y,J){if(K==null)K=0;if(J==null)J=!1;var G=P.encode.compress(q,X,V,K,[!1,!1,!1,0,J]);return P.encode.compressPNG(G,-1),P.encode._main(G,X,V,Q,Y)};P.encodeLL=function(q,X,V,K,Q,Y,J,G){var W={ctype:0+(K==1?0:2)+(Q==0?0:4),depth:Y,frames:[]},Z=Date.now(),H=(K+Q)*Y,U=H*X;for(var z=0;z1,U=!1,z=33+(H?20:0);if(Q.sRGB!=null)z+=13;if(Q.pHYs!=null)z+=21;if(q.ctype==3){var k=q.plte.length;for(var M=0;M>>24!=255)U=!0;z+=8+k*3+4+(U?8+k*1+4:0)}for(var j=0;j>>8&255,$=R>>>16&255;L[Z+N+0]=v,L[Z+N+1]=w,L[Z+N+2]=$}if(Z+=k*3,J(L,Z,Y(L,Z-k*3-4,k*3+4)),Z+=4,U){J(L,Z,k),Z+=4,W(L,Z,"tRNS"),Z+=4;for(var M=0;M>>24&255;Z+=k,J(L,Z,Y(L,Z-k-4,k+4)),Z+=4}}var S=0;for(var j=0;j>2,D>>2));for(var k=0;kq0&&r==u[B-q0])J0[B]=J0[B-q0];else{var I0=N[r];if(I0==null){if(N[r]=I0=R.length,R.push(r),R.length>=300)break}J0[B]=I0}}}var n0=R.length;if(n0<=256&&Z==!1){if(n0<=2)U=1;else if(n0<=4)U=2;else if(n0<=16)U=4;else U=8;U=Math.max(U,W)}for(var k=0;k>1)]|=N1[y1+R0]<<4-(R0&1)*4;else if(U==2)for(var R0=0;R0>2)]|=N1[y1+R0]<<6-(R0&3)*2;else if(U==1)for(var R0=0;R0>3)]|=N1[y1+R0]<<7-(R0&7)*1}Z2=$2,H=3,bq=1}else if(L==!1&&O.length==1){var $2=new Uint8Array(q0*y2*3),pK=q0*y2;for(var B=0;B$)$=b;if(hS)S=h}}if($==-1)v=w=$=S=0;if(Q){if((v&1)==1)v--;if((w&1)==1)w--}var D=($-v+1)*(S-w+1);if(DB)B=R;if(vL)L=v}}if(B==-1)M=j=B=L=0;if(J){if((M&1)==1)M--;if((j&1)==1)j--}Y={x:M,y:j,width:B-M+1,height:L-j+1};var S=K[Q];if(S.rect=Y,S.blend=1,S.img=new Uint8Array(Y.width*Y.height*4),K[Q-1].dispose==0)P._copyTile(Z,X,V,S.img,Y.width,Y.height,-Y.x,-Y.y,0),P.encode._prepareDiff(z,X,V,S.img,Y);else P._copyTile(z,X,V,S.img,Y.width,Y.height,-Y.x,-Y.y,0)};P.encode._prepareDiff=function(q,X,V,K,Q){P._copyTile(q,X,V,K,Q.width,Q.height,-Q.x,-Q.y,2)};P.encode._filterZero=function(q,X,V,K,Q,Y,J){var G=[],W=[0,1,2,3,4];if(Y!=-1)W=[Y];else if(X*K>500000||V==1)W=[0];var Z;if(J)Z={level:0};var H=J&&UZIP!=null?UZIP:kK.default;for(var U=0;U>1)+256&255;if(Y==4)for(var Z=Q;Z>1)&255;for(var Z=Q;Z>1)&255}if(Y==4){for(var Z=0;Z>>1;else V=V>>>1;q[X]=V}return q}(),update:function(q,X,V,K){for(var Q=0;Q>>8;return q},crc:function(q,X,V){return P.crc.update(4294967295,q,X,V)^4294967295}};P.quantize=function(q,X){var V=new Uint8Array(q),K=V.slice(0),Q=new Uint32Array(K.buffer),Y=P.quantize.getKDtree(K,X),J=Y[0],G=Y[1],W=P.quantize.planeDst,Z=V,H=Q,U=Z.length,z=new Uint8Array(V.length>>2);for(var k=0;k>2]=O.ind,H[k>>2]=O.est.rgba}return{abuf:K.buffer,inds:z,plte:G}};P.quantize.getKDtree=function(q,X,V){if(V==null)V=0.0001;var K=new Uint32Array(q.buffer),Q={i0:0,i1:q.length,bst:null,est:null,tdst:0,left:null,right:null};Q.bst=P.quantize.stats(q,Q.i0,Q.i1),Q.est=P.quantize.estats(Q.bst);var Y=[Q];while(Y.lengthJ)J=Y[W].est.L,G=W;if(J=H||Z.i1<=H;if(U){Z.est.L=0;continue}var z={i0:Z.i0,i1:H,bst:null,est:null,tdst:0,left:null,right:null};z.bst=P.quantize.stats(q,z.i0,z.i1),z.est=P.quantize.estats(z.bst);var k={i0:H,i1:Z.i1,bst:null,est:null,tdst:0,left:null,right:null};k.bst={R:[],m:[],N:Z.bst.N-z.bst.N};for(var W=0;W<16;W++)k.bst.R[W]=Z.bst.R[W]-z.bst.R[W];for(var W=0;W<4;W++)k.bst.m[W]=Z.bst.m[W]-z.bst.m[W];k.est=P.quantize.estats(k.bst),Z.left=z,Z.right=k,Y[G]=z,Y.push(k)}Y.sort(function(M,j){return j.bst.N-M.bst.N});for(var W=0;W0)J=q.right,G=q.left;var W=P.quantize.getNearest(J,X,V,K,Q);if(W.tdst<=Y*Y)return W;var Z=P.quantize.getNearest(G,X,V,K,Q);return Z.tdstY)K-=4;if(V>=K)break;var W=X[V>>2];X[V>>2]=X[K>>2],X[K>>2]=W,V+=4,K-=4}while(J(q,V,Q)>Y)V-=4;return V+4};P.quantize.vecDot=function(q,X,V){return q[X]*V[0]+q[X+1]*V[1]+q[X+2]*V[2]+q[X+3]*V[3]};P.quantize.stats=function(q,X,V){var K=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],Q=[0,0,0,0],Y=V-X>>2;for(var J=X;J>>0}};P.M4={multVec:function(q,X){return[q[0]*X[0]+q[1]*X[1]+q[2]*X[2]+q[3]*X[3],q[4]*X[0]+q[5]*X[1]+q[6]*X[2]+q[7]*X[3],q[8]*X[0]+q[9]*X[1]+q[10]*X[2]+q[11]*X[3],q[12]*X[0]+q[13]*X[1]+q[14]*X[2]+q[15]*X[3]]},dot:function(q,X){return q[0]*X[0]+q[1]*X[1]+q[2]*X[2]+q[3]*X[3]},sml:function(q,X){return[q*X[0],q*X[1],q*X[2],q*X[3]]}};P.encode.concatRGBA=function(q){var X=0;for(var V=0;V1)throw Error("Animated PNGs are not supported");var Q=new Uint8Array(K[0]),Y=lG(Q),J=Y.rgbChannel,G=Y.alphaChannel;this.rgbChannel=J;var W=G.some(function(Z){return Z<255});if(W)this.alphaChannel=G;this.type=fG(V.ctype),this.width=V.width,this.height=V.height,this.bitsPerComponent=8}return q.load=function(X){return new q(X)},q}();var _G=function(){function q(X){this.image=X,this.bitsPerComponent=X.bitsPerComponent,this.width=X.width,this.height=X.height,this.colorSpace="DeviceRGB"}return q.for=function(X){return _(this,void 0,void 0,function(){var V;return c(this,function(K){return V=IK.load(X),[2,new q(V)]})})},q.prototype.embedIntoContext=function(X,V){return _(this,void 0,void 0,function(){var K,Q;return c(this,function(Y){if(K=this.embedAlphaChannel(X),Q=X.flateStream(this.image.rgbChannel,{Type:"XObject",Subtype:"Image",BitsPerComponent:this.image.bitsPerComponent,Width:this.image.width,Height:this.image.height,ColorSpace:this.colorSpace,SMask:K}),V)return X.assign(V,Q),[2,V];else return[2,X.register(Q)];return[2]})})},q.prototype.embedAlphaChannel=function(X){if(!this.image.alphaChannel)return;var V=X.flateStream(this.image.alphaChannel,{Type:"XObject",Subtype:"Image",Height:this.image.height,Width:this.image.width,BitsPerComponent:this.image.bitsPerComponent,ColorSpace:"DeviceGray",Decode:[0,1]});return X.register(V)},q}(),X8=_G;var cG=function(){function q(X,V,K){this.bytes=X,this.start=V||0,this.pos=this.start,this.end=!!V&&!!K?V+K:this.bytes.length}return Object.defineProperty(q.prototype,"length",{get:function(){return this.end-this.start},enumerable:!1,configurable:!0}),Object.defineProperty(q.prototype,"isEmpty",{get:function(){return this.length===0},enumerable:!1,configurable:!0}),q.prototype.getByte=function(){if(this.pos>=this.end)return-1;return this.bytes[this.pos++]},q.prototype.getUint16=function(){var X=this.getByte(),V=this.getByte();if(X===-1||V===-1)return-1;return(X<<8)+V},q.prototype.getInt32=function(){var X=this.getByte(),V=this.getByte(),K=this.getByte(),Q=this.getByte();return(X<<24)+(V<<16)+(K<<8)+Q},q.prototype.getBytes=function(X,V){if(V===void 0)V=!1;var K=this.bytes,Q=this.pos,Y=this.end;if(!X){var J=K.subarray(Q,Y);return V?new Uint8ClampedArray(J):J}else{var G=Q+X;if(G>Y)G=Y;this.pos=G;var J=K.subarray(Q,G);return V?new Uint8ClampedArray(J):J}},q.prototype.peekByte=function(){var X=this.getByte();return this.pos--,X},q.prototype.peekBytes=function(X,V){if(V===void 0)V=!1;var K=this.getBytes(X,V);return this.pos-=K.length,K},q.prototype.skip=function(X){if(!X)X=1;this.pos+=X},q.prototype.reset=function(){this.pos=this.start},q.prototype.moveStart=function(){this.start=this.pos},q.prototype.makeSubStream=function(X,V){return new q(this.bytes,X,V)},q.prototype.decode=function(){return this.bytes},q}(),Hq=cG;var pG=new Uint8Array(0),dG=function(){function q(X){if(this.pos=0,this.bufferLength=0,this.eof=!1,this.buffer=pG,this.minBufferLength=512,X)while(this.minBufferLengthY)K=Y}else{while(!this.eof)this.readBlock();K=this.bufferLength}this.pos=K;var J=this.buffer.subarray(Q,K);return V&&!(J instanceof Uint8ClampedArray)?new Uint8ClampedArray(J):J},q.prototype.peekByte=function(){var X=this.getByte();return this.pos--,X},q.prototype.peekBytes=function(X,V){if(V===void 0)V=!1;var K=this.getBytes(X,V);return this.pos-=K.length,K},q.prototype.skip=function(X){if(!X)X=1;this.pos+=X},q.prototype.reset=function(){this.pos=0},q.prototype.makeSubStream=function(X,V){var K=X+V;while(this.bufferLength<=K&&!this.eof)this.readBlock();return new Hq(this.buffer,X,V)},q.prototype.decode=function(){while(!this.eof)this.readBlock();return this.buffer.subarray(0,this.bufferLength)},q.prototype.readBlock=function(){throw new u0(this.constructor.name,"readBlock")},q.prototype.ensureBuffer=function(X){var V=this.buffer;if(X<=V.byteLength)return V;var K=this.minBufferLength;while(K=0;--Z)W[G+Z]=U&255,U>>=8}},X}(d2),jK=nG;var rG=function(q){A(X,q);function X(V,K){var Q=q.call(this,K)||this;if(Q.stream=V,Q.firstDigit=-1,K)K=0.5*K;return Q}return X.prototype.readBlock=function(){var V=8000,K=this.stream.getBytes(V);if(!K.length){this.eof=!0;return}var Q=K.length+1>>1,Y=this.ensureBuffer(this.bufferLength+Q),J=this.bufferLength,G=this.firstDigit;for(var W=0,Z=K.length;W=48&&H<=57)U=H&15;else if(H>=65&&H<=70||H>=97&&H<=102)U=(H&15)+9;else if(H===62){this.eof=!0;break}else continue;if(G<0)G=U;else Y[J++]=G<<4|U,G=-1}if(G>=0&&this.eof)Y[J++]=G<<4,G=-1;this.firstDigit=G,this.bufferLength=J},X}(d2),LK=rG;var BK=new Int32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),iG=new Int32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),aG=new Int32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),oG=[new Int32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,590000,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],sG=[new Int32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5],tG=function(q){A(X,q);function X(V,K){var Q=q.call(this,K)||this;Q.stream=V;var Y=V.getByte(),J=V.getByte();if(Y===-1||J===-1)throw Error("Invalid header in flate stream: "+Y+", "+J);if((Y&15)!==8)throw Error("Unknown compression method in flate stream: "+Y+", "+J);if(((Y<<8)+J)%31!==0)throw Error("Bad FCHECK in flate stream: "+Y+", "+J);if(J&32)throw Error("FDICT bit set in flate stream: "+Y+", "+J);return Q.codeSize=0,Q.codeBuf=0,Q}return X.prototype.readBlock=function(){var V,K,Q=this.stream,Y=this.getBits(3);if(Y&1)this.eof=!0;if(Y>>=1,Y===0){var J=void 0;if((J=Q.getByte())===-1)throw Error("Bad block header in flate stream");var G=J;if((J=Q.getByte())===-1)throw Error("Bad block header in flate stream");if(G|=J<<8,(J=Q.getByte())===-1)throw Error("Bad block header in flate stream");var W=J;if((J=Q.getByte())===-1)throw Error("Bad block header in flate stream");if(W|=J<<8,W!==(~G&65535)&&(G!==0||W!==0))throw Error("Bad uncompressed block length in flate stream");this.codeBuf=0,this.codeSize=0;var Z=this.bufferLength;V=this.ensureBuffer(Z+G);var H=Z+G;if(this.bufferLength=H,G===0){if(Q.peekByte()===-1)this.eof=!0}else for(var U=Z;U0)v[O++]=S}z=this.generateHuffmanTable(v.subarray(0,M)),k=this.generateHuffmanTable(v.subarray(M,R))}else throw Error("Unknown block type in flate stream");V=this.buffer;var C=V?V.length:0,D=this.bufferLength;while(!0){var l=this.getCode(z);if(l<256){if(D+1>=C)V=this.ensureBuffer(D+1),C=V.length;V[D++]=l;continue}if(l===256){this.bufferLength=D;return}l-=257,l=iG[l];var u=l>>16;if(u>0)u=this.getBits(u);if(K=(l&65535)+u,l=this.getCode(k),l=aG[l],u=l>>16,u>0)u=this.getBits(u);var q0=(l&65535)+u;if(D+K>=C)V=this.ensureBuffer(D+K),C=V.length;for(var J0=0;J0>V,this.codeSize=Q-=V,J},X.prototype.getCode=function(V){var K=this.stream,Q=V[0],Y=V[1],J=this.codeSize,G=this.codeBuf,W;while(J>16,U=Z&65535;if(H<1||J>H,this.codeSize=J-H,U},X.prototype.generateHuffmanTable=function(V){var K=V.length,Q=0,Y;for(Y=0;YQ)Q=V[Y];var J=1<>=1;for(Y=z;Y0;if(!v||v<256)B[0]=v,L=1;else if(v>=258)if(v=0;J--)B[J]=U[G],G=k[G]}else B[L++]=B[0];else if(v===256){M=9,H=258,L=0;continue}else{this.eof=!0,delete this.lzwState;break}if(w)k[H]=j,z[H]=z[j]+1,U[H]=B[0],H++,M=H+Z&H+Z-1?M:Math.min(Math.log(H+Z)/0.6931471805599453+1,12)|0;if(j=v,O+=L,K>>K&(1<0){var J=this.stream.getBytes(Y);K.set(J,Q),Q+=Y}}else{Y=257-Y;var G=V[1];K=this.ensureBuffer(Q+Y+1);for(var W=0;WK.size())throw new Y5(V,0,K.size());K.remove(V)}},X.prototype.normalizedEntries=function(){var V=this.Kids();if(!V)V=this.dict.context.obj([this.ref]),this.dict.set(I.of("Kids"),V);return{Kids:V}},X.fromDict=function(V,K){return new X(V,K)},X}(Y8),K2=UZ;var zZ=function(q){A(X,q);function X(){return q!==null&&q.apply(this,arguments)||this}return X.prototype.Opt=function(){return this.dict.lookupMaybe(I.of("Opt"),K0,g,i)},X.prototype.setOpt=function(V){this.dict.set(I.of("Opt"),this.dict.context.obj(V))},X.prototype.getExportValues=function(){var V=this.Opt();if(!V)return;if(V instanceof K0||V instanceof g)return[V];var K=[];for(var Q=0,Y=V.size();QK.size())throw new Y5(V,0,K.size());K.remove(V)}},X.prototype.normalizeExportValues=function(){var V,K,Q,Y,J=(V=this.getExportValues())!==null&&V!==void 0?V:[],G=[],W=this.getWidgets();for(var Z=0,H=W.length;Z1){if(!this.hasFlag(G0.MultiSelect))throw new W7;this.dict.set(I.of("V"),this.dict.context.obj(V))}this.updateSelectedIndices(V)},X.prototype.valuesAreValid=function(V){var K=this.getOptions(),Q=function(W,Z){var H=V[W].decodeText();if(!K.find(function(U){return H===(U.display||U.value).decodeText()}))return{value:!1}};for(var Y=0,J=V.length;Y1){var K=Array(V.length),Q=this.getOptions(),Y=function(W,Z){var H=V[W].decodeText();K[W]=Q.findIndex(function(U){return H===(U.display||U.value).decodeText()})};for(var J=0,G=V.length;J0){var G=J.lookup(0,K0,g),W=J.lookupMaybe(1,K0,g);K.push({value:G,display:W||G})}}}return K}return[]},X}(K2),G8=kZ;var IZ=function(q){A(X,q);function X(){return q!==null&&q.apply(this,arguments)||this}return X.fromDict=function(V,K){return new X(V,K)},X.create=function(V){var K=V.obj({FT:"Ch",Ff:G0.Combo,Kids:[]}),Q=V.register(K);return new X(K,Q)},X}(G8),Q6=IZ;var EZ=function(q){A(X,q);function X(){return q!==null&&q.apply(this,arguments)||this}return X.prototype.addField=function(V){var K=this.normalizedEntries().Kids;K===null||K===void 0||K.push(V)},X.prototype.normalizedEntries=function(){var V=this.Kids();if(!V)V=this.dict.context.obj([]),this.dict.set(I.of("Kids"),V);return{Kids:V}},X.fromDict=function(V,K){return new X(V,K)},X.create=function(V){var K=V.obj({}),Q=V.register(K);return new X(K,Q)},X}(Y8),Y6=EZ;var jZ=function(q){A(X,q);function X(){return q!==null&&q.apply(this,arguments)||this}return X.fromDict=function(V,K){return new X(V,K)},X}(K2),F6=jZ;var LZ=function(q){A(X,q);function X(){return q!==null&&q.apply(this,arguments)||this}return X.prototype.MaxLen=function(){var V=this.dict.lookup(I.of("MaxLen"));if(V instanceof x)return V;return},X.prototype.Q=function(){var V=this.dict.lookup(I.of("Q"));if(V instanceof x)return V;return},X.prototype.setMaxLength=function(V){this.dict.set(I.of("MaxLen"),x.of(V))},X.prototype.removeMaxLength=function(){this.dict.delete(I.of("MaxLen"))},X.prototype.getMaxLength=function(){var V;return(V=this.MaxLen())===null||V===void 0?void 0:V.asNumber()},X.prototype.setQuadding=function(V){this.dict.set(I.of("Q"),x.of(V))},X.prototype.getQuadding=function(){var V;return(V=this.Q())===null||V===void 0?void 0:V.asNumber()},X.prototype.setValue=function(V){this.dict.set(I.of("V"),V)},X.prototype.removeValue=function(){this.dict.delete(I.of("V"))},X.prototype.getValue=function(){var V=this.V();if(V instanceof K0||V instanceof g)return V;return},X.fromDict=function(V,K){return new X(V,K)},X.create=function(V){var K=V.obj({FT:"Tx",Kids:[]}),Q=V.register(K);return new X(K,Q)},X}(K2),J6=LZ;var BZ=function(q){A(X,q);function X(){return q!==null&&q.apply(this,arguments)||this}return X.fromDict=function(V,K){return new X(V,K)},X.create=function(V){var K=V.obj({FT:"Btn",Ff:f0.PushButton,Kids:[]}),Q=V.register(K);return new X(K,Q)},X}(h6),G6=BZ;var TZ=function(q){A(X,q);function X(){return q!==null&&q.apply(this,arguments)||this}return X.prototype.setValue=function(V){var K=this.getOnValues();if(!K.includes(V)&&V!==I.of("Off"))throw new J5;this.dict.set(I.of("V"),V);var Q=this.getWidgets();for(var Y=0,J=Q.length;YY)throw new qq(K,Y);var J=K;for(var G=0,W=Q.size();GJ)return H.insertLeafNode(V,J)||Z;else J-=H.Count().asNumber();if(H instanceof _0)J-=1}if(J===0){this.insertLeafKid(Q.size(),V);return}throw new Xq(K,"insertLeafNode")},X.prototype.removeLeafNode=function(V,K){if(K===void 0)K=!0;var Q=this.Kids(),Y=this.Count().asNumber();if(V>=Y)throw new qq(V,Y);var J=V;for(var G=0,W=Q.size();GJ){if(H.removeLeafNode(J,K),K&&H.Kids().size()===0)Q.remove(G);return}else J-=H.Count().asNumber();if(H instanceof _0)if(J===0){this.removeKid(G);return}else J-=1}throw new Xq(V,"removeLeafNode")},X.prototype.ascend=function(V){V(this);var K=this.Parent();if(K)K.ascend(V)},X.prototype.traverse=function(V){var K=this.Kids();for(var Q=0,Y=K.size();QNumber.MAX_SAFE_INTEGER)if(this.capNumbers){var Q="Parsed number that is too large for some PDF readers: "+X+", using Number.MAX_SAFE_INTEGER instead.";return console.warn(Q),Number.MAX_SAFE_INTEGER}else{var Q="Parsed number that is too large for some PDF readers: "+X+", not capping.";console.warn(Q)}return K},q.prototype.skipWhitespace=function(){while(!this.bytes.done()&&k2[this.bytes.peek()])this.bytes.next()},q.prototype.skipLine=function(){while(!this.bytes.done()){var X=this.bytes.peek();if(X===AK||X===NK)return;this.bytes.next()}},q.prototype.skipComment=function(){if(this.bytes.peek()!==E.Percent)return!1;while(!this.bytes.done()){var X=this.bytes.peek();if(X===AK||X===NK)return!0;this.bytes.next()}return!0},q.prototype.skipWhitespaceAndComments=function(){this.skipWhitespace();while(this.skipComment())this.skipWhitespace()},q.prototype.matchKeyword=function(X){var V=this.bytes.offset();for(var K=0,Q=X.length;K=this.length},q.prototype.offset=function(){return this.idx},q.prototype.slice=function(X,V){return this.bytes.slice(X,V)},q.prototype.position=function(){return{line:this.line,column:this.column,offset:this.idx}},q.of=function(X){return new q(X)},q.fromPDFRawStream=function(X){return q.of(V8(X).decode())},q}(),D6=CZ;var hZ=E.Space,U1=E.CarriageReturn,z1=E.Newline,M1=[E.s,E.t,E.r,E.e,E.a,E.m],Eq=[E.e,E.n,E.d,E.s,E.t,E.r,E.e,E.a,E.m],M0={header:[E.Percent,E.P,E.D,E.F,E.Dash],eof:[E.Percent,E.Percent,E.E,E.O,E.F],obj:[E.o,E.b,E.j],endobj:[E.e,E.n,E.d,E.o,E.b,E.j],xref:[E.x,E.r,E.e,E.f],trailer:[E.t,E.r,E.a,E.i,E.l,E.e,E.r],startxref:[E.s,E.t,E.a,E.r,E.t,E.x,E.r,E.e,E.f],true:[E.t,E.r,E.u,E.e],false:[E.f,E.a,E.l,E.s,E.e],null:[E.n,E.u,E.l,E.l],stream:M1,streamEOF1:Q0(M1,[hZ,U1,z1]),streamEOF2:Q0(M1,[U1,z1]),streamEOF3:Q0(M1,[U1]),streamEOF4:Q0(M1,[z1]),endstream:Eq,EOF1endstream:Q0([U1,z1],Eq),EOF2endstream:Q0([U1],Eq),EOF3endstream:Q0([z1],Eq)};var FZ=function(q){A(X,q);function X(V,K,Q){if(Q===void 0)Q=!1;var Y=q.call(this,V,Q)||this;return Y.context=K,Y}return X.prototype.parseObject=function(){if(this.skipWhitespaceAndComments(),this.matchKeyword(M0.true))return c2.True;if(this.matchKeyword(M0.false))return c2.False;if(this.matchKeyword(M0.null))return F0;var V=this.bytes.peek();if(V===E.LessThan&&this.bytes.peekAhead(1)===E.LessThan)return this.parseDictOrStream();if(V===E.LessThan)return this.parseHexString();if(V===E.LeftParen)return this.parseString();if(V===E.ForwardSlash)return this.parseName();if(V===E.LeftSquareBracket)return this.parseArray();if(H1[V])return this.parseNumberOrRef();throw new M7(this.bytes.position(),V)},X.prototype.parseNumberOrRef=function(){var V=this.parseRawNumber();this.skipWhitespaceAndComments();var K=this.bytes.offset();if(P0[this.bytes.peek()]){var Q=this.parseRawNumber();if(this.skipWhitespaceAndComments(),this.bytes.peek()===E.R)return this.bytes.assertNext(E.R),a.of(V,Q)}return this.bytes.moveTo(K),x.of(V)},X.prototype.parseHexString=function(){var V="";this.bytes.assertNext(E.LessThan);while(!this.bytes.done()&&this.bytes.peek()!==E.GreaterThan)V+=t0(this.bytes.next());return this.bytes.assertNext(E.GreaterThan),g.of(V)},X.prototype.parseString=function(){var V=0,K=!1,Q="";while(!this.bytes.done()){var Y=this.bytes.next();if(Q+=t0(Y),!K){if(Y===E.LeftParen)V+=1;if(Y===E.RightParen)V-=1}if(Y===E.BackSlash)K=!K;else if(K)K=!1;if(V===0)return K0.of(Q.substring(1,Q.length-1))}throw new E7(this.bytes.position())},X.prototype.parseName=function(){this.bytes.assertNext(E.ForwardSlash);var V="";while(!this.bytes.done()){var K=this.bytes.peek();if(k2[K]||V2[K])break;V+=t0(K),this.bytes.next()}return I.of(V)},X.prototype.parseArray=function(){this.bytes.assertNext(E.LeftSquareBracket),this.skipWhitespaceAndComments();var V=i.withContext(this.context);while(this.bytes.peek()!==E.RightSquareBracket){var K=this.parseObject();V.push(K),this.skipWhitespaceAndComments()}return this.bytes.assertNext(E.RightSquareBracket),V},X.prototype.parseDict=function(){this.bytes.assertNext(E.LessThan),this.bytes.assertNext(E.LessThan),this.skipWhitespaceAndComments();var V=new Map;while(!this.bytes.done()&&this.bytes.peek()!==E.GreaterThan&&this.bytes.peekAhead(1)!==E.GreaterThan){var K=this.parseName(),Q=this.parseObject();V.set(K,Q),this.skipWhitespaceAndComments()}this.skipWhitespaceAndComments(),this.bytes.assertNext(E.GreaterThan),this.bytes.assertNext(E.GreaterThan);var Y=V.get(I.of("Type"));if(Y===I.of("Catalog"))return W8.fromMapWithContext(V,this.context);else if(Y===I.of("Pages"))return H8.fromMapWithContext(V,this.context);else if(Y===I.of("Page"))return _0.fromMapWithContext(V,this.context);else return m.fromMapWithContext(V,this.context)},X.prototype.parseDictOrStream=function(){var V=this.bytes.position(),K=this.parseDict();if(this.skipWhitespaceAndComments(),!this.matchKeyword(M0.streamEOF1)&&!this.matchKeyword(M0.streamEOF2)&&!this.matchKeyword(M0.streamEOF3)&&!this.matchKeyword(M0.streamEOF4)&&!this.matchKeyword(M0.stream))return K;var Q=this.bytes.offset(),Y,J=K.get(I.of("Length"));if(J instanceof x){if(Y=Q+J.asNumber(),this.bytes.moveTo(Y),this.skipWhitespaceAndComments(),!this.matchKeyword(M0.endstream))this.bytes.moveTo(Q),Y=this.findEndOfStreamFallback(V)}else Y=this.findEndOfStreamFallback(V);var G=this.bytes.slice(Q,Y);return A2.of(K,G)},X.prototype.findEndOfStreamFallback=function(V){var K=1,Q=this.bytes.offset();while(!this.bytes.done()){if(Q=this.bytes.offset(),this.matchKeyword(M0.stream))K+=1;else if(this.matchKeyword(M0.EOF1endstream)||this.matchKeyword(M0.EOF2endstream)||this.matchKeyword(M0.EOF3endstream)||this.matchKeyword(M0.endstream))K-=1;else this.bytes.next();if(K===0)break}if(K!==0)throw new I7(V);return Q},X.forBytes=function(V,K,Q){return new X(D6.of(V),K,Q)},X.forByteStream=function(V,K,Q){if(Q===void 0)Q=!1;return new X(V,K,Q)},X}(SK),U8=FZ;var PZ=function(q){A(X,q);function X(V,K){var Q=q.call(this,D6.fromPDFRawStream(V),V.dict.context)||this,Y=V.dict;return Q.alreadyParsed=!1,Q.shouldWaitForTick=K||function(){return!1},Q.firstOffset=Y.lookup(I.of("First"),x).asNumber(),Q.objectCount=Y.lookup(I.of("N"),x).asNumber(),Q}return X.prototype.parseIntoContext=function(){return _(this,void 0,void 0,function(){var V,K,Q,Y,J,G,W,Z;return c(this,function(H){switch(H.label){case 0:if(this.alreadyParsed)throw new Q5("PDFObjectStreamParser","parseIntoContext");this.alreadyParsed=!0,V=this.parseOffsetsAndObjectNumbers(),K=0,Q=V.length,H.label=1;case 1:if(!(K=E.Space&&K<=E.Tilde;if(Q){if(this.matchKeyword(M0.xref)||this.matchKeyword(M0.trailer)||this.matchKeyword(M0.startxref)||this.matchIndirectObjectHeader()){this.bytes.moveTo(V);break}}this.bytes.next()}},X.prototype.skipBinaryHeaderComment=function(){this.skipWhitespaceAndComments();try{var V=this.bytes.offset();this.parseIndirectObjectHeader(),this.bytes.moveTo(V)}catch(K){this.bytes.next(),this.skipWhitespaceAndComments()}},X.forBytesWithOptions=function(V,K,Q,Y){return new X(V,K,Q,Y)},X}(U8),Bq=uZ;var n2=function(q){return 1<0)K[K.length]=+Q;V[V.length]={cmd:X,args:K},K=[],Q="",Y=!1}X=Z}else if([" ",","].includes(Z)||Z==="-"&&Q.length>0&&Q[Q.length-1]!=="e"||Z==="."&&Y){if(Q.length===0)continue;if(K.length===J){if(V[V.length]={cmd:X,args:K},K=[+Q],X==="M")X="L";if(X==="m")X="l"}else K[K.length]=+Q;Y=Z===".",Q=["-","."].includes(Z)?Z:""}else if(Q+=Z,Z===".")Y=!0}if(Q.length>0)if(K.length===J){if(V[V.length]={cmd:X,args:K},K=[+Q],X==="M")X="L";if(X==="m")X="l"}else K[K.length]=+Q;return V[V.length]={cmd:X,args:K},V},oZ=function(q){d=n=Z0=W0=v1=R1=0;var X=[];for(var V=0;V1)z=Math.sqrt(z),V*=z,K*=z;var k=U/V,M=H/V,j=-H/K,B=U/K,L=k*G+M*W,O=j*G+B*W,N=k*q+M*X,R=j*q+B*X,v=(N-L)*(N-L)+(R-O)*(R-O),w=1/v-0.25;if(w<0)w=0;var $=Math.sqrt(w);if(Y===Q)$=-$;var S=0.5*(L+N)-$*(R-O),h=0.5*(O+R)+$*(N-L),b=Math.atan2(O-h,L-S),C=Math.atan2(R-h,N-S),D=C-b;if(D<0&&Y===1)D+=2*Math.PI;else if(D>0&&Y===0)D-=2*Math.PI;var l=Math.ceil(Math.abs(D/(Math.PI*0.5+0.001))),u=[];for(var q0=0;q0q.length)return Q-1;var B=X.heightAtSize(Q),L=B+B*0.2,O=L*Y;if(O>Math.abs(V.height))return Q-1;Q+=1}return Q},K3=function(q,X,V,K){var Q=V.width/K,Y=V.height,J=mK,G=J4(q);while(JQ*0.75;if(U)return J-1}var z=X.heightAtSize(J,{descender:!1});if(z>Y)return J-1;J+=1}return J},Q3=function(q){for(var X=q.length;X>0;X--)if(/\s/.test(q[X]))return X;return},Y3=function(q,X,V,K){var Q,Y=q.length;while(Y>0){var J=q.substring(0,Y),G=V.encodeText(J),W=V.widthOfTextAtSize(J,K);if(Wz)z=$+v;if(M+G>k)k=M+G;Z.push({text:N,encoded:R,width:v,height:G,x:$,y:M}),L=w===null||w===void 0?void 0:w.trim()}}return{fontSize:K,lineHeight:W,lines:Z,bounds:{x:H,y:U,width:z-H,height:k-U}}},KX=function(q,X){var{fontSize:V,font:K,bounds:Q,cellCount:Y}=X,J=F1(k6(q));if(J.length>Y)throw new qX(J.length,Y);if(V===void 0||V===0)V=K3(J,K,Q,Y);var G=Q.width/Y,W=K.heightAtSize(V,{descender:!1}),Z=Q.y+(Q.height/2-W/2),H=[],U=Q.x,z=Q.y,k=Q.x+Q.width,M=Q.y+Q.height,j=0,B=0;while(jk)k=$+v;if(Z+W>M)M=Z+W;H.push({text:J,encoded:R,width:v,height:W,x:$,y:Z}),j+=1,B+=N}return{fontSize:V,cells:H,bounds:{x:U,y:z,width:k-U,height:M-z}}},v8=function(q,X){var{alignment:V,fontSize:K,font:Q,bounds:Y}=X,J=F1(k6(q));if(K===void 0||K===0)K=lK([J],Q,Y);var G=Q.encodeText(J),W=Q.widthOfTextAtSize(J,K),Z=Q.heightAtSize(K,{descender:!1}),H=V===v0.Left?Y.x:V===v0.Center?Y.x+Y.width/2-W/2:V===v0.Right?Y.x+Y.width-W:Y.x,U=Y.y+(Y.height/2-Z/2);return{fontSize:K,line:{text:J,encoded:G,width:W,height:Z,x:H,y:U},bounds:{x:H,y:U,width:W,height:Z}}};var G2=function(q){if("normal"in q)return q;return{normal:q}},J3=/\/([^\0\t\n\f\r\ ]+)[\0\t\n\f\r\ ]+(\d*\.\d+|\d+)[\0\t\n\f\r\ ]+Tf/,m6=function(q){var X,V,K=(X=q.getDefaultAppearance())!==null&&X!==void 0?X:"",Q=(V=F5(K,J3).match)!==null&&V!==void 0?V:[],Y=Number(Q[2]);return isFinite(Y)?Y:void 0},G3=/(\d*\.\d+|\d+)[\0\t\n\f\r\ ]*(\d*\.\d+|\d+)?[\0\t\n\f\r\ ]*(\d*\.\d+|\d+)?[\0\t\n\f\r\ ]*(\d*\.\d+|\d+)?[\0\t\n\f\r\ ]+(g|rg|k)/,L2=function(q){var X,V=(X=q.getDefaultAppearance())!==null&&X!==void 0?X:"",K=F5(V,G3).match,Q=K!==null&&K!==void 0?K:[],Y=Q[1],J=Q[2],G=Q[3],W=Q[4],Z=Q[5];if(Z==="g"&&Y)return Sq(Number(Y));if(Z==="rg"&&Y&&J&&G)return Y0(Number(Y),Number(J),Number(G));if(Z==="k"&&Y&&J&&G&&W)return yq(Number(Y),Number(J),Number(G),Number(W));return},B2=function(q,X,V,K){var Q;if(K===void 0)K=0;var Y=[E2(X).toString(),T5((Q=V===null||V===void 0?void 0:V.name)!==null&&Q!==void 0?Q:"dummy__noop",K).toString()].join(` -`);q.setDefaultAppearance(Y)},QX=function(q,X){var V,K,Q,Y=L2(X),J=L2(q.acroField),G=X.getRectangle(),W=X.getAppearanceCharacteristics(),Z=X.getBorderStyle(),H=(V=Z===null||Z===void 0?void 0:Z.getWidth())!==null&&V!==void 0?V:0,U=I2(W===null||W===void 0?void 0:W.getRotation()),z=r2(G,U),k=z.width,M=z.height,j=j2(o(o({},G),{rotation:U})),B=Y0(0,0,0),L=(K=l0(W===null||W===void 0?void 0:W.getBorderColor()))!==null&&K!==void 0?K:B,O=l0(W===null||W===void 0?void 0:W.getBackgroundColor()),N=l0(W===null||W===void 0?void 0:W.getBackgroundColor(),0.8),R=(Q=Y!==null&&Y!==void 0?Y:J)!==null&&Q!==void 0?Q:B;if(Y)B2(X,R);else B2(q.acroField,R);var v={x:0+H/2,y:0+H/2,width:k-H,height:M-H,thickness:1.5,borderWidth:H,borderColor:L,markColor:R};return{normal:{on:Q0(j,B8(o(o({},v),{color:O,filled:!0}))),off:Q0(j,B8(o(o({},v),{color:O,filled:!1})))},down:{on:Q0(j,B8(o(o({},v),{color:N,filled:!0}))),off:Q0(j,B8(o(o({},v),{color:N,filled:!1})))}}},YX=function(q,X){var V,K,Q,Y=L2(X),J=L2(q.acroField),G=X.getRectangle(),W=X.getAppearanceCharacteristics(),Z=X.getBorderStyle(),H=(V=Z===null||Z===void 0?void 0:Z.getWidth())!==null&&V!==void 0?V:0,U=I2(W===null||W===void 0?void 0:W.getRotation()),z=r2(G,U),k=z.width,M=z.height,j=j2(o(o({},G),{rotation:U})),B=Y0(0,0,0),L=(K=l0(W===null||W===void 0?void 0:W.getBorderColor()))!==null&&K!==void 0?K:B,O=l0(W===null||W===void 0?void 0:W.getBackgroundColor()),N=l0(W===null||W===void 0?void 0:W.getBackgroundColor(),0.8),R=(Q=Y!==null&&Y!==void 0?Y:J)!==null&&Q!==void 0?Q:B;if(Y)B2(X,R);else B2(q.acroField,R);var v={x:k/2,y:M/2,width:k-H,height:M-H,borderWidth:H,borderColor:L,dotColor:R};return{normal:{on:Q0(j,T8(o(o({},v),{color:O,filled:!0}))),off:Q0(j,T8(o(o({},v),{color:O,filled:!1})))},down:{on:Q0(j,T8(o(o({},v),{color:N,filled:!0}))),off:Q0(j,T8(o(o({},v),{color:N,filled:!1})))}}},JX=function(q,X,V){var K,Q,Y,J,G,W=L2(X),Z=L2(q.acroField),H=m6(X),U=m6(q.acroField),z=X.getRectangle(),k=X.getAppearanceCharacteristics(),M=X.getBorderStyle(),j=k===null||k===void 0?void 0:k.getCaptions(),B=(K=j===null||j===void 0?void 0:j.normal)!==null&&K!==void 0?K:"",L=(Y=(Q=j===null||j===void 0?void 0:j.down)!==null&&Q!==void 0?Q:B)!==null&&Y!==void 0?Y:"",O=(J=M===null||M===void 0?void 0:M.getWidth())!==null&&J!==void 0?J:0,N=I2(k===null||k===void 0?void 0:k.getRotation()),R=r2(z,N),v=R.width,w=R.height,$=j2(o(o({},z),{rotation:N})),S=Y0(0,0,0),h=l0(k===null||k===void 0?void 0:k.getBorderColor()),b=l0(k===null||k===void 0?void 0:k.getBackgroundColor()),C=l0(k===null||k===void 0?void 0:k.getBackgroundColor(),0.8),D={x:O,y:O,width:v-O*2,height:w-O*2},l=v8(B,{alignment:v0.Center,fontSize:H!==null&&H!==void 0?H:U,font:V,bounds:D}),u=v8(L,{alignment:v0.Center,fontSize:H!==null&&H!==void 0?H:U,font:V,bounds:D}),q0=Math.min(l.fontSize,u.fontSize),J0=(G=W!==null&&W!==void 0?W:Z)!==null&&G!==void 0?G:S;if(W||H!==void 0)B2(X,J0,V,q0);else B2(q.acroField,J0,V,q0);var r={x:0+O/2,y:0+O/2,width:v-O,height:w-O,borderWidth:O,borderColor:h,textColor:J0,font:V.name,fontSize:q0};return{normal:Q0($,hq(o(o({},r),{color:b,textLines:[l.line]}))),down:Q0($,hq(o(o({},r),{color:C,textLines:[u.line]})))}},GX=function(q,X,V){var K,Q,Y,J,G=L2(X),W=L2(q.acroField),Z=m6(X),H=m6(q.acroField),U=X.getRectangle(),z=X.getAppearanceCharacteristics(),k=X.getBorderStyle(),M=(K=q.getText())!==null&&K!==void 0?K:"",j=(Q=k===null||k===void 0?void 0:k.getWidth())!==null&&Q!==void 0?Q:0,B=I2(z===null||z===void 0?void 0:z.getRotation()),L=r2(U,B),O=L.width,N=L.height,R=j2(o(o({},U),{rotation:B})),v=Y0(0,0,0),w=l0(z===null||z===void 0?void 0:z.getBorderColor()),$=l0(z===null||z===void 0?void 0:z.getBackgroundColor()),S,h,b=q.isCombed()?0:1,C={x:j+b,y:j+b,width:O-(j+b)*2,height:N-(j+b)*2};if(q.isMultiline()){var D=uq(M,{alignment:q.getAlignment(),fontSize:Z!==null&&Z!==void 0?Z:H,font:V,bounds:C});S=D.lines,h=D.fontSize}else if(q.isCombed()){var D=KX(M,{fontSize:Z!==null&&Z!==void 0?Z:H,font:V,bounds:C,cellCount:(Y=q.getMaxLength())!==null&&Y!==void 0?Y:0});S=D.cells,h=D.fontSize}else{var D=v8(M,{alignment:q.getAlignment(),fontSize:Z!==null&&Z!==void 0?Z:H,font:V,bounds:C});S=[D.line],h=D.fontSize}var l=(J=G!==null&&G!==void 0?G:W)!==null&&J!==void 0?J:v;if(G||Z!==void 0)B2(X,l,V,h);else B2(q.acroField,l,V,h);var u={x:0+j/2,y:0+j/2,width:O-j,height:N-j,borderWidth:j!==null&&j!==void 0?j:0,borderColor:w,textColor:l,font:V.name,fontSize:h,color:$,textLines:S,padding:b};return Q0(R,Pq(u))},ZX=function(q,X,V){var K,Q,Y,J=L2(X),G=L2(q.acroField),W=m6(X),Z=m6(q.acroField),H=X.getRectangle(),U=X.getAppearanceCharacteristics(),z=X.getBorderStyle(),k=(K=q.getSelected()[0])!==null&&K!==void 0?K:"",M=(Q=z===null||z===void 0?void 0:z.getWidth())!==null&&Q!==void 0?Q:0,j=I2(U===null||U===void 0?void 0:U.getRotation()),B=r2(H,j),L=B.width,O=B.height,N=j2(o(o({},H),{rotation:j})),R=Y0(0,0,0),v=l0(U===null||U===void 0?void 0:U.getBorderColor()),w=l0(U===null||U===void 0?void 0:U.getBackgroundColor()),$=1,S={x:M+$,y:M+$,width:L-(M+$)*2,height:O-(M+$)*2},h=v8(k,{alignment:v0.Left,fontSize:W!==null&&W!==void 0?W:Z,font:V,bounds:S}),b=h.line,C=h.fontSize,D=(Y=J!==null&&J!==void 0?J:G)!==null&&Y!==void 0?Y:R;if(J||W!==void 0)B2(X,D,V,C);else B2(q.acroField,D,V,C);var l={x:0+M/2,y:0+M/2,width:L-M,height:O-M,borderWidth:M!==null&&M!==void 0?M:0,borderColor:v,textColor:D,font:V.name,fontSize:C,color:w,textLines:[b],padding:$};return Q0(N,Pq(l))},WX=function(q,X,V){var K,Q,Y=L2(X),J=L2(q.acroField),G=m6(X),W=m6(q.acroField),Z=X.getRectangle(),H=X.getAppearanceCharacteristics(),U=X.getBorderStyle(),z=(K=U===null||U===void 0?void 0:U.getWidth())!==null&&K!==void 0?K:0,k=I2(H===null||H===void 0?void 0:H.getRotation()),M=r2(Z,k),j=M.width,B=M.height,L=j2(o(o({},Z),{rotation:k})),O=Y0(0,0,0),N=l0(H===null||H===void 0?void 0:H.getBorderColor()),R=l0(H===null||H===void 0?void 0:H.getBackgroundColor()),v=q.getOptions(),w=q.getSelected();if(q.isSorted())v.sort();var $="";for(var S=0,h=v.length;S1||Q.length===1&&K)this.enableMultiselect();var G=Array(Q.length);for(var W=0,Z=Q.length;W1||Q.length===1&&K)this.enableMultiselect();var J=Array(Q.length);for(var G=0,W=Q.length;GK)throw new XX(V.length,K,this.getName());if(this.markAsDirty(),this.disableRichFormatting(),V)this.acroField.setValue(g.fromText(V));else this.acroField.removeValue()},X.prototype.getAlignment=function(){var V=this.acroField.getQuadding();return V===0?v0.Left:V===1?v0.Center:V===2?v0.Right:v0.Left},X.prototype.setAlignment=function(V){M2(V,"alignment",v0),this.markAsDirty(),this.acroField.setQuadding(V)},X.prototype.getMaxLength=function(){return this.acroField.getMaxLength()},X.prototype.setMaxLength=function(V){if(X2(V,"maxLength",0,Number.MAX_SAFE_INTEGER),this.markAsDirty(),V===void 0)this.acroField.removeMaxLength();else{var K=this.getText();if(K&&K.length>V)throw new VX(K.length,V,this.getName());this.acroField.setMaxLength(V)}},X.prototype.removeMaxLength=function(){this.markAsDirty(),this.acroField.removeMaxLength()},X.prototype.setImage=function(V){var K=this.getAlignment(),Q=K===v0.Center?T2.Center:K===v0.Right?T2.Right:T2.Left,Y=this.acroField.getWidgets();for(var J=0,G=Y.length;J"u")globalThis.Buffer=y;if(typeof globalThis.process>"u")globalThis.process=N3;globalThis.__bundles=globalThis.__bundles||{};globalThis.__bundles["pdf-lib"]=UX;})(); diff --git a/apps/sim/lib/execution/sandbox/bundles/pptxgenjs.cjs b/apps/sim/lib/execution/sandbox/bundles/pptxgenjs.cjs deleted file mode 100644 index ec626780fb6..00000000000 --- a/apps/sim/lib/execution/sandbox/bundles/pptxgenjs.cjs +++ /dev/null @@ -1,124 +0,0 @@ -// sandbox bundle: pptxgenjs -// generated by apps/sim/lib/execution/sandbox/bundles/build.ts -// do not edit by hand. run `bun run build:sandbox-bundles` to regenerate. -(()=>{var fJ=Object.create;var{getPrototypeOf:RJ,defineProperty:X6,getOwnPropertyNames:$9,getOwnPropertyDescriptor:IJ}=Object,Q9=Object.prototype.hasOwnProperty;function q9($){return this[$]}var CJ,jJ,K9=($,q,Q)=>{var K=$!=null&&typeof $==="object";if(K){var J=q?CJ??=new WeakMap:jJ??=new WeakMap,Z=J.get($);if(Z)return Z}Q=$!=null?fJ(RJ($)):{};let G=q||!$||!$.__esModule?X6(Q,"default",{value:$,enumerable:!0}):Q;for(let W of $9($))if(!Q9.call(G,W))X6(G,W,{get:q9.bind($,W),enumerable:!0});if(K)J.set($,G);return G},X0=($)=>{var q=(e7??=new WeakMap).get($),Q;if(q)return q;if(q=X6({},"__esModule",{value:!0}),$&&typeof $==="object"||typeof $==="function"){for(var K of $9($))if(!Q9.call(q,K))X6(q,K,{get:q9.bind($,K),enumerable:!(Q=IJ($,K))||Q.enumerable})}return e7.set($,q),q},e7,N0=($,q)=>()=>(q||$((q={exports:{}}).exports,q),q.exports);var gJ=($)=>$;function AJ($,q){this[$]=gJ.bind(null,q)}var c1=($,q)=>{for(var Q in q)X6($,Q,{get:q[Q],enumerable:!0,configurable:!0,set:AJ.bind(q,Q)})};var b1=($,q)=>()=>($&&(q=$($=0)),q);var J9=(($)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy($,{get:(q,Q)=>(typeof require<"u"?require:q)[Q]}):$)(function($){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+$+'" is not supported')});var K2={};c1(K2,{transcode:()=>MV,resolveObjectURL:()=>BV,kStringMaxLength:()=>w9,kMaxLength:()=>y6,isUtf8:()=>zV,isAscii:()=>FV,default:()=>wV,constants:()=>EJ,btoa:()=>PJ,atob:()=>TJ,INSPECT_MAX_BYTES:()=>M9,File:()=>uJ,Buffer:()=>o,Blob:()=>SJ});function XJ($){var q=$.length;if(q%4>0)throw Error("Invalid string. Length must be a multiple of 4");var Q=$.indexOf("=");if(Q===-1)Q=q;var K=Q===q?0:4-Q%4;return[Q,K]}function yJ($,q){return($+q)*3/4-q}function hJ($){var q,Q=XJ($),K=Q[0],J=Q[1],Z=new Uint8Array(yJ(K,J)),G=0,W=J>0?K-4:K,B;for(B=0;B>16&255,Z[G++]=q>>8&255,Z[G++]=q&255;if(J===2)q=F2[$.charCodeAt(B)]<<2|F2[$.charCodeAt(B+1)]>>4,Z[G++]=q&255;if(J===1)q=F2[$.charCodeAt(B)]<<10|F2[$.charCodeAt(B+1)]<<4|F2[$.charCodeAt(B+2)]>>2,Z[G++]=q>>8&255,Z[G++]=q&255;return Z}function xJ($){return I2[$>>18&63]+I2[$>>12&63]+I2[$>>6&63]+I2[$&63]}function OJ($,q,Q){var K,J=[];for(var Z=q;ZW?W:G+Z));if(K===1)q=$[Q-1],J.push(I2[q>>2]+I2[q<<4&63]+"==");else if(K===2)q=($[Q-2]<<8)+$[Q-1],J.push(I2[q>>10]+I2[q>>4&63]+I2[q<<2&63]+"=");return J.join("")}function N8($,q,Q,K,J){var Z,G,W=J*8-K-1,B=(1<>1,U=-7,w=Q?J-1:0,F=Q?-1:1,M=$[q+w];w+=F,Z=M&(1<<-U)-1,M>>=-U,U+=W;for(;U>0;Z=Z*256+$[q+w],w+=F,U-=8);G=Z&(1<<-U)-1,Z>>=-U,U+=K;for(;U>0;G=G*256+$[q+w],w+=F,U-=8);if(Z===0)Z=1-V;else if(Z===B)return G?NaN:(M?-1:1)*(1/0);else G=G+Math.pow(2,K),Z=Z-V;return(M?-1:1)*G*Math.pow(2,Z-K)}function F9($,q,Q,K,J,Z){var G,W,B,V=Z*8-J-1,U=(1<>1,F=J===23?Math.pow(2,-24)-Math.pow(2,-77):0,M=K?0:Z-1,k=K?1:-1,f=q<0||q===0&&1/q<0?1:0;if(q=Math.abs(q),isNaN(q)||q===1/0)W=isNaN(q)?1:0,G=U;else{if(G=Math.floor(Math.log(q)/Math.LN2),q*(B=Math.pow(2,-G))<1)G--,B*=2;if(G+w>=1)q+=F/B;else q+=F*Math.pow(2,1-w);if(q*B>=2)G++,B/=2;if(G+w>=U)W=0,G=U;else if(G+w>=1)W=(q*B-1)*Math.pow(2,J),G=G+w;else W=q*Math.pow(2,w-1)*Math.pow(2,J),G=0}for(;J>=8;$[Q+M]=W&255,M+=k,W/=256,J-=8);G=G<0;$[Q+M]=G&255,M+=k,G/=256,V-=8);$[Q+M-k]|=f*128}function S2($){if($>y6)throw RangeError('The value "'+$+'" is invalid for option "size"');let q=new Uint8Array($);return Object.setPrototypeOf(q,o.prototype),q}function h5($,q,Q){return class extends Q{constructor(){super();Object.defineProperty(this,"message",{value:q.apply(this,arguments),writable:!0,configurable:!0}),this.name=`${this.name} [${$}]`,this.stack,delete this.name}get code(){return $}set code(K){Object.defineProperty(this,"code",{configurable:!0,enumerable:!0,value:K,writable:!0})}toString(){return`${this.name} [${$}]: ${this.message}`}}}function o($,q,Q){if(typeof $==="number"){if(typeof q==="string")throw TypeError('The "string" argument must be of type string. Received type number');return x5($)}return N9($,q,Q)}function N9($,q,Q){if(typeof $==="string")return nJ($,q);if(ArrayBuffer.isView($))return dJ($);if($==null)throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof $);if(C2($,ArrayBuffer)||$&&C2($.buffer,ArrayBuffer))return X5($,q,Q);if(typeof SharedArrayBuffer<"u"&&(C2($,SharedArrayBuffer)||$&&C2($.buffer,SharedArrayBuffer)))return X5($,q,Q);if(typeof $==="number")throw TypeError('The "value" argument must not be of type number. Received type number');let K=$.valueOf&&$.valueOf();if(K!=null&&K!==$)return o.from(K,q,Q);let J=mJ($);if(J)return J;if(typeof Symbol<"u"&&Symbol.toPrimitive!=null&&typeof $[Symbol.toPrimitive]==="function")return o.from($[Symbol.toPrimitive]("string"),q,Q);throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof $)}function Y9($){if(typeof $!=="number")throw TypeError('"size" argument must be of type number');else if($<0)throw RangeError('The value "'+$+'" is invalid for option "size"')}function bJ($,q,Q){if(Y9($),$<=0)return S2($);if(q!==void 0)return typeof Q==="string"?S2($).fill(q,Q):S2($).fill(q);return S2($)}function x5($){return Y9($),S2($<0?0:O5($)|0)}function nJ($,q){if(typeof q!=="string"||q==="")q="utf8";if(!o.isEncoding(q))throw TypeError("Unknown encoding: "+q);let Q=k9($,q)|0,K=S2(Q),J=K.write($,q);if(J!==Q)K=K.slice(0,J);return K}function A5($){let q=$.length<0?0:O5($.length)|0,Q=S2(q);for(let K=0;K=y6)throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+y6.toString(16)+" bytes");return $|0}function k9($,q){if(o.isBuffer($))return $.length;if(ArrayBuffer.isView($)||C2($,ArrayBuffer))return $.byteLength;if(typeof $!=="string")throw TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof $);let Q=$.length,K=arguments.length>2&&arguments[2]===!0;if(!K&&Q===0)return 0;let J=!1;for(;;)switch(q){case"ascii":case"latin1":case"binary":return Q;case"utf8":case"utf-8":return y5($).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Q*2;case"hex":return Q>>>1;case"base64":return j9($).length;default:if(J)return K?-1:y5($).length;q=(""+q).toLowerCase(),J=!0}}function pJ($,q,Q){let K=!1;if(q===void 0||q<0)q=0;if(q>this.length)return"";if(Q===void 0||Q>this.length)Q=this.length;if(Q<=0)return"";if(Q>>>=0,q>>>=0,Q<=q)return"";if(!$)$="utf8";while(!0)switch($){case"hex":return QV(this,q,Q);case"utf8":case"utf-8":return L9(this,q,Q);case"ascii":return eJ(this,q,Q);case"latin1":case"binary":return $V(this,q,Q);case"base64":return sJ(this,q,Q);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return qV(this,q,Q);default:if(K)throw TypeError("Unknown encoding: "+$);$=($+"").toLowerCase(),K=!0}}function w1($,q,Q){let K=$[q];$[q]=$[Q],$[Q]=K}function D9($,q,Q,K,J){if($.length===0)return-1;if(typeof Q==="string")K=Q,Q=0;else if(Q>2147483647)Q=2147483647;else if(Q<-2147483648)Q=-2147483648;if(Q=+Q,Number.isNaN(Q))Q=J?0:$.length-1;if(Q<0)Q=$.length+Q;if(Q>=$.length)if(J)return-1;else Q=$.length-1;else if(Q<0)if(J)Q=0;else return-1;if(typeof q==="string")q=o.from(q,K);if(o.isBuffer(q)){if(q.length===0)return-1;return W9($,q,Q,K,J)}else if(typeof q==="number"){if(q=q&255,typeof Uint8Array.prototype.indexOf==="function")if(J)return Uint8Array.prototype.indexOf.call($,q,Q);else return Uint8Array.prototype.lastIndexOf.call($,q,Q);return W9($,[q],Q,K,J)}throw TypeError("val must be string, number or Buffer")}function W9($,q,Q,K,J){let Z=1,G=$.length,W=q.length;if(K!==void 0){if(K=String(K).toLowerCase(),K==="ucs2"||K==="ucs-2"||K==="utf16le"||K==="utf-16le"){if($.length<2||q.length<2)return-1;Z=2,G/=2,W/=2,Q/=2}}function B(U,w){if(Z===1)return U[w];else return U.readUInt16BE(w*Z)}let V;if(J){let U=-1;for(V=Q;VG)Q=G-W;for(V=Q;V>=0;V--){let U=!0;for(let w=0;wJ)K=J;let Z=q.length;if(K>Z/2)K=Z/2;let G;for(G=0;G239?4:Z>223?3:Z>191?2:1;if(J+W<=Q){let B,V,U,w;switch(W){case 1:if(Z<128)G=Z;break;case 2:if(B=$[J+1],(B&192)===128){if(w=(Z&31)<<6|B&63,w>127)G=w}break;case 3:if(B=$[J+1],V=$[J+2],(B&192)===128&&(V&192)===128){if(w=(Z&15)<<12|(B&63)<<6|V&63,w>2047&&(w<55296||w>57343))G=w}break;case 4:if(B=$[J+1],V=$[J+2],U=$[J+3],(B&192)===128&&(V&192)===128&&(U&192)===128){if(w=(Z&15)<<18|(B&63)<<12|(V&63)<<6|U&63,w>65535&&w<1114112)G=w}}}if(G===null)G=65533,W=1;else if(G>65535)G-=65536,K.push(G>>>10&1023|55296),G=56320|G&1023;K.push(G),J+=W}return tJ(K)}function tJ($){let q=$.length;if(q<=B9)return String.fromCharCode.apply(String,$);let Q="",K=0;while(KK)Q=K;let J="";for(let Z=q;ZQ)throw RangeError("Trying to access beyond buffer length")}function s0($,q,Q,K,J,Z){if(!o.isBuffer($))throw TypeError('"buffer" argument must be a Buffer instance');if(q>J||q$.length)throw RangeError("Index out of range")}function H9($,q,Q,K,J){C9(q,K,J,$,Q,7);let Z=Number(q&BigInt(4294967295));$[Q++]=Z,Z=Z>>8,$[Q++]=Z,Z=Z>>8,$[Q++]=Z,Z=Z>>8,$[Q++]=Z;let G=Number(q>>BigInt(32)&BigInt(4294967295));return $[Q++]=G,G=G>>8,$[Q++]=G,G=G>>8,$[Q++]=G,G=G>>8,$[Q++]=G,Q}function v9($,q,Q,K,J){C9(q,K,J,$,Q,7);let Z=Number(q&BigInt(4294967295));$[Q+7]=Z,Z=Z>>8,$[Q+6]=Z,Z=Z>>8,$[Q+5]=Z,Z=Z>>8,$[Q+4]=Z;let G=Number(q>>BigInt(32)&BigInt(4294967295));return $[Q+3]=G,G=G>>8,$[Q+2]=G,G=G>>8,$[Q+1]=G,G=G>>8,$[Q]=G,Q+8}function f9($,q,Q,K,J,Z){if(Q+K>$.length)throw RangeError("Index out of range");if(Q<0)throw RangeError("Index out of range")}function R9($,q,Q,K,J){if(q=+q,Q=Q>>>0,!J)f9($,q,Q,4,340282346638528860000000000000000000000,-340282346638528860000000000000000000000);return F9($,q,Q,K,23,4),Q+4}function I9($,q,Q,K,J){if(q=+q,Q=Q>>>0,!J)f9($,q,Q,8,179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,-179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);return F9($,q,Q,K,52,8),Q+8}function z9($){let q="",Q=$.length,K=$[0]==="-"?1:0;for(;Q>=K+4;Q-=3)q=`_${$.slice(Q-3,Q)}${q}`;return`${$.slice(0,Q)}${q}`}function KV($,q,Q){if(n1(q,"offset"),$[q]===void 0||$[q+Q]===void 0)h6(q,$.length-(Q+1))}function C9($,q,Q,K,J,Z){if($>Q||$3)if(q===0||q===BigInt(0))W=`>= 0${G} and < 2${G} ** ${(Z+1)*8}${G}`;else W=`>= -(2${G} ** ${(Z+1)*8-1}${G}) and < 2 ** ${(Z+1)*8-1}${G}`;else W=`>= ${q}${G} and <= ${Q}${G}`;throw new g5("value",W,$)}KV(K,J,Z)}function n1($,q){if(typeof $!=="number")throw new cJ(q,"number",$)}function h6($,q,Q){if(Math.floor($)!==$)throw n1($,Q),new g5(Q||"offset","an integer",$);if(q<0)throw new _J;throw new g5(Q||"offset",`>= ${Q?1:0} and <= ${q}`,$)}function VV($){if($=$.split("=")[0],$=$.trim().replace(JV,""),$.length<2)return"";while($.length%4!==0)$=$+"=";return $}function y5($,q){q=q||1/0;let Q,K=$.length,J=null,Z=[];for(let G=0;G55295&&Q<57344){if(!J){if(Q>56319){if((q-=3)>-1)Z.push(239,191,189);continue}else if(G+1===K){if((q-=3)>-1)Z.push(239,191,189);continue}J=Q;continue}if(Q<56320){if((q-=3)>-1)Z.push(239,191,189);J=Q;continue}Q=(J-55296<<10|Q-56320)+65536}else if(J){if((q-=3)>-1)Z.push(239,191,189)}if(J=null,Q<128){if((q-=1)<0)break;Z.push(Q)}else if(Q<2048){if((q-=2)<0)break;Z.push(Q>>6|192,Q&63|128)}else if(Q<65536){if((q-=3)<0)break;Z.push(Q>>12|224,Q>>6&63|128,Q&63|128)}else if(Q<1114112){if((q-=4)<0)break;Z.push(Q>>18|240,Q>>12&63|128,Q>>6&63|128,Q&63|128)}else throw Error("Invalid code point")}return Z}function UV($){let q=[];for(let Q=0;Q<$.length;++Q)q.push($.charCodeAt(Q)&255);return q}function ZV($,q){let Q,K,J,Z=[];for(let G=0;G<$.length;++G){if((q-=2)<0)break;Q=$.charCodeAt(G),K=Q>>8,J=Q%256,Z.push(J),Z.push(K)}return Z}function j9($){return hJ(VV($))}function Y8($,q,Q,K){let J;for(J=0;J=q.length||J>=$.length)break;q[J+Q]=$[J]}return J}function C2($,q){return $ instanceof q||$!=null&&$.constructor!=null&&$.constructor.name!=null&&$.constructor.name===q.name}function l2($){return typeof BigInt>"u"?WV:$}function WV(){throw Error("BigInt not supported")}function P5($){return()=>{throw Error($+" is not implemented for node:buffer browser polyfill")}}var I2,F2,j5="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",M1,U9,G9,M9=50,y6=2147483647,w9=536870888,PJ,TJ,uJ,SJ,EJ,_J,cJ,g5,B9=4096,JV,GV,BV,zV,FV=($)=>{for(let q of $)if(q.charCodeAt(0)>127)return!1;return!0},MV,wV;var t0=b1(()=>{I2=[],F2=[];for(M1=0,U9=j5.length;M14294967296)J=z9(String(Q));else if(typeof Q==="bigint"){if(J=String(Q),Q>BigInt(2)**BigInt(32)||Q<-(BigInt(2)**BigInt(32)))J=z9(J);J+="n"}return K+=` It must be ${q}. Received ${J}`,K},RangeError);Object.defineProperty(o.prototype,"parent",{enumerable:!0,get:function(){if(!o.isBuffer(this))return;return this.buffer}});Object.defineProperty(o.prototype,"offset",{enumerable:!0,get:function(){if(!o.isBuffer(this))return;return this.byteOffset}});o.poolSize=8192;o.from=function($,q,Q){return N9($,q,Q)};Object.setPrototypeOf(o.prototype,Uint8Array.prototype);Object.setPrototypeOf(o,Uint8Array);o.alloc=function($,q,Q){return bJ($,q,Q)};o.allocUnsafe=function($){return x5($)};o.allocUnsafeSlow=function($){return x5($)};o.isBuffer=function($){return $!=null&&$._isBuffer===!0&&$!==o.prototype};o.compare=function($,q){if(C2($,Uint8Array))$=o.from($,$.offset,$.byteLength);if(C2(q,Uint8Array))q=o.from(q,q.offset,q.byteLength);if(!o.isBuffer($)||!o.isBuffer(q))throw TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if($===q)return 0;let Q=$.length,K=q.length;for(let J=0,Z=Math.min(Q,K);JK.length){if(!o.isBuffer(Z))Z=o.from(Z);Z.copy(K,J)}else Uint8Array.prototype.set.call(K,Z,J);else if(!o.isBuffer(Z))throw TypeError('"list" argument must be an Array of Buffers');else Z.copy(K,J);J+=Z.length}return K};o.byteLength=k9;o.prototype._isBuffer=!0;o.prototype.swap16=function(){let $=this.length;if($%2!==0)throw RangeError("Buffer size must be a multiple of 16-bits");for(let q=0;q<$;q+=2)w1(this,q,q+1);return this};o.prototype.swap32=function(){let $=this.length;if($%4!==0)throw RangeError("Buffer size must be a multiple of 32-bits");for(let q=0;q<$;q+=4)w1(this,q,q+3),w1(this,q+1,q+2);return this};o.prototype.swap64=function(){let $=this.length;if($%8!==0)throw RangeError("Buffer size must be a multiple of 64-bits");for(let q=0;q<$;q+=8)w1(this,q,q+7),w1(this,q+1,q+6),w1(this,q+2,q+5),w1(this,q+3,q+4);return this};o.prototype.toString=function(){let $=this.length;if($===0)return"";if(arguments.length===0)return L9(this,0,$);return pJ.apply(this,arguments)};o.prototype.toLocaleString=o.prototype.toString;o.prototype.equals=function($){if(!o.isBuffer($))throw TypeError("Argument must be a Buffer");if(this===$)return!0;return o.compare(this,$)===0};o.prototype.inspect=function(){let $="",q=M9;if($=this.toString("hex",0,q).replace(/(.{2})/g,"$1 ").trim(),this.length>q)$+=" ... ";return""};if(G9)o.prototype[G9]=o.prototype.inspect;o.prototype.compare=function($,q,Q,K,J){if(C2($,Uint8Array))$=o.from($,$.offset,$.byteLength);if(!o.isBuffer($))throw TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof $);if(q===void 0)q=0;if(Q===void 0)Q=$?$.length:0;if(K===void 0)K=0;if(J===void 0)J=this.length;if(q<0||Q>$.length||K<0||J>this.length)throw RangeError("out of range index");if(K>=J&&q>=Q)return 0;if(K>=J)return-1;if(q>=Q)return 1;if(q>>>=0,Q>>>=0,K>>>=0,J>>>=0,this===$)return 0;let Z=J-K,G=Q-q,W=Math.min(Z,G),B=this.slice(K,J),V=$.slice(q,Q);for(let U=0;U>>0,isFinite(Q)){if(Q=Q>>>0,K===void 0)K="utf8"}else K=Q,Q=void 0;else throw Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");let J=this.length-q;if(Q===void 0||Q>J)Q=J;if($.length>0&&(Q<0||q<0)||q>this.length)throw RangeError("Attempt to write outside buffer bounds");if(!K)K="utf8";let Z=!1;for(;;)switch(K){case"hex":return iJ(this,$,q,Q);case"utf8":case"utf-8":return oJ(this,$,q,Q);case"ascii":case"latin1":case"binary":return aJ(this,$,q,Q);case"base64":return lJ(this,$,q,Q);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return rJ(this,$,q,Q);default:if(Z)throw TypeError("Unknown encoding: "+K);K=(""+K).toLowerCase(),Z=!0}};o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};o.prototype.slice=function($,q){let Q=this.length;if($=~~$,q=q===void 0?Q:~~q,$<0){if($+=Q,$<0)$=0}else if($>Q)$=Q;if(q<0){if(q+=Q,q<0)q=0}else if(q>Q)q=Q;if(q<$)q=$;let K=this.subarray($,q);return Object.setPrototypeOf(K,o.prototype),K};o.prototype.readUintLE=o.prototype.readUIntLE=function($,q,Q){if($=$>>>0,q=q>>>0,!Q)b0($,q,this.length);let K=this[$],J=1,Z=0;while(++Z>>0,q=q>>>0,!Q)b0($,q,this.length);let K=this[$+--q],J=1;while(q>0&&(J*=256))K+=this[$+--q]*J;return K};o.prototype.readUint8=o.prototype.readUInt8=function($,q){if($=$>>>0,!q)b0($,1,this.length);return this[$]};o.prototype.readUint16LE=o.prototype.readUInt16LE=function($,q){if($=$>>>0,!q)b0($,2,this.length);return this[$]|this[$+1]<<8};o.prototype.readUint16BE=o.prototype.readUInt16BE=function($,q){if($=$>>>0,!q)b0($,2,this.length);return this[$]<<8|this[$+1]};o.prototype.readUint32LE=o.prototype.readUInt32LE=function($,q){if($=$>>>0,!q)b0($,4,this.length);return(this[$]|this[$+1]<<8|this[$+2]<<16)+this[$+3]*16777216};o.prototype.readUint32BE=o.prototype.readUInt32BE=function($,q){if($=$>>>0,!q)b0($,4,this.length);return this[$]*16777216+(this[$+1]<<16|this[$+2]<<8|this[$+3])};o.prototype.readBigUInt64LE=l2(function($){$=$>>>0,n1($,"offset");let q=this[$],Q=this[$+7];if(q===void 0||Q===void 0)h6($,this.length-8);let K=q+this[++$]*256+this[++$]*65536+this[++$]*16777216,J=this[++$]+this[++$]*256+this[++$]*65536+Q*16777216;return BigInt(K)+(BigInt(J)<>>0,n1($,"offset");let q=this[$],Q=this[$+7];if(q===void 0||Q===void 0)h6($,this.length-8);let K=q*16777216+this[++$]*65536+this[++$]*256+this[++$],J=this[++$]*16777216+this[++$]*65536+this[++$]*256+Q;return(BigInt(K)<>>0,q=q>>>0,!Q)b0($,q,this.length);let K=this[$],J=1,Z=0;while(++Z=J)K-=Math.pow(2,8*q);return K};o.prototype.readIntBE=function($,q,Q){if($=$>>>0,q=q>>>0,!Q)b0($,q,this.length);let K=q,J=1,Z=this[$+--K];while(K>0&&(J*=256))Z+=this[$+--K]*J;if(J*=128,Z>=J)Z-=Math.pow(2,8*q);return Z};o.prototype.readInt8=function($,q){if($=$>>>0,!q)b0($,1,this.length);if(!(this[$]&128))return this[$];return(255-this[$]+1)*-1};o.prototype.readInt16LE=function($,q){if($=$>>>0,!q)b0($,2,this.length);let Q=this[$]|this[$+1]<<8;return Q&32768?Q|4294901760:Q};o.prototype.readInt16BE=function($,q){if($=$>>>0,!q)b0($,2,this.length);let Q=this[$+1]|this[$]<<8;return Q&32768?Q|4294901760:Q};o.prototype.readInt32LE=function($,q){if($=$>>>0,!q)b0($,4,this.length);return this[$]|this[$+1]<<8|this[$+2]<<16|this[$+3]<<24};o.prototype.readInt32BE=function($,q){if($=$>>>0,!q)b0($,4,this.length);return this[$]<<24|this[$+1]<<16|this[$+2]<<8|this[$+3]};o.prototype.readBigInt64LE=l2(function($){$=$>>>0,n1($,"offset");let q=this[$],Q=this[$+7];if(q===void 0||Q===void 0)h6($,this.length-8);let K=this[$+4]+this[$+5]*256+this[$+6]*65536+(Q<<24);return(BigInt(K)<>>0,n1($,"offset");let q=this[$],Q=this[$+7];if(q===void 0||Q===void 0)h6($,this.length-8);let K=(q<<24)+this[++$]*65536+this[++$]*256+this[++$];return(BigInt(K)<>>0,!q)b0($,4,this.length);return N8(this,$,!0,23,4)};o.prototype.readFloatBE=function($,q){if($=$>>>0,!q)b0($,4,this.length);return N8(this,$,!1,23,4)};o.prototype.readDoubleLE=function($,q){if($=$>>>0,!q)b0($,8,this.length);return N8(this,$,!0,52,8)};o.prototype.readDoubleBE=function($,q){if($=$>>>0,!q)b0($,8,this.length);return N8(this,$,!1,52,8)};o.prototype.writeUintLE=o.prototype.writeUIntLE=function($,q,Q,K){if($=+$,q=q>>>0,Q=Q>>>0,!K){let G=Math.pow(2,8*Q)-1;s0(this,$,q,Q,G,0)}let J=1,Z=0;this[q]=$&255;while(++Z>>0,Q=Q>>>0,!K){let G=Math.pow(2,8*Q)-1;s0(this,$,q,Q,G,0)}let J=Q-1,Z=1;this[q+J]=$&255;while(--J>=0&&(Z*=256))this[q+J]=$/Z&255;return q+Q};o.prototype.writeUint8=o.prototype.writeUInt8=function($,q,Q){if($=+$,q=q>>>0,!Q)s0(this,$,q,1,255,0);return this[q]=$&255,q+1};o.prototype.writeUint16LE=o.prototype.writeUInt16LE=function($,q,Q){if($=+$,q=q>>>0,!Q)s0(this,$,q,2,65535,0);return this[q]=$&255,this[q+1]=$>>>8,q+2};o.prototype.writeUint16BE=o.prototype.writeUInt16BE=function($,q,Q){if($=+$,q=q>>>0,!Q)s0(this,$,q,2,65535,0);return this[q]=$>>>8,this[q+1]=$&255,q+2};o.prototype.writeUint32LE=o.prototype.writeUInt32LE=function($,q,Q){if($=+$,q=q>>>0,!Q)s0(this,$,q,4,4294967295,0);return this[q+3]=$>>>24,this[q+2]=$>>>16,this[q+1]=$>>>8,this[q]=$&255,q+4};o.prototype.writeUint32BE=o.prototype.writeUInt32BE=function($,q,Q){if($=+$,q=q>>>0,!Q)s0(this,$,q,4,4294967295,0);return this[q]=$>>>24,this[q+1]=$>>>16,this[q+2]=$>>>8,this[q+3]=$&255,q+4};o.prototype.writeBigUInt64LE=l2(function($,q=0){return H9(this,$,q,BigInt(0),BigInt("0xffffffffffffffff"))});o.prototype.writeBigUInt64BE=l2(function($,q=0){return v9(this,$,q,BigInt(0),BigInt("0xffffffffffffffff"))});o.prototype.writeIntLE=function($,q,Q,K){if($=+$,q=q>>>0,!K){let W=Math.pow(2,8*Q-1);s0(this,$,q,Q,W-1,-W)}let J=0,Z=1,G=0;this[q]=$&255;while(++J>0)-G&255}return q+Q};o.prototype.writeIntBE=function($,q,Q,K){if($=+$,q=q>>>0,!K){let W=Math.pow(2,8*Q-1);s0(this,$,q,Q,W-1,-W)}let J=Q-1,Z=1,G=0;this[q+J]=$&255;while(--J>=0&&(Z*=256)){if($<0&&G===0&&this[q+J+1]!==0)G=1;this[q+J]=($/Z>>0)-G&255}return q+Q};o.prototype.writeInt8=function($,q,Q){if($=+$,q=q>>>0,!Q)s0(this,$,q,1,127,-128);if($<0)$=255+$+1;return this[q]=$&255,q+1};o.prototype.writeInt16LE=function($,q,Q){if($=+$,q=q>>>0,!Q)s0(this,$,q,2,32767,-32768);return this[q]=$&255,this[q+1]=$>>>8,q+2};o.prototype.writeInt16BE=function($,q,Q){if($=+$,q=q>>>0,!Q)s0(this,$,q,2,32767,-32768);return this[q]=$>>>8,this[q+1]=$&255,q+2};o.prototype.writeInt32LE=function($,q,Q){if($=+$,q=q>>>0,!Q)s0(this,$,q,4,2147483647,-2147483648);return this[q]=$&255,this[q+1]=$>>>8,this[q+2]=$>>>16,this[q+3]=$>>>24,q+4};o.prototype.writeInt32BE=function($,q,Q){if($=+$,q=q>>>0,!Q)s0(this,$,q,4,2147483647,-2147483648);if($<0)$=4294967295+$+1;return this[q]=$>>>24,this[q+1]=$>>>16,this[q+2]=$>>>8,this[q+3]=$&255,q+4};o.prototype.writeBigInt64LE=l2(function($,q=0){return H9(this,$,q,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))});o.prototype.writeBigInt64BE=l2(function($,q=0){return v9(this,$,q,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))});o.prototype.writeFloatLE=function($,q,Q){return R9(this,$,q,!0,Q)};o.prototype.writeFloatBE=function($,q,Q){return R9(this,$,q,!1,Q)};o.prototype.writeDoubleLE=function($,q,Q){return I9(this,$,q,!0,Q)};o.prototype.writeDoubleBE=function($,q,Q){return I9(this,$,q,!1,Q)};o.prototype.copy=function($,q,Q,K){if(!o.isBuffer($))throw TypeError("argument should be a Buffer");if(!Q)Q=0;if(!K&&K!==0)K=this.length;if(q>=$.length)q=$.length;if(!q)q=0;if(K>0&&K=this.length)throw RangeError("Index out of range");if(K<0)throw RangeError("sourceEnd out of bounds");if(K>this.length)K=this.length;if($.length-q>>0,Q=Q===void 0?this.length:Q>>>0,!$)$=0;let J;if(typeof $==="number")for(J=q;J{var S0=y9.exports={},j2,g2;function T5(){throw Error("setTimeout has not been defined")}function u5(){throw Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function")j2=setTimeout;else j2=T5}catch($){j2=T5}try{if(typeof clearTimeout==="function")g2=clearTimeout;else g2=u5}catch($){g2=u5}})();function g9($){if(j2===setTimeout)return setTimeout($,0);if((j2===T5||!j2)&&setTimeout)return j2=setTimeout,setTimeout($,0);try{return j2($,0)}catch(q){try{return j2.call(null,$,0)}catch(Q){return j2.call(this,$,0)}}}function NV($){if(g2===clearTimeout)return clearTimeout($);if((g2===u5||!g2)&&clearTimeout)return g2=clearTimeout,clearTimeout($);try{return g2($)}catch(q){try{return g2.call(null,$)}catch(Q){return g2.call(this,$)}}}var E2=[],d1=!1,N1,k8=-1;function YV(){if(!d1||!N1)return;if(d1=!1,N1.length)E2=N1.concat(E2);else k8=-1;if(E2.length)A9()}function A9(){if(d1)return;var $=g9(YV);d1=!0;var q=E2.length;while(q){N1=E2,E2=[];while(++k81)for(var Q=1;Qn9,once:()=>c9,listenerCount:()=>d9,init:()=>r2,getMaxListeners:()=>p9,getEventListeners:()=>b9,default:()=>CV,captureRejectionSymbol:()=>u9,addAbortListener:()=>i9,EventEmitter:()=>r2});function S9($,q){var{_events:Q}=$;if(q[0]??=Error("Unhandled error."),!Q)throw q[0];var K=Q[T9];if(K)for(var J of O9.call(K))J.apply($,q);var Z=Q.error;if(!Z)throw q[0];for(var J of O9.call(Z))J.apply($,q);return!0}function LV($,q,Q,K){q.then(void 0,function(J){queueMicrotask(()=>HV($,J,Q,K))})}function HV($,q,Q,K){if(typeof $[x9]==="function")$[x9](q,Q,...K);else try{$[Y1]=!1,$.emit("error",q)}finally{$[Y1]=!0}}function E9($,q,Q){Q.warned=!0;let K=Error(`Possible EventEmitter memory leak detected. ${Q.length} ${String(q)} listeners added to [${$.constructor.name}]. Use emitter.setMaxListeners() to increase limit`);K.name="MaxListenersExceededWarning",K.emitter=$,K.type=q,K.count=Q.length,console.warn(K)}function _9($,q,...Q){this.removeListener($,q),q.apply(this,Q)}function c9($,q,Q){var K=Q?.signal;if(m9(K,"options.signal"),K?.aborted)throw new S5(void 0,{cause:K?.reason});let{resolve:J,reject:Z,promise:G}=$newPromiseCapability(Promise),W=(U)=>{if($.removeListener(q,B),K!=null)D8(K,"abort",V);Z(U)},B=(...U)=>{if(typeof $.removeListener==="function")$.removeListener("error",W);if(K!=null)D8(K,"abort",V);J(U)};if(P9($,q,B,{once:!0}),q!=="error"&&typeof $.once==="function")$.once("error",W);function V(){D8($,q,B),D8($,"error",W),Z(new S5(void 0,{cause:K?.reason}))}if(K!=null)P9(K,"abort",V,{once:!0});return G}function b9($,q){return $.listeners(q)}function n9($,...q){_5($,"setMaxListeners",0);var Q;if(q&&(Q=q.length))for(let K=0;KK||(Q!=null||K!=null)&&Number.isNaN($))throw RV(q,`${Q!=null?`>= ${Q}`:""}${Q!=null&&K!=null?" && ":""}${K!=null?`<= ${K}`:""}`,$)}function x6($){if(typeof $!=="function")throw TypeError("The listener must be a function")}function IV($,q){if(typeof $!=="boolean")throw m1(q,"boolean",$)}function p9($){return $?._maxListeners??k1}function i9($,q){if($===void 0)throw m1("signal","AbortSignal",$);if(m9($,"signal"),typeof q!=="function")throw m1("listener","function",q);let Q;if($.aborted)queueMicrotask(()=>q());else $.addEventListener("abort",q,{__proto__:null,once:!0}),Q=()=>{$.removeEventListener("abort",q)};return{__proto__:null,[Symbol.dispose](){Q?.()}}}var E5,Y1,T9,kV,DV,x9,u9,O9,k1=10,r2=function($){if(this._events===void 0||this._events===this.__proto__._events)this._events={__proto__:null},this._eventsCount=0;if(this._maxListeners??=void 0,this[Y1]=$?.captureRejections?Boolean($?.captureRejections):y0[Y1])this.emit=fV},y0,vV=function($,...q){if($==="error")return S9(this,q);var{_events:Q}=this;if(Q===void 0)return!1;var K=Q[$];if(K===void 0)return!1;let J=K.length>1?K.slice():K;for(let Z=0,{length:G}=J;Z1?K.slice():K;for(let Z=0,{length:G}=J;Z{E5=Symbol.for,Y1=Symbol("kCapture"),T9=E5("events.errorMonitor"),kV=Symbol("events.maxEventTargetListeners"),DV=Symbol("events.maxEventTargetListenersWarned"),x9=E5("nodejs.rejection"),u9=E5("nodejs.rejection"),O9=Array.prototype.slice,y0=r2.prototype={};y0._events=void 0;y0._eventsCount=0;y0._maxListeners=void 0;y0.setMaxListeners=function($){return _5($,"setMaxListeners",0),this._maxListeners=$,this};y0.constructor=r2;y0.getMaxListeners=function(){return this?._maxListeners??k1};y0.emit=vV;y0.addListener=function($,q){x6(q);var Q=this._events;if(!Q)Q=this._events={__proto__:null},this._eventsCount=0;else if(Q.newListener)this.emit("newListener",$,q.listener??q);var K=Q[$];if(!K)Q[$]=[q],this._eventsCount++;else{K.push(q);var J=this._maxListeners??k1;if(J>0&&K.length>J&&!K.warned)E9(this,$,K)}return this};y0.on=y0.addListener;y0.prependListener=function($,q){x6(q);var Q=this._events;if(!Q)Q=this._events={__proto__:null},this._eventsCount=0;else if(Q.newListener)this.emit("newListener",$,q.listener??q);var K=Q[$];if(!K)Q[$]=[q],this._eventsCount++;else{K.unshift(q);var J=this._maxListeners??k1;if(J>0&&K.length>J&&!K.warned)E9(this,$,K)}return this};y0.once=function($,q){x6(q);let Q=_9.bind(this,$,q);return Q.listener=q,this.addListener($,Q),this};y0.prependOnceListener=function($,q){x6(q);let Q=_9.bind(this,$,q);return Q.listener=q,this.prependListener($,Q),this};y0.removeListener=function($,q){x6(q);var{_events:Q}=this;if(!Q)return this;var K=Q[$];if(!K)return this;var J=K.length;let Z=-1;for(let G=J-1;G>=0;G--)if(K[G]===q||K[G].listener===q){Z=G;break}if(Z<0)return this;if(Z===0)K.shift();else K.splice(Z,1);if(K.length===0)delete Q[$],this._eventsCount--;return this};y0.off=y0.removeListener;y0.removeAllListeners=function($){var{_events:q}=this;if($&&q){if(q[$])delete q[$],this._eventsCount--}else this._events={__proto__:null};return this};y0.listeners=function($){var{_events:q}=this;if(!q)return[];var Q=q[$];if(!Q)return[];return Q.map((K)=>K.listener??K)};y0.rawListeners=function($){var{_events:q}=this;if(!q)return[];var Q=q[$];if(!Q)return[];return Q.slice()};y0.listenerCount=function($){var{_events:q}=this;if(!q)return 0;return q[$]?.length??0};y0.eventNames=function(){return this._eventsCount>0?Reflect.ownKeys(this._events):[]};y0[Y1]=!1;S5=class S5 extends Error{constructor($="The operation was aborted",q=void 0){if(q!==void 0&&typeof q!=="object")throw m1("options","Object",q);super($,q);this.code="ABORT_ERR",this.name="AbortError"}};Object.defineProperties(r2,{captureRejections:{get(){return y0[Y1]},set($){IV($,"EventEmitter.captureRejections"),y0[Y1]=$},enumerable:!0},defaultMaxListeners:{enumerable:!0,get:()=>{return k1},set:($)=>{_5($,"defaultMaxListeners",0),k1=$}},kMaxEventTargetListeners:{value:kV,enumerable:!1,configurable:!1,writable:!1},kMaxEventTargetListenersWarned:{value:DV,enumerable:!1,configurable:!1,writable:!1}});Object.assign(r2,{once:c9,getEventListeners:b9,getMaxListeners:p9,setMaxListeners:n9,EventEmitter:r2,usingDomains:!1,captureRejectionSymbol:u9,errorMonitor:T9,addAbortListener:i9,init:r2,listenerCount:d9});CV=r2});var a1=N0((Bz,$$)=>{var g0=($,q)=>()=>(q||$((q={exports:{}}).exports,q),q.exports),P0=g0(($,q)=>{class Q extends Error{constructor(K){if(!Array.isArray(K))throw TypeError(`Expected input to be an Array, got ${typeof K}`);let J="";for(let Z=0;Z{q.exports={format(Q,...K){return Q.replace(/%([sdifj])/g,function(...[J,Z]){let G=K.shift();if(Z==="f")return G.toFixed(6);else if(Z==="j")return JSON.stringify(G);else if(Z==="s"&&typeof G==="object")return`${G.constructor!==Object?G.constructor.name:""} {}`.trim();else return G.toString()})},inspect(Q){switch(typeof Q){case"string":if(Q.includes("'")){if(!Q.includes('"'))return`"${Q}"`;else if(!Q.includes("`")&&!Q.includes("${"))return`\`${Q}\``}return`'${Q}'`;case"number":if(isNaN(Q))return"NaN";else if(Object.is(Q,-0))return String(Q);return Q;case"bigint":return`${String(Q)}n`;case"boolean":case"undefined":return String(Q);case"object":return"{}"}}}}),a0=g0(($,q)=>{var{format:Q,inspect:K}=o9(),{AggregateError:J}=P0(),Z=globalThis.AggregateError||J,G=Symbol("kIsNodeError"),W=["string","function","number","object","Function","Object","boolean","bigint","symbol"],B=/^([A-Z][a-z0-9]*)+$/,V={};function U(D,z){if(!D)throw new V.ERR_INTERNAL_ASSERTION(z)}function w(D){let z="",N=D.length,H=D[0]==="-"?1:0;for(;N>=H+4;N-=3)z=`_${D.slice(N-3,N)}${z}`;return`${D.slice(0,N)}${z}`}function F(D,z,N){if(typeof z==="function")return U(z.length<=N.length,`Code: ${D}; The provided arguments length (${N.length}) does not match the required ones (${z.length}).`),z(...N);let H=(z.match(/%[dfijoOs]/g)||[]).length;if(U(H===N.length,`Code: ${D}; The provided arguments length (${N.length}) does not match the required ones (${H}).`),N.length===0)return z;return Q(z,...N)}function M(D,z,N){if(!N)N=Error;class H extends N{constructor(...v){super(F(D,z,v))}toString(){return`${this.name} [${D}]: ${this.message}`}}Object.defineProperties(H.prototype,{name:{value:N.name,writable:!0,enumerable:!1,configurable:!0},toString:{value(){return`${this.name} [${D}]: ${this.message}`},writable:!0,enumerable:!1,configurable:!0}}),H.prototype.code=D,H.prototype[G]=!0,V[D]=H}function k(D){let z="__node_internal_"+D.name;return Object.defineProperty(D,"name",{value:z}),D}function f(D,z){if(D&&z&&D!==z){if(Array.isArray(z.errors))return z.errors.push(D),z;let N=new Z([z,D],z.message);return N.code=z.code,N}return D||z}class L extends Error{constructor(D="The operation was aborted",z=void 0){if(z!==void 0&&typeof z!=="object")throw new V.ERR_INVALID_ARG_TYPE("options","Object",z);super(D,z);this.code="ABORT_ERR",this.name="AbortError"}}M("ERR_ASSERTION","%s",Error),M("ERR_INVALID_ARG_TYPE",(D,z,N)=>{if(U(typeof D==="string","'name' must be a string"),!Array.isArray(z))z=[z];let H="The ";if(D.endsWith(" argument"))H+=`${D} `;else H+=`"${D}" ${D.includes(".")?"property":"argument"} `;H+="must be ";let v=[],j=[],n=[];for(let _ of z)if(U(typeof _==="string","All expected entries have to be of type string"),W.includes(_))v.push(_.toLowerCase());else if(B.test(_))j.push(_);else U(_!=="object",'The value "object" should be written as "Object"'),n.push(_);if(j.length>0){let _=v.indexOf("object");if(_!==-1)v.splice(v,_,1),j.push("Object")}if(v.length>0){switch(v.length){case 1:H+=`of type ${v[0]}`;break;case 2:H+=`one of type ${v[0]} or ${v[1]}`;break;default:{let _=v.pop();H+=`one of type ${v.join(", ")}, or ${_}`}}if(j.length>0||n.length>0)H+=" or "}if(j.length>0){switch(j.length){case 1:H+=`an instance of ${j[0]}`;break;case 2:H+=`an instance of ${j[0]} or ${j[1]}`;break;default:{let _=j.pop();H+=`an instance of ${j.join(", ")}, or ${_}`}}if(n.length>0)H+=" or "}switch(n.length){case 0:break;case 1:if(n[0].toLowerCase()!==n[0])H+="an ";H+=`${n[0]}`;break;case 2:H+=`one of ${n[0]} or ${n[1]}`;break;default:{let _=n.pop();H+=`one of ${n.join(", ")}, or ${_}`}}if(N==null)H+=`. Received ${N}`;else if(typeof N==="function"&&N.name)H+=`. Received function ${N.name}`;else if(typeof N==="object"){var d;if((d=N.constructor)!==null&&d!==void 0&&d.name)H+=`. Received an instance of ${N.constructor.name}`;else{let _=K(N,{depth:-1});H+=`. Received ${_}`}}else{let _=K(N,{colors:!1});if(_.length>25)_=`${_.slice(0,25)}...`;H+=`. Received type ${typeof N} (${_})`}return H},TypeError),M("ERR_INVALID_ARG_VALUE",(D,z,N="is invalid")=>{let H=K(z);if(H.length>128)H=H.slice(0,128)+"...";return`The ${D.includes(".")?"property":"argument"} '${D}' ${N}. Received ${H}`},TypeError),M("ERR_INVALID_RETURN_VALUE",(D,z,N)=>{var H;let v=N!==null&&N!==void 0&&(H=N.constructor)!==null&&H!==void 0&&H.name?`instance of ${N.constructor.name}`:`type ${typeof N}`;return`Expected ${D} to be returned from the "${z}" function but got ${v}.`},TypeError),M("ERR_MISSING_ARGS",(...D)=>{U(D.length>0,"At least one arg needs to be specified");let z,N=D.length;switch(D=(Array.isArray(D)?D:[D]).map((H)=>`"${H}"`).join(" or "),N){case 1:z+=`The ${D[0]} argument`;break;case 2:z+=`The ${D[0]} and ${D[1]} arguments`;break;default:{let H=D.pop();z+=`The ${D.join(", ")}, and ${H} arguments`}break}return`${z} must be specified`},TypeError),M("ERR_OUT_OF_RANGE",(D,z,N)=>{U(z,'Missing "range" argument');let H;if(Number.isInteger(N)&&Math.abs(N)>4294967296)H=w(String(N));else if(typeof N==="bigint"){H=String(N);let v=BigInt(2)**BigInt(32);if(N>v||N<-v)H=w(H);H+="n"}else H=K(N);return`The value of "${D}" is out of range. It must be ${z}. Received ${H}`},RangeError),M("ERR_MULTIPLE_CALLBACK","Callback called multiple times",Error),M("ERR_METHOD_NOT_IMPLEMENTED","The %s method is not implemented",Error),M("ERR_STREAM_ALREADY_FINISHED","Cannot call %s after a stream was finished",Error),M("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable",Error),M("ERR_STREAM_DESTROYED","Cannot call %s after a stream was destroyed",Error),M("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),M("ERR_STREAM_PREMATURE_CLOSE","Premature close",Error),M("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF",Error),M("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event",Error),M("ERR_STREAM_WRITE_AFTER_END","write after end",Error),M("ERR_UNKNOWN_ENCODING","Unknown encoding: %s",TypeError),q.exports={AbortError:L,aggregateTwoErrors:k(f),hideStackFrames:k,codes:V}}),jV=g0(($,q)=>{Object.defineProperty($,"__esModule",{value:!0});var Q=new WeakMap,K=new WeakMap;function J(X){let P=Q.get(X);return console.assert(P!=null,"'this' is expected an Event object, but got",X),P}function Z(X){if(X.passiveListener!=null){if(typeof console<"u"&&typeof console.error==="function")console.error("Unable to preventDefault inside passive event listener invocation.",X.passiveListener);return}if(!X.event.cancelable)return;if(X.canceled=!0,typeof X.event.preventDefault==="function")X.event.preventDefault()}function G(X,P){Q.set(this,{eventTarget:X,event:P,eventPhase:2,currentTarget:X,canceled:!1,stopped:!1,immediateStopped:!1,passiveListener:null,timeStamp:P.timeStamp||Date.now()}),Object.defineProperty(this,"isTrusted",{value:!1,enumerable:!0});let g=Object.keys(P);for(let c=0;c0){let X=Array(arguments.length);for(let P=0;P{Object.defineProperty($,"__esModule",{value:!0});var Q=jV();class K extends Q.EventTarget{constructor(){super();throw TypeError("AbortSignal cannot be constructed directly")}get aborted(){let U=G.get(this);if(typeof U!=="boolean")throw TypeError(`Expected 'this' to be an 'AbortSignal' object, but got ${this===null?"null":typeof this}`);return U}}Q.defineEventAttribute(K.prototype,"abort");function J(){let U=Object.create(K.prototype);return Q.EventTarget.call(U),G.set(U,!1),U}function Z(U){if(G.get(U)!==!1)return;G.set(U,!0),U.dispatchEvent({type:"abort"})}var G=new WeakMap;if(Object.defineProperties(K.prototype,{aborted:{enumerable:!0}}),typeof Symbol==="function"&&typeof Symbol.toStringTag==="symbol")Object.defineProperty(K.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortSignal"});class W{constructor(){B.set(this,J())}get signal(){return V(this)}abort(){Z(V(this))}}var B=new WeakMap;function V(U){let w=B.get(U);if(w==null)throw TypeError(`Expected 'this' to be an 'AbortController' object, but got ${U===null?"null":typeof U}`);return w}if(Object.defineProperties(W.prototype,{signal:{enumerable:!0},abort:{enumerable:!0}}),typeof Symbol==="function"&&typeof Symbol.toStringTag==="symbol")Object.defineProperty(W.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortController"});$.AbortController=W,$.AbortSignal=K,$.default=W,q.exports=W,q.exports.AbortController=q.exports.default=W,q.exports.AbortSignal=K}),e0=g0(($,q)=>{var Q=(t0(),X0(K2)),{format:K,inspect:J}=o9(),{codes:{ERR_INVALID_ARG_TYPE:Z}}=a0(),{kResistStopPropagation:G,AggregateError:W,SymbolDispose:B}=P0(),V=globalThis.AbortSignal||O6().AbortSignal,U=globalThis.AbortController||O6().AbortController,w=Object.getPrototypeOf(async function(){}).constructor,F=globalThis.Blob||Q.Blob,M=typeof F<"u"?function(L){return L instanceof F}:function(L){return!1},k=(L,D)=>{if(L!==void 0&&(L===null||typeof L!=="object"||!("aborted"in L)))throw new Z(D,"AbortSignal",L)},f=(L,D)=>{if(typeof L!=="function")throw new Z(D,"Function",L)};q.exports={AggregateError:W,kEmptyObject:Object.freeze({}),once(L){let D=!1;return function(...z){if(D)return;D=!0,L.apply(this,z)}},createDeferredPromise:function(){let L,D;return{promise:new Promise((z,N)=>{L=z,D=N}),resolve:L,reject:D}},promisify(L){return new Promise((D,z)=>{L((N,...H)=>{if(N)return z(N);return D(...H)})})},debuglog(){return function(){}},format:K,inspect:J,types:{isAsyncFunction(L){return L instanceof w},isArrayBufferView(L){return ArrayBuffer.isView(L)}},isBlob:M,deprecate(L,D){return L},addAbortListener:(i1(),X0(p1)).addAbortListener||function(L,D){if(L===void 0)throw new Z("signal","AbortSignal",L);k(L,"signal"),f(D,"listener");let z;if(L.aborted)queueMicrotask(()=>D());else L.addEventListener("abort",D,{__proto__:null,once:!0,[G]:!0}),z=()=>{L.removeEventListener("abort",D)};return{__proto__:null,[B](){var N;(N=z)===null||N===void 0||N()}}},AbortSignalAny:V.any||function(L){if(L.length===1)return L[0];let D=new U,z=()=>D.abort();return L.forEach((N)=>{k(N,"signals"),N.addEventListener("abort",z,{once:!0})}),D.signal.addEventListener("abort",()=>{L.forEach((N)=>N.removeEventListener("abort",z))},{once:!0}),D.signal}},q.exports.promisify.custom=Symbol.for("nodejs.util.promisify.custom")}),P6=g0(($,q)=>{var{ArrayIsArray:Q,ArrayPrototypeIncludes:K,ArrayPrototypeJoin:J,ArrayPrototypeMap:Z,NumberIsInteger:G,NumberIsNaN:W,NumberMAX_SAFE_INTEGER:B,NumberMIN_SAFE_INTEGER:V,NumberParseInt:U,ObjectPrototypeHasOwnProperty:w,RegExpPrototypeExec:F,String:M,StringPrototypeToUpperCase:k,StringPrototypeTrim:f}=P0(),{hideStackFrames:L,codes:{ERR_SOCKET_BAD_PORT:D,ERR_INVALID_ARG_TYPE:z,ERR_INVALID_ARG_VALUE:N,ERR_OUT_OF_RANGE:H,ERR_UNKNOWN_SIGNAL:v}}=a0(),{normalizeEncoding:j}=e0(),{isAsyncFunction:n,isArrayBufferView:d}=e0().types,_={};function X(T){return T===(T|0)}function P(T){return T===T>>>0}var g=/^[0-7]+$/,c="must be a 32-bit unsigned integer or an octal string";function h(T,t,G0){if(typeof T>"u")T=G0;if(typeof T==="string"){if(F(g,T)===null)throw new N(t,T,c);T=U(T,8)}return $0(T,t),T}var x=L((T,t,G0=V,Q0=B)=>{if(typeof T!=="number")throw new z(t,"number",T);if(!G(T))throw new H(t,"an integer",T);if(TQ0)throw new H(t,`>= ${G0} && <= ${Q0}`,T)}),l=L((T,t,G0=-2147483648,Q0=2147483647)=>{if(typeof T!=="number")throw new z(t,"number",T);if(!G(T))throw new H(t,"an integer",T);if(TQ0)throw new H(t,`>= ${G0} && <= ${Q0}`,T)}),$0=L((T,t,G0=!1)=>{if(typeof T!=="number")throw new z(t,"number",T);if(!G(T))throw new H(t,"an integer",T);let Q0=G0?1:0,M0=4294967295;if(TM0)throw new H(t,`>= ${Q0} && <= ${M0}`,T)});function Z0(T,t){if(typeof T!=="string")throw new z(t,"string",T)}function F0(T,t,G0=void 0,Q0){if(typeof T!=="number")throw new z(t,"number",T);if(G0!=null&&TQ0||(G0!=null||Q0!=null)&&W(T))throw new H(t,`${G0!=null?`>= ${G0}`:""}${G0!=null&&Q0!=null?" && ":""}${Q0!=null?`<= ${Q0}`:""}`,T)}var p=L((T,t,G0)=>{if(!K(G0,T)){let Q0="must be one of: "+J(Z(G0,(M0)=>typeof M0==="string"?`'${M0}'`:M(M0)),", ");throw new N(t,T,Q0)}});function W0(T,t){if(typeof T!=="boolean")throw new z(t,"boolean",T)}function y(T,t,G0){return T==null||!w(T,t)?G0:T[t]}var i=L((T,t,G0=null)=>{let Q0=y(G0,"allowArray",!1),M0=y(G0,"allowFunction",!1);if(!y(G0,"nullable",!1)&&T===null||!Q0&&Q(T)||typeof T!=="object"&&(!M0||typeof T!=="function"))throw new z(t,"Object",T)}),U0=L((T,t)=>{if(T!=null&&typeof T!=="object"&&typeof T!=="function")throw new z(t,"a dictionary",T)}),m=L((T,t,G0=0)=>{if(!Q(T))throw new z(t,"Array",T);if(T.length{if(!d(T))throw new z(t,["Buffer","TypedArray","DataView"],T)});function E(T,t){let G0=j(t),Q0=T.length;if(G0==="hex"&&Q0%2!==0)throw new N("encoding",t,`is invalid for data of length ${Q0}`)}function a(T,t="Port",G0=!0){if(typeof T!=="number"&&typeof T!=="string"||typeof T==="string"&&f(T).length===0||+T!==+T>>>0||T>65535||T===0&&!G0)throw new D(t,T,G0);return T|0}var K0=L((T,t)=>{if(T!==void 0&&(T===null||typeof T!=="object"||!("aborted"in T)))throw new z(t,"AbortSignal",T)}),R=L((T,t)=>{if(typeof T!=="function")throw new z(t,"Function",T)}),Y=L((T,t)=>{if(typeof T!=="function"||n(T))throw new z(t,"Function",T)}),C=L((T,t)=>{if(T!==void 0)throw new z(t,"undefined",T)});function u(T,t,G0){if(!K(G0,T))throw new z(t,`('${J(G0,"|")}')`,T)}var e=/^(?:<[^>]*>)(?:\s*;\s*[^;"\s]+(?:=(")?[^;"\s]*\1)?)*$/;function r(T,t){if(typeof T>"u"||!F(e,T))throw new N(t,T,'must be an array or string of format "; rel=preload; as=style"')}function s(T){if(typeof T==="string")return r(T,"hints"),T;else if(Q(T)){let t=T.length,G0="";if(t===0)return G0;for(let Q0=0;Q0; rel=preload; as=style"')}q.exports={isInt32:X,isUint32:P,parseFileMode:h,validateArray:m,validateStringArray:V0,validateBooleanArray:w0,validateAbortSignalArray:S,validateBoolean:W0,validateBuffer:O,validateDictionary:U0,validateEncoding:E,validateFunction:R,validateInt32:l,validateInteger:x,validateNumber:F0,validateObject:i,validateOneOf:p,validatePlainFunction:Y,validatePort:a,validateSignalName:b,validateString:Z0,validateUint32:$0,validateUndefined:C,validateUnion:u,validateAbortSignal:K0,validateLinkHeaderValue:s}}),D1=g0(($,q)=>{q.exports=globalThis.process}),b2=g0(($,q)=>{var{SymbolAsyncIterator:Q,SymbolIterator:K,SymbolFor:J}=P0(),Z=J("nodejs.stream.destroyed"),G=J("nodejs.stream.errored"),W=J("nodejs.stream.readable"),B=J("nodejs.stream.writable"),V=J("nodejs.stream.disturbed"),U=J("nodejs.webstream.isClosedPromise"),w=J("nodejs.webstream.controllerErrorFunction");function F(y,i=!1){var U0;return!!(y&&typeof y.pipe==="function"&&typeof y.on==="function"&&(!i||typeof y.pause==="function"&&typeof y.resume==="function")&&(!y._writableState||((U0=y._readableState)===null||U0===void 0?void 0:U0.readable)!==!1)&&(!y._writableState||y._readableState))}function M(y){var i;return!!(y&&typeof y.write==="function"&&typeof y.on==="function"&&(!y._readableState||((i=y._writableState)===null||i===void 0?void 0:i.writable)!==!1))}function k(y){return!!(y&&typeof y.pipe==="function"&&y._readableState&&typeof y.on==="function"&&typeof y.write==="function")}function f(y){return y&&(y._readableState||y._writableState||typeof y.write==="function"&&typeof y.on==="function"||typeof y.pipe==="function"&&typeof y.on==="function")}function L(y){return!!(y&&!f(y)&&typeof y.pipeThrough==="function"&&typeof y.getReader==="function"&&typeof y.cancel==="function")}function D(y){return!!(y&&!f(y)&&typeof y.getWriter==="function"&&typeof y.abort==="function")}function z(y){return!!(y&&!f(y)&&typeof y.readable==="object"&&typeof y.writable==="object")}function N(y){return L(y)||D(y)||z(y)}function H(y,i){if(y==null)return!1;if(i===!0)return typeof y[Q]==="function";if(i===!1)return typeof y[K]==="function";return typeof y[Q]==="function"||typeof y[K]==="function"}function v(y){if(!f(y))return null;let{_writableState:i,_readableState:U0}=y,m=i||U0;return!!(y.destroyed||y[Z]||m!==null&&m!==void 0&&m.destroyed)}function j(y){if(!M(y))return null;if(y.writableEnded===!0)return!0;let i=y._writableState;if(i!==null&&i!==void 0&&i.errored)return!1;if(typeof(i===null||i===void 0?void 0:i.ended)!=="boolean")return null;return i.ended}function n(y,i){if(!M(y))return null;if(y.writableFinished===!0)return!0;let U0=y._writableState;if(U0!==null&&U0!==void 0&&U0.errored)return!1;if(typeof(U0===null||U0===void 0?void 0:U0.finished)!=="boolean")return null;return!!(U0.finished||i===!1&&U0.ended===!0&&U0.length===0)}function d(y){if(!F(y))return null;if(y.readableEnded===!0)return!0;let i=y._readableState;if(!i||i.errored)return!1;if(typeof(i===null||i===void 0?void 0:i.ended)!=="boolean")return null;return i.ended}function _(y,i){if(!F(y))return null;let U0=y._readableState;if(U0!==null&&U0!==void 0&&U0.errored)return!1;if(typeof(U0===null||U0===void 0?void 0:U0.endEmitted)!=="boolean")return null;return!!(U0.endEmitted||i===!1&&U0.ended===!0&&U0.length===0)}function X(y){if(y&&y[W]!=null)return y[W];if(typeof(y===null||y===void 0?void 0:y.readable)!=="boolean")return null;if(v(y))return!1;return F(y)&&y.readable&&!_(y)}function P(y){if(y&&y[B]!=null)return y[B];if(typeof(y===null||y===void 0?void 0:y.writable)!=="boolean")return null;if(v(y))return!1;return M(y)&&y.writable&&!j(y)}function g(y,i){if(!f(y))return null;if(v(y))return!0;if((i===null||i===void 0?void 0:i.readable)!==!1&&X(y))return!1;if((i===null||i===void 0?void 0:i.writable)!==!1&&P(y))return!1;return!0}function c(y){var i,U0;if(!f(y))return null;if(y.writableErrored)return y.writableErrored;return(i=(U0=y._writableState)===null||U0===void 0?void 0:U0.errored)!==null&&i!==void 0?i:null}function h(y){var i,U0;if(!f(y))return null;if(y.readableErrored)return y.readableErrored;return(i=(U0=y._readableState)===null||U0===void 0?void 0:U0.errored)!==null&&i!==void 0?i:null}function x(y){if(!f(y))return null;if(typeof y.closed==="boolean")return y.closed;let{_writableState:i,_readableState:U0}=y;if(typeof(i===null||i===void 0?void 0:i.closed)==="boolean"||typeof(U0===null||U0===void 0?void 0:U0.closed)==="boolean")return(i===null||i===void 0?void 0:i.closed)||(U0===null||U0===void 0?void 0:U0.closed);if(typeof y._closed==="boolean"&&l(y))return y._closed;return null}function l(y){return typeof y._closed==="boolean"&&typeof y._defaultKeepAlive==="boolean"&&typeof y._removedConnection==="boolean"&&typeof y._removedContLen==="boolean"}function $0(y){return typeof y._sent100==="boolean"&&l(y)}function Z0(y){var i;return typeof y._consuming==="boolean"&&typeof y._dumped==="boolean"&&((i=y.req)===null||i===void 0?void 0:i.upgradeOrConnect)===void 0}function F0(y){if(!f(y))return null;let{_writableState:i,_readableState:U0}=y,m=i||U0;return!m&&$0(y)||!!(m&&m.autoDestroy&&m.emitClose&&m.closed===!1)}function p(y){var i;return!!(y&&((i=y[V])!==null&&i!==void 0?i:y.readableDidRead||y.readableAborted))}function W0(y){var i,U0,m,V0,w0,S,b,O,E,a;return!!(y&&((i=(U0=(m=(V0=(w0=(S=y[G])!==null&&S!==void 0?S:y.readableErrored)!==null&&w0!==void 0?w0:y.writableErrored)!==null&&V0!==void 0?V0:(b=y._readableState)===null||b===void 0?void 0:b.errorEmitted)!==null&&m!==void 0?m:(O=y._writableState)===null||O===void 0?void 0:O.errorEmitted)!==null&&U0!==void 0?U0:(E=y._readableState)===null||E===void 0?void 0:E.errored)!==null&&i!==void 0?i:(a=y._writableState)===null||a===void 0?void 0:a.errored))}q.exports={isDestroyed:v,kIsDestroyed:Z,isDisturbed:p,kIsDisturbed:V,isErrored:W0,kIsErrored:G,isReadable:X,kIsReadable:W,kIsClosedPromise:U,kControllerErrorFunction:w,kIsWritable:B,isClosed:x,isDuplexNodeStream:k,isFinished:g,isIterable:H,isReadableNodeStream:F,isReadableStream:L,isReadableEnded:d,isReadableFinished:_,isReadableErrored:h,isNodeStream:f,isWebStream:N,isWritable:P,isWritableNodeStream:M,isWritableStream:D,isWritableEnded:j,isWritableFinished:n,isWritableErrored:c,isServerRequest:Z0,isServerResponse:$0,willEmitClose:F0,isTransformStream:z}}),s2=g0(($,q)=>{var Q=D1(),{AbortError:K,codes:J}=a0(),{ERR_INVALID_ARG_TYPE:Z,ERR_STREAM_PREMATURE_CLOSE:G}=J,{kEmptyObject:W,once:B}=e0(),{validateAbortSignal:V,validateFunction:U,validateObject:w,validateBoolean:F}=P6(),{Promise:M,PromisePrototypeThen:k,SymbolDispose:f}=P0(),{isClosed:L,isReadable:D,isReadableNodeStream:z,isReadableStream:N,isReadableFinished:H,isReadableErrored:v,isWritable:j,isWritableNodeStream:n,isWritableStream:d,isWritableFinished:_,isWritableErrored:X,isNodeStream:P,willEmitClose:g,kIsClosedPromise:c}=b2(),h;function x(p){return p.setHeader&&typeof p.abort==="function"}var l=()=>{};function $0(p,W0,y){var i,U0;if(arguments.length===2)y=W0,W0=W;else if(W0==null)W0=W;else w(W0,"options");if(U(y,"callback"),V(W0.signal,"options.signal"),y=B(y),N(p)||d(p))return Z0(p,W0,y);if(!P(p))throw new Z("stream",["ReadableStream","WritableStream","Stream"],p);let m=(i=W0.readable)!==null&&i!==void 0?i:z(p),V0=(U0=W0.writable)!==null&&U0!==void 0?U0:n(p),w0=p._writableState,S=p._readableState,b=()=>{if(!p.writable)a()},O=g(p)&&z(p)===m&&n(p)===V0,E=_(p,!1),a=()=>{if(E=!0,p.destroyed)O=!1;if(O&&(!p.readable||m))return;if(!m||K0)y.call(p)},K0=H(p,!1),R=()=>{if(K0=!0,p.destroyed)O=!1;if(O&&(!p.writable||V0))return;if(!V0||E)y.call(p)},Y=(T)=>{y.call(p,T)},C=L(p),u=()=>{C=!0;let T=X(p)||v(p);if(T&&typeof T!=="boolean")return y.call(p,T);if(m&&!K0&&z(p,!0)){if(!H(p,!1))return y.call(p,new G)}if(V0&&!E){if(!_(p,!1))return y.call(p,new G)}y.call(p)},e=()=>{C=!0;let T=X(p)||v(p);if(T&&typeof T!=="boolean")return y.call(p,T);y.call(p)},r=()=>{p.req.on("finish",a)};if(x(p)){if(p.on("complete",a),!O)p.on("abort",u);if(p.req)r();else p.on("request",r)}else if(V0&&!w0)p.on("end",b),p.on("close",b);if(!O&&typeof p.aborted==="boolean")p.on("aborted",u);if(p.on("end",R),p.on("finish",a),W0.error!==!1)p.on("error",Y);if(p.on("close",u),C)Q.nextTick(u);else if(w0!==null&&w0!==void 0&&w0.errorEmitted||S!==null&&S!==void 0&&S.errorEmitted){if(!O)Q.nextTick(e)}else if(!m&&(!O||D(p))&&(E||j(p)===!1))Q.nextTick(e);else if(!V0&&(!O||j(p))&&(K0||D(p)===!1))Q.nextTick(e);else if(S&&p.req&&p.aborted)Q.nextTick(e);let s=()=>{if(y=l,p.removeListener("aborted",u),p.removeListener("complete",a),p.removeListener("abort",u),p.removeListener("request",r),p.req)p.req.removeListener("finish",a);p.removeListener("end",b),p.removeListener("close",b),p.removeListener("finish",a),p.removeListener("end",R),p.removeListener("error",Y),p.removeListener("close",u)};if(W0.signal&&!C){let T=()=>{let t=y;s(),t.call(p,new K(void 0,{cause:W0.signal.reason}))};if(W0.signal.aborted)Q.nextTick(T);else{h=h||e0().addAbortListener;let t=h(W0.signal,T),G0=y;y=B((...Q0)=>{t[f](),G0.apply(p,Q0)})}}return s}function Z0(p,W0,y){let i=!1,U0=l;if(W0.signal)if(U0=()=>{i=!0,y.call(p,new K(void 0,{cause:W0.signal.reason}))},W0.signal.aborted)Q.nextTick(U0);else{h=h||e0().addAbortListener;let V0=h(W0.signal,U0),w0=y;y=B((...S)=>{V0[f](),w0.apply(p,S)})}let m=(...V0)=>{if(!i)Q.nextTick(()=>y.apply(p,V0))};return k(p[c].promise,m,m),l}function F0(p,W0){var y;let i=!1;if(W0===null)W0=W;if((y=W0)!==null&&y!==void 0&&y.cleanup)F(W0.cleanup,"cleanup"),i=W0.cleanup;return new M((U0,m)=>{let V0=$0(p,W0,(w0)=>{if(i)V0();if(w0)m(w0);else U0()})})}q.exports=$0,q.exports.finished=F0}),o1=g0(($,q)=>{var Q=D1(),{aggregateTwoErrors:K,codes:{ERR_MULTIPLE_CALLBACK:J},AbortError:Z}=a0(),{Symbol:G}=P0(),{kIsDestroyed:W,isDestroyed:B,isFinished:V,isServerRequest:U}=b2(),w=G("kDestroy"),F=G("kConstruct");function M(g,c,h){if(g){if(g.stack,c&&!c.errored)c.errored=g;if(h&&!h.errored)h.errored=g}}function k(g,c){let h=this._readableState,x=this._writableState,l=x||h;if(x!==null&&x!==void 0&&x.destroyed||h!==null&&h!==void 0&&h.destroyed){if(typeof c==="function")c();return this}if(M(g,x,h),x)x.destroyed=!0;if(h)h.destroyed=!0;if(!l.constructed)this.once(w,function($0){f(this,K($0,g),c)});else f(this,g,c);return this}function f(g,c,h){let x=!1;function l($0){if(x)return;x=!0;let{_readableState:Z0,_writableState:F0}=g;if(M($0,F0,Z0),F0)F0.closed=!0;if(Z0)Z0.closed=!0;if(typeof h==="function")h($0);if($0)Q.nextTick(L,g,$0);else Q.nextTick(D,g)}try{g._destroy(c||null,l)}catch($0){l($0)}}function L(g,c){z(g,c),D(g)}function D(g){let{_readableState:c,_writableState:h}=g;if(h)h.closeEmitted=!0;if(c)c.closeEmitted=!0;if(h!==null&&h!==void 0&&h.emitClose||c!==null&&c!==void 0&&c.emitClose)g.emit("close")}function z(g,c){let{_readableState:h,_writableState:x}=g;if(x!==null&&x!==void 0&&x.errorEmitted||h!==null&&h!==void 0&&h.errorEmitted)return;if(x)x.errorEmitted=!0;if(h)h.errorEmitted=!0;g.emit("error",c)}function N(){let g=this._readableState,c=this._writableState;if(g)g.constructed=!0,g.closed=!1,g.closeEmitted=!1,g.destroyed=!1,g.errored=null,g.errorEmitted=!1,g.reading=!1,g.ended=g.readable===!1,g.endEmitted=g.readable===!1;if(c)c.constructed=!0,c.destroyed=!1,c.closed=!1,c.closeEmitted=!1,c.errored=null,c.errorEmitted=!1,c.finalCalled=!1,c.prefinished=!1,c.ended=c.writable===!1,c.ending=c.writable===!1,c.finished=c.writable===!1}function H(g,c,h){let{_readableState:x,_writableState:l}=g;if(l!==null&&l!==void 0&&l.destroyed||x!==null&&x!==void 0&&x.destroyed)return this;if(x!==null&&x!==void 0&&x.autoDestroy||l!==null&&l!==void 0&&l.autoDestroy)g.destroy(c);else if(c){if(c.stack,l&&!l.errored)l.errored=c;if(x&&!x.errored)x.errored=c;if(h)Q.nextTick(z,g,c);else z(g,c)}}function v(g,c){if(typeof g._construct!=="function")return;let{_readableState:h,_writableState:x}=g;if(h)h.constructed=!1;if(x)x.constructed=!1;if(g.once(F,c),g.listenerCount(F)>1)return;Q.nextTick(j,g)}function j(g){let c=!1;function h(x){if(c){H(g,x!==null&&x!==void 0?x:new J);return}c=!0;let{_readableState:l,_writableState:$0}=g,Z0=$0||l;if(l)l.constructed=!0;if($0)$0.constructed=!0;if(Z0.destroyed)g.emit(w,x);else if(x)H(g,x,!0);else Q.nextTick(n,g)}try{g._construct((x)=>{Q.nextTick(h,x)})}catch(x){Q.nextTick(h,x)}}function n(g){g.emit(F)}function d(g){return(g===null||g===void 0?void 0:g.setHeader)&&typeof g.abort==="function"}function _(g){g.emit("close")}function X(g,c){g.emit("error",c),Q.nextTick(_,g)}function P(g,c){if(!g||B(g))return;if(!c&&!V(g))c=new Z;if(U(g))g.socket=null,g.destroy(c);else if(d(g))g.abort();else if(d(g.req))g.req.abort();else if(typeof g.destroy==="function")g.destroy(c);else if(typeof g.close==="function")g.close();else if(c)Q.nextTick(X,g,c);else Q.nextTick(_,g);if(!g.destroyed)g[W]=!0}q.exports={construct:v,destroyer:P,destroy:k,undestroy:N,errorOrDestroy:H}}),c5=g0(($,q)=>{var{ArrayIsArray:Q,ObjectSetPrototypeOf:K}=P0(),{EventEmitter:J}=(i1(),X0(p1));function Z(W){J.call(this,W)}K(Z.prototype,J.prototype),K(Z,J),Z.prototype.pipe=function(W,B){let V=this;function U(D){if(W.writable&&W.write(D)===!1&&V.pause)V.pause()}V.on("data",U);function w(){if(V.readable&&V.resume)V.resume()}if(W.on("drain",w),!W._isStdio&&(!B||B.end!==!1))V.on("end",M),V.on("close",k);let F=!1;function M(){if(F)return;F=!0,W.end()}function k(){if(F)return;if(F=!0,typeof W.destroy==="function")W.destroy()}function f(D){if(L(),J.listenerCount(this,"error")===0)this.emit("error",D)}G(V,"error",f),G(W,"error",f);function L(){V.removeListener("data",U),W.removeListener("drain",w),V.removeListener("end",M),V.removeListener("close",k),V.removeListener("error",f),W.removeListener("error",f),V.removeListener("end",L),V.removeListener("close",L),W.removeListener("close",L)}return V.on("end",L),V.on("close",L),W.on("close",L),W.emit("pipe",V),W};function G(W,B,V){if(typeof W.prependListener==="function")return W.prependListener(B,V);if(!W._events||!W._events[B])W.on(B,V);else if(Q(W._events[B]))W._events[B].unshift(V);else W._events[B]=[V,W._events[B]]}q.exports={Stream:Z,prependListener:G}}),L8=g0(($,q)=>{var{SymbolDispose:Q}=P0(),{AbortError:K,codes:J}=a0(),{isNodeStream:Z,isWebStream:G,kControllerErrorFunction:W}=b2(),B=s2(),{ERR_INVALID_ARG_TYPE:V}=J,U,w=(F,M)=>{if(typeof F!=="object"||!("aborted"in F))throw new V(M,"AbortSignal",F)};q.exports.addAbortSignal=function(F,M){if(w(F,"signal"),!Z(M)&&!G(M))throw new V("stream",["ReadableStream","WritableStream","Stream"],M);return q.exports.addAbortSignalNoValidate(F,M)},q.exports.addAbortSignalNoValidate=function(F,M){if(typeof F!=="object"||!("aborted"in F))return M;let k=Z(M)?()=>{M.destroy(new K(void 0,{cause:F.reason}))}:()=>{M[W](new K(void 0,{cause:F.reason}))};if(F.aborted)k();else{U=U||e0().addAbortListener;let f=U(F,k);B(M,f[Q])}return M}}),gV=g0(($,q)=>{var{StringPrototypeSlice:Q,SymbolIterator:K,TypedArrayPrototypeSet:J,Uint8Array:Z}=P0(),{Buffer:G}=(t0(),X0(K2)),{inspect:W}=e0();q.exports=class{constructor(){this.head=null,this.tail=null,this.length=0}push(B){let V={data:B,next:null};if(this.length>0)this.tail.next=V;else this.head=V;this.tail=V,++this.length}unshift(B){let V={data:B,next:this.head};if(this.length===0)this.tail=V;this.head=V,++this.length}shift(){if(this.length===0)return;let B=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;return--this.length,B}clear(){this.head=this.tail=null,this.length=0}join(B){if(this.length===0)return"";let V=this.head,U=""+V.data;while((V=V.next)!==null)U+=B+V.data;return U}concat(B){if(this.length===0)return G.alloc(0);let V=G.allocUnsafe(B>>>0),U=this.head,w=0;while(U)J(V,U.data,w),w+=U.data.length,U=U.next;return V}consume(B,V){let U=this.head.data;if(BF.length)V+=F,B-=F.length;else{if(B===F.length)if(V+=F,++w,U.next)this.head=U.next;else this.head=this.tail=null;else V+=Q(F,0,B),this.head=U,U.data=Q(F,B);break}++w}while((U=U.next)!==null);return this.length-=w,V}_getBuffer(B){let V=G.allocUnsafe(B),U=B,w=this.head,F=0;do{let M=w.data;if(B>M.length)J(V,M,U-B),B-=M.length;else{if(B===M.length)if(J(V,M,U-B),++F,w.next)this.head=w.next;else this.head=this.tail=null;else J(V,new Z(M.buffer,M.byteOffset,B),U-B),this.head=w,w.data=M.slice(B);break}++F}while((w=w.next)!==null);return this.length-=F,V}[Symbol.for("nodejs.util.inspect.custom")](B,V){return W(this,{...V,depth:0,customInspect:!1})}}}),H8=g0(($,q)=>{var{MathFloor:Q,NumberIsInteger:K}=P0(),{validateInteger:J}=P6(),{ERR_INVALID_ARG_VALUE:Z}=a0().codes,G=16384,W=16;function B(F,M,k){return F.highWaterMark!=null?F.highWaterMark:M?F[k]:null}function V(F){return F?W:G}function U(F,M){if(J(M,"value",0),F)W=M;else G=M}function w(F,M,k,f){let L=B(M,f,k);if(L!=null){if(!K(L)||L<0){let D=f?`options.${k}`:"options.highWaterMark";throw new Z(D,L)}return Q(L)}return V(F.objectMode)}q.exports={getHighWaterMark:w,getDefaultHighWaterMark:V,setDefaultHighWaterMark:U}}),AV=g0(($,q)=>{/*! safe-buffer. MIT License. Feross Aboukhadijeh */var Q=(t0(),X0(K2)),K=Q.Buffer;function J(G,W){for(var B in G)W[B]=G[B]}if(K.from&&K.alloc&&K.allocUnsafe&&K.allocUnsafeSlow)q.exports=Q;else J(Q,$),$.Buffer=Z;function Z(G,W,B){return K(G,W,B)}Z.prototype=Object.create(K.prototype),J(K,Z),Z.from=function(G,W,B){if(typeof G==="number")throw TypeError("Argument must not be a number");return K(G,W,B)},Z.alloc=function(G,W,B){if(typeof G!=="number")throw TypeError("Argument must be a number");var V=K(G);if(W!==void 0)if(typeof B==="string")V.fill(W,B);else V.fill(W);else V.fill(0);return V},Z.allocUnsafe=function(G){if(typeof G!=="number")throw TypeError("Argument must be a number");return K(G)},Z.allocUnsafeSlow=function(G){if(typeof G!=="number")throw TypeError("Argument must be a number");return Q.SlowBuffer(G)}}),XV=g0(($)=>{var q=AV().Buffer,Q=q.isEncoding||function(z){switch(z=""+z,z&&z.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function K(z){if(!z)return"utf8";var N;while(!0)switch(z){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return z;default:if(N)return;z=(""+z).toLowerCase(),N=!0}}function J(z){var N=K(z);if(typeof N!=="string"&&(q.isEncoding===Q||!Q(z)))throw Error("Unknown encoding: "+z);return N||z}$.StringDecoder=Z;function Z(z){this.encoding=J(z);var N;switch(this.encoding){case"utf16le":this.text=F,this.end=M,N=4;break;case"utf8":this.fillLast=V,N=4;break;case"base64":this.text=k,this.end=f,N=3;break;default:this.write=L,this.end=D;return}this.lastNeed=0,this.lastTotal=0,this.lastChar=q.allocUnsafe(N)}Z.prototype.write=function(z){if(z.length===0)return"";var N,H;if(this.lastNeed){if(N=this.fillLast(z),N===void 0)return"";H=this.lastNeed,this.lastNeed=0}else H=0;if(H>5===6)return 2;else if(z>>4===14)return 3;else if(z>>3===30)return 4;return z>>6===2?-1:-2}function W(z,N,H){var v=N.length-1;if(v=0){if(j>0)z.lastNeed=j-1;return j}if(--v=0){if(j>0)z.lastNeed=j-2;return j}if(--v=0){if(j>0)if(j===2)j=0;else z.lastNeed=j-3;return j}return 0}function B(z,N,H){if((N[0]&192)!==128)return z.lastNeed=0,"�";if(z.lastNeed>1&&N.length>1){if((N[1]&192)!==128)return z.lastNeed=1,"�";if(z.lastNeed>2&&N.length>2){if((N[2]&192)!==128)return z.lastNeed=2,"�"}}}function V(z){var N=this.lastTotal-this.lastNeed,H=B(this,z,N);if(H!==void 0)return H;if(this.lastNeed<=z.length)return z.copy(this.lastChar,N,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);z.copy(this.lastChar,N,0,z.length),this.lastNeed-=z.length}function U(z,N){var H=W(this,z,N);if(!this.lastNeed)return z.toString("utf8",N);this.lastTotal=H;var v=z.length-(H-this.lastNeed);return z.copy(this.lastChar,0,v),z.toString("utf8",N,v)}function w(z){var N=z&&z.length?this.write(z):"";if(this.lastNeed)return N+"�";return N}function F(z,N){if((z.length-N)%2===0){var H=z.toString("utf16le",N);if(H){var v=H.charCodeAt(H.length-1);if(v>=55296&&v<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=z[z.length-2],this.lastChar[1]=z[z.length-1],H.slice(0,-1)}return H}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=z[z.length-1],z.toString("utf16le",N,z.length-1)}function M(z){var N=z&&z.length?this.write(z):"";if(this.lastNeed){var H=this.lastTotal-this.lastNeed;return N+this.lastChar.toString("utf16le",0,H)}return N}function k(z,N){var H=(z.length-N)%3;if(H===0)return z.toString("base64",N);if(this.lastNeed=3-H,this.lastTotal=3,H===1)this.lastChar[0]=z[z.length-1];else this.lastChar[0]=z[z.length-2],this.lastChar[1]=z[z.length-1];return z.toString("base64",N,z.length-H)}function f(z){var N=z&&z.length?this.write(z):"";if(this.lastNeed)return N+this.lastChar.toString("base64",0,3-this.lastNeed);return N}function L(z){return z.toString(this.encoding)}function D(z){return z&&z.length?this.write(z):""}}),a9=g0(($,q)=>{var Q=D1(),{PromisePrototypeThen:K,SymbolAsyncIterator:J,SymbolIterator:Z}=P0(),{Buffer:G}=(t0(),X0(K2)),{ERR_INVALID_ARG_TYPE:W,ERR_STREAM_NULL_VALUES:B}=a0().codes;function V(U,w,F){let M;if(typeof w==="string"||w instanceof G)return new U({objectMode:!0,...F,read(){this.push(w),this.push(null)}});let k;if(w&&w[J])k=!0,M=w[J]();else if(w&&w[Z])k=!1,M=w[Z]();else throw new W("iterable",["Iterable"],w);let f=new U({objectMode:!0,highWaterMark:1,...F}),L=!1;f._read=function(){if(!L)L=!0,z()},f._destroy=function(N,H){K(D(N),()=>Q.nextTick(H,N),(v)=>Q.nextTick(H,v||N))};async function D(N){let H=N!==void 0&&N!==null,v=typeof M.throw==="function";if(H&&v){let{value:j,done:n}=await M.throw(N);if(await j,n)return}if(typeof M.return==="function"){let{value:j}=await M.return();await j}}async function z(){for(;;){try{let{value:N,done:H}=k?await M.next():M.next();if(H)f.push(null);else{let v=N&&typeof N.then==="function"?await N:N;if(v===null)throw L=!1,new B;else if(f.push(v))continue;else L=!1}}catch(N){f.destroy(N)}break}}return f}q.exports=V}),v8=g0(($,q)=>{var Q=D1(),{ArrayPrototypeIndexOf:K,NumberIsInteger:J,NumberIsNaN:Z,NumberParseInt:G,ObjectDefineProperties:W,ObjectKeys:B,ObjectSetPrototypeOf:V,Promise:U,SafeSet:w,SymbolAsyncDispose:F,SymbolAsyncIterator:M,Symbol:k}=P0();q.exports=Q0,Q0.ReadableState=G0;var{EventEmitter:f}=(i1(),X0(p1)),{Stream:L,prependListener:D}=c5(),{Buffer:z}=(t0(),X0(K2)),{addAbortSignal:N}=L8(),H=s2(),v=e0().debuglog("stream",(I)=>{v=I}),j=gV(),n=o1(),{getHighWaterMark:d,getDefaultHighWaterMark:_}=H8(),{aggregateTwoErrors:X,codes:{ERR_INVALID_ARG_TYPE:P,ERR_METHOD_NOT_IMPLEMENTED:g,ERR_OUT_OF_RANGE:c,ERR_STREAM_PUSH_AFTER_EOF:h,ERR_STREAM_UNSHIFT_AFTER_END_EVENT:x},AbortError:l}=a0(),{validateObject:$0}=P6(),Z0=k("kPaused"),{StringDecoder:F0}=XV(),p=a9();V(Q0.prototype,L.prototype),V(Q0,L);var W0=()=>{},{errorOrDestroy:y}=n,i=1,U0=2,m=4,V0=8,w0=16,S=32,b=64,O=128,E=256,a=512,K0=1024,R=2048,Y=4096,C=8192,u=16384,e=32768,r=65536,s=131072,T=262144;function t(I){return{enumerable:!1,get(){return(this.state&I)!==0},set(A){if(A)this.state|=I;else this.state&=~I}}}W(G0.prototype,{objectMode:t(i),ended:t(U0),endEmitted:t(m),reading:t(V0),constructed:t(w0),sync:t(S),needReadable:t(b),emittedReadable:t(O),readableListening:t(E),resumeScheduled:t(a),errorEmitted:t(K0),emitClose:t(R),autoDestroy:t(Y),destroyed:t(C),closed:t(u),closeEmitted:t(e),multiAwaitDrain:t(r),readingMore:t(s),dataEmitted:t(T)});function G0(I,A,J0){if(typeof J0!=="boolean")J0=A instanceof c2();if(this.state=R|Y|w0|S,I&&I.objectMode)this.state|=i;if(J0&&I&&I.readableObjectMode)this.state|=i;if(this.highWaterMark=I?d(this,I,"readableHighWaterMark",J0):_(!1),this.buffer=new j,this.length=0,this.pipes=[],this.flowing=null,this[Z0]=null,I&&I.emitClose===!1)this.state&=~R;if(I&&I.autoDestroy===!1)this.state&=~Y;if(this.errored=null,this.defaultEncoding=I&&I.defaultEncoding||"utf8",this.awaitDrainWriters=null,this.decoder=null,this.encoding=null,I&&I.encoding)this.decoder=new F0(I.encoding),this.encoding=I.encoding}function Q0(I){if(!(this instanceof Q0))return new Q0(I);let A=this instanceof c2();if(this._readableState=new G0(I,this,A),I){if(typeof I.read==="function")this._read=I.read;if(typeof I.destroy==="function")this._destroy=I.destroy;if(typeof I.construct==="function")this._construct=I.construct;if(I.signal&&!A)N(I.signal,this)}L.call(this,I),n.construct(this,()=>{if(this._readableState.needReadable)_1(this,this._readableState)})}Q0.prototype.destroy=n.destroy,Q0.prototype._undestroy=n.undestroy,Q0.prototype._destroy=function(I,A){A(I)},Q0.prototype[f.captureRejectionSymbol]=function(I){this.destroy(I)},Q0.prototype[F]=function(){let I;if(!this.destroyed)I=this.readableEnded?null:new l,this.destroy(I);return new U((A,J0)=>H(this,(B0)=>B0&&B0!==I?J0(B0):A(null)))},Q0.prototype.push=function(I,A){return M0(this,I,A,!1)},Q0.prototype.unshift=function(I,A){return M0(this,I,A,!0)};function M0(I,A,J0,B0){v("readableAddChunk",A);let z0=I._readableState,i0;if((z0.state&i)===0){if(typeof A==="string"){if(J0=J0||z0.defaultEncoding,z0.encoding!==J0)if(B0&&z0.encoding)A=z.from(A,J0).toString(z0.encoding);else A=z.from(A,J0),J0=""}else if(A instanceof z)J0="";else if(L._isUint8Array(A))A=L._uint8ArrayToBuffer(A),J0="";else if(A!=null)i0=new P("chunk",["string","Buffer","Uint8Array"],A)}if(i0)y(I,i0);else if(A===null)z0.state&=~V0,O0(I,z0);else if((z0.state&i)!==0||A&&A.length>0)if(B0)if((z0.state&m)!==0)y(I,new x);else if(z0.destroyed||z0.errored)return!1;else I0(I,z0,A,!0);else if(z0.ended)y(I,new h);else if(z0.destroyed||z0.errored)return!1;else if(z0.state&=~V0,z0.decoder&&!J0)if(A=z0.decoder.write(A),z0.objectMode||A.length!==0)I0(I,z0,A,!1);else _1(I,z0);else I0(I,z0,A,!1);else if(!B0)z0.state&=~V0,_1(I,z0);return!z0.ended&&(z0.length0){if((A.state&r)!==0)A.awaitDrainWriters.clear();else A.awaitDrainWriters=null;A.dataEmitted=!0,I.emit("data",J0)}else{if(A.length+=A.objectMode?1:J0.length,B0)A.buffer.unshift(J0);else A.buffer.push(J0);if((A.state&b)!==0)u0(I)}_1(I,A)}Q0.prototype.isPaused=function(){let I=this._readableState;return I[Z0]===!0||I.flowing===!1},Q0.prototype.setEncoding=function(I){let A=new F0(I);this._readableState.decoder=A,this._readableState.encoding=this._readableState.decoder.encoding;let J0=this._readableState.buffer,B0="";for(let z0 of J0)B0+=A.write(z0);if(J0.clear(),B0!=="")J0.push(B0);return this._readableState.length=B0.length,this};var m0=1073741824;function p0(I){if(I>m0)throw new c("size","<= 1GiB",I);else I--,I|=I>>>1,I|=I>>>2,I|=I>>>4,I|=I>>>8,I|=I>>>16,I++;return I}function q2(I,A){if(I<=0||A.length===0&&A.ended)return 0;if((A.state&i)!==0)return 1;if(Z(I)){if(A.flowing&&A.length)return A.buffer.first().length;return A.length}if(I<=A.length)return I;return A.ended?A.length:0}Q0.prototype.read=function(I){if(v("read",I),I===void 0)I=NaN;else if(!J(I))I=G(I,10);let A=this._readableState,J0=I;if(I>A.highWaterMark)A.highWaterMark=p0(I);if(I!==0)A.state&=~O;if(I===0&&A.needReadable&&((A.highWaterMark!==0?A.length>=A.highWaterMark:A.length>0)||A.ended)){if(v("read: emitReadable",A.length,A.ended),A.length===0&&A.ended)v5(this);else u0(this);return null}if(I=q2(I,A),I===0&&A.ended){if(A.length===0)v5(this);return null}let B0=(A.state&b)!==0;if(v("need readable",B0),A.length===0||A.length-I0)z0=a7(I,A);else z0=null;if(z0===null)A.needReadable=A.length<=A.highWaterMark,I=0;else if(A.length-=I,A.multiAwaitDrain)A.awaitDrainWriters.clear();else A.awaitDrainWriters=null;if(A.length===0){if(!A.ended)A.needReadable=!0;if(J0!==I&&A.ended)v5(this)}if(z0!==null&&!A.errorEmitted&&!A.closeEmitted)A.dataEmitted=!0,this.emit("data",z0);return z0};function O0(I,A){if(v("onEofChunk"),A.ended)return;if(A.decoder){let J0=A.decoder.end();if(J0&&J0.length)A.buffer.push(J0),A.length+=A.objectMode?1:J0.length}if(A.ended=!0,A.sync)u0(I);else A.needReadable=!1,A.emittedReadable=!0,E1(I)}function u0(I){let A=I._readableState;if(v("emitReadable",A.needReadable,A.emittedReadable),A.needReadable=!1,!A.emittedReadable)v("emitReadable",A.flowing),A.emittedReadable=!0,Q.nextTick(E1,I)}function E1(I){let A=I._readableState;if(v("emitReadable_",A.destroyed,A.length,A.ended),!A.destroyed&&!A.errored&&(A.length||A.ended))I.emit("readable"),A.emittedReadable=!1;A.needReadable=!A.flowing&&!A.ended&&A.length<=A.highWaterMark,i7(I)}function _1(I,A){if(!A.readingMore&&A.constructed)A.readingMore=!0,Q.nextTick(R2,I,A)}function R2(I,A){while(!A.reading&&!A.ended&&(A.length1&&B0.pipes.includes(I))v("false write response, pause",B0.awaitDrainWriters.size),B0.awaitDrainWriters.add(I);J0.pause()}if(!z1)z1=wJ(J0,I),I.on("drain",z1)}J0.on("data",t7);function t7(F1){v("ondata");let u2=I.write(F1);if(v("dest.write",u2),u2===!1)s7()}function R5(F1){if(v("onerror",F1),A6(),I.removeListener("error",R5),I.listenerCount("error")===0){let u2=I._writableState||I._readableState;if(u2&&!u2.errorEmitted)y(I,F1);else I.emit("error",F1)}}D(I,"error",R5);function I5(){I.removeListener("finish",C5),A6()}I.once("close",I5);function C5(){v("onfinish"),I.removeListener("close",I5),A6()}I.once("finish",C5);function A6(){v("unpipe"),J0.unpipe(I)}if(I.emit("pipe",J0),I.writableNeedDrain===!0)s7();else if(!B0.flowing)v("pipe resume"),J0.resume();return I};function wJ(I,A){return function(){let J0=I._readableState;if(J0.awaitDrainWriters===A)v("pipeOnDrain",1),J0.awaitDrainWriters=null;else if(J0.multiAwaitDrain)v("pipeOnDrain",J0.awaitDrainWriters.size),J0.awaitDrainWriters.delete(A);if((!J0.awaitDrainWriters||J0.awaitDrainWriters.size===0)&&I.listenerCount("data"))I.resume()}}Q0.prototype.unpipe=function(I){let A=this._readableState,J0={hasUnpiped:!1};if(A.pipes.length===0)return this;if(!I){let z0=A.pipes;A.pipes=[],this.pause();for(let i0=0;i00,B0.flowing!==!1)this.resume()}else if(I==="readable"){if(!B0.endEmitted&&!B0.readableListening){if(B0.readableListening=B0.needReadable=!0,B0.flowing=!1,B0.emittedReadable=!1,v("on readable",B0.length,B0.reading),B0.length)u0(this);else if(!B0.reading)Q.nextTick(NJ,this)}}return J0},Q0.prototype.addListener=Q0.prototype.on,Q0.prototype.removeListener=function(I,A){let J0=L.prototype.removeListener.call(this,I,A);if(I==="readable")Q.nextTick(p7,this);return J0},Q0.prototype.off=Q0.prototype.removeListener,Q0.prototype.removeAllListeners=function(I){let A=L.prototype.removeAllListeners.apply(this,arguments);if(I==="readable"||I===void 0)Q.nextTick(p7,this);return A};function p7(I){let A=I._readableState;if(A.readableListening=I.listenerCount("readable")>0,A.resumeScheduled&&A[Z0]===!1)A.flowing=!0;else if(I.listenerCount("data")>0)I.resume();else if(!A.readableListening)A.flowing=null}function NJ(I){v("readable nexttick read 0"),I.read(0)}Q0.prototype.resume=function(){let I=this._readableState;if(!I.flowing)v("resume"),I.flowing=!I.readableListening,YJ(this,I);return I[Z0]=!1,this};function YJ(I,A){if(!A.resumeScheduled)A.resumeScheduled=!0,Q.nextTick(kJ,I,A)}function kJ(I,A){if(v("resume",A.reading),!A.reading)I.read(0);if(A.resumeScheduled=!1,I.emit("resume"),i7(I),A.flowing&&!A.reading)I.read(0)}Q0.prototype.pause=function(){if(v("call pause flowing=%j",this._readableState.flowing),this._readableState.flowing!==!1)v("pause"),this._readableState.flowing=!1,this.emit("pause");return this._readableState[Z0]=!0,this};function i7(I){let A=I._readableState;v("flow",A.flowing);while(A.flowing&&I.read()!==null);}Q0.prototype.wrap=function(I){let A=!1;I.on("data",(B0)=>{if(!this.push(B0)&&I.pause)A=!0,I.pause()}),I.on("end",()=>{this.push(null)}),I.on("error",(B0)=>{y(this,B0)}),I.on("close",()=>{this.destroy()}),I.on("destroy",()=>{this.destroy()}),this._read=()=>{if(A&&I.resume)A=!1,I.resume()};let J0=B(I);for(let B0=1;B0{z0=z2?X(z0,z2):null,J0(),J0=W0});try{while(!0){let z2=I.destroyed?null:I.read();if(z2!==null)yield z2;else if(z0)throw z0;else if(z0===null)return;else await new U(B0)}}catch(z2){throw z0=X(z0,z2),z0}finally{if((z0||(A===null||A===void 0?void 0:A.destroyOnReturn)!==!1)&&(z0===void 0||I._readableState.autoDestroy))n.destroyer(I,null);else I.off("readable",B0),i0()}}W(Q0.prototype,{readable:{__proto__:null,get(){let I=this._readableState;return!!I&&I.readable!==!1&&!I.destroyed&&!I.errorEmitted&&!I.endEmitted},set(I){if(this._readableState)this._readableState.readable=!!I}},readableDidRead:{__proto__:null,enumerable:!1,get:function(){return this._readableState.dataEmitted}},readableAborted:{__proto__:null,enumerable:!1,get:function(){return!!(this._readableState.readable!==!1&&(this._readableState.destroyed||this._readableState.errored)&&!this._readableState.endEmitted)}},readableHighWaterMark:{__proto__:null,enumerable:!1,get:function(){return this._readableState.highWaterMark}},readableBuffer:{__proto__:null,enumerable:!1,get:function(){return this._readableState&&this._readableState.buffer}},readableFlowing:{__proto__:null,enumerable:!1,get:function(){return this._readableState.flowing},set:function(I){if(this._readableState)this._readableState.flowing=I}},readableLength:{__proto__:null,enumerable:!1,get(){return this._readableState.length}},readableObjectMode:{__proto__:null,enumerable:!1,get(){return this._readableState?this._readableState.objectMode:!1}},readableEncoding:{__proto__:null,enumerable:!1,get(){return this._readableState?this._readableState.encoding:null}},errored:{__proto__:null,enumerable:!1,get(){return this._readableState?this._readableState.errored:null}},closed:{__proto__:null,get(){return this._readableState?this._readableState.closed:!1}},destroyed:{__proto__:null,enumerable:!1,get(){return this._readableState?this._readableState.destroyed:!1},set(I){if(!this._readableState)return;this._readableState.destroyed=I}},readableEnded:{__proto__:null,enumerable:!1,get(){return this._readableState?this._readableState.endEmitted:!1}}}),W(G0.prototype,{pipesCount:{__proto__:null,get(){return this.pipes.length}},paused:{__proto__:null,get(){return this[Z0]!==!1},set(I){this[Z0]=!!I}}}),Q0._fromList=a7;function a7(I,A){if(A.length===0)return null;let J0;if(A.objectMode)J0=A.buffer.shift();else if(!I||I>=A.length){if(A.decoder)J0=A.buffer.join("");else if(A.buffer.length===1)J0=A.buffer.first();else J0=A.buffer.concat(A.length);A.buffer.clear()}else J0=A.buffer.consume(I,A.decoder);return J0}function v5(I){let A=I._readableState;if(v("endReadable",A.endEmitted),!A.endEmitted)A.ended=!0,Q.nextTick(LJ,A,I)}function LJ(I,A){if(v("endReadableNT",I.endEmitted,I.length),!I.errored&&!I.closeEmitted&&!I.endEmitted&&I.length===0){if(I.endEmitted=!0,A.emit("end"),A.writable&&A.allowHalfOpen===!1)Q.nextTick(HJ,A);else if(I.autoDestroy){let J0=A._writableState;if(!J0||J0.autoDestroy&&(J0.finished||J0.writable===!1))A.destroy()}}}function HJ(I){if(I.writable&&!I.writableEnded&&!I.destroyed)I.end()}Q0.from=function(I,A){return p(Q0,I,A)};var f5;function l7(){if(f5===void 0)f5={};return f5}Q0.fromWeb=function(I,A){return l7().newStreamReadableFromReadableStream(I,A)},Q0.toWeb=function(I,A){return l7().newReadableStreamFromStreamReadable(I,A)},Q0.wrap=function(I,A){var J0,B0;return new Q0({objectMode:(J0=(B0=I.readableObjectMode)!==null&&B0!==void 0?B0:I.objectMode)!==null&&J0!==void 0?J0:!0,...A,destroy(z0,i0){n.destroyer(I,z0),i0(z0)}}).wrap(I)}}),b5=g0(($,q)=>{var Q=D1(),{ArrayPrototypeSlice:K,Error:J,FunctionPrototypeSymbolHasInstance:Z,ObjectDefineProperty:G,ObjectDefineProperties:W,ObjectSetPrototypeOf:B,StringPrototypeToLowerCase:V,Symbol:U,SymbolHasInstance:w}=P0();q.exports=$0,$0.WritableState=x;var{EventEmitter:F}=(i1(),X0(p1)),M=c5().Stream,{Buffer:k}=(t0(),X0(K2)),f=o1(),{addAbortSignal:L}=L8(),{getHighWaterMark:D,getDefaultHighWaterMark:z}=H8(),{ERR_INVALID_ARG_TYPE:N,ERR_METHOD_NOT_IMPLEMENTED:H,ERR_MULTIPLE_CALLBACK:v,ERR_STREAM_CANNOT_PIPE:j,ERR_STREAM_DESTROYED:n,ERR_STREAM_ALREADY_FINISHED:d,ERR_STREAM_NULL_VALUES:_,ERR_STREAM_WRITE_AFTER_END:X,ERR_UNKNOWN_ENCODING:P}=a0().codes,{errorOrDestroy:g}=f;B($0.prototype,M.prototype),B($0,M);function c(){}var h=U("kOnFinished");function x(Y,C,u){if(typeof u!=="boolean")u=C instanceof c2();if(this.objectMode=!!(Y&&Y.objectMode),u)this.objectMode=this.objectMode||!!(Y&&Y.writableObjectMode);this.highWaterMark=Y?D(this,Y,"writableHighWaterMark",u):z(!1),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;let e=!!(Y&&Y.decodeStrings===!1);this.decodeStrings=!e,this.defaultEncoding=Y&&Y.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=y.bind(void 0,C),this.writecb=null,this.writelen=0,this.afterWriteTickInfo=null,l(this),this.pendingcb=0,this.constructed=!0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=!Y||Y.emitClose!==!1,this.autoDestroy=!Y||Y.autoDestroy!==!1,this.errored=null,this.closed=!1,this.closeEmitted=!1,this[h]=[]}function l(Y){Y.buffered=[],Y.bufferedIndex=0,Y.allBuffers=!0,Y.allNoop=!0}x.prototype.getBuffer=function(){return K(this.buffered,this.bufferedIndex)},G(x.prototype,"bufferedRequestCount",{__proto__:null,get(){return this.buffered.length-this.bufferedIndex}});function $0(Y){let C=this instanceof c2();if(!C&&!Z($0,this))return new $0(Y);if(this._writableState=new x(Y,this,C),Y){if(typeof Y.write==="function")this._write=Y.write;if(typeof Y.writev==="function")this._writev=Y.writev;if(typeof Y.destroy==="function")this._destroy=Y.destroy;if(typeof Y.final==="function")this._final=Y.final;if(typeof Y.construct==="function")this._construct=Y.construct;if(Y.signal)L(Y.signal,this)}M.call(this,Y),f.construct(this,()=>{let u=this._writableState;if(!u.writing)V0(this,u);O(this,u)})}G($0,w,{__proto__:null,value:function(Y){if(Z(this,Y))return!0;if(this!==$0)return!1;return Y&&Y._writableState instanceof x}}),$0.prototype.pipe=function(){g(this,new j)};function Z0(Y,C,u,e){let r=Y._writableState;if(typeof u==="function")e=u,u=r.defaultEncoding;else{if(!u)u=r.defaultEncoding;else if(u!=="buffer"&&!k.isEncoding(u))throw new P(u);if(typeof e!=="function")e=c}if(C===null)throw new _;else if(!r.objectMode)if(typeof C==="string"){if(r.decodeStrings!==!1)C=k.from(C,u),u="buffer"}else if(C instanceof k)u="buffer";else if(M._isUint8Array(C))C=M._uint8ArrayToBuffer(C),u="buffer";else throw new N("chunk",["string","Buffer","Uint8Array"],C);let s;if(r.ending)s=new X;else if(r.destroyed)s=new n("write");if(s)return Q.nextTick(e,s),g(Y,s,!0),s;return r.pendingcb++,F0(Y,r,C,u,e)}$0.prototype.write=function(Y,C,u){return Z0(this,Y,C,u)===!0},$0.prototype.cork=function(){this._writableState.corked++},$0.prototype.uncork=function(){let Y=this._writableState;if(Y.corked){if(Y.corked--,!Y.writing)V0(this,Y)}},$0.prototype.setDefaultEncoding=function(Y){if(typeof Y==="string")Y=V(Y);if(!k.isEncoding(Y))throw new P(Y);return this._writableState.defaultEncoding=Y,this};function F0(Y,C,u,e,r){let s=C.objectMode?1:u.length;C.length+=s;let T=C.lengthu.bufferedIndex)V0(Y,u);if(e)if(u.afterWriteTickInfo!==null&&u.afterWriteTickInfo.cb===r)u.afterWriteTickInfo.count++;else u.afterWriteTickInfo={count:1,cb:r,stream:Y,state:u},Q.nextTick(i,u.afterWriteTickInfo);else U0(Y,u,1,r)}}function i({stream:Y,state:C,count:u,cb:e}){return C.afterWriteTickInfo=null,U0(Y,C,u,e)}function U0(Y,C,u,e){if(!C.ending&&!Y.destroyed&&C.length===0&&C.needDrain)C.needDrain=!1,Y.emit("drain");while(u-- >0)C.pendingcb--,e();if(C.destroyed)m(C);O(Y,C)}function m(Y){if(Y.writing)return;for(let r=Y.bufferedIndex;r1&&Y._writev){C.pendingcb-=s-1;let t=C.allNoop?c:(Q0)=>{for(let M0=T;M0256)u.splice(0,T),C.bufferedIndex=0;else C.bufferedIndex=T}C.bufferProcessing=!1}$0.prototype._write=function(Y,C,u){if(this._writev)this._writev([{chunk:Y,encoding:C}],u);else throw new H("_write()")},$0.prototype._writev=null,$0.prototype.end=function(Y,C,u){let e=this._writableState;if(typeof Y==="function")u=Y,Y=null,C=null;else if(typeof C==="function")u=C,C=null;let r;if(Y!==null&&Y!==void 0){let s=Z0(this,Y,C);if(s instanceof J)r=s}if(e.corked)e.corked=1,this.uncork();if(r);else if(!e.errored&&!e.ending)e.ending=!0,O(this,e,!0),e.ended=!0;else if(e.finished)r=new d("end");else if(e.destroyed)r=new n("end");if(typeof u==="function")if(r||e.finished)Q.nextTick(u,r);else e[h].push(u);return this};function w0(Y){return Y.ending&&!Y.destroyed&&Y.constructed&&Y.length===0&&!Y.errored&&Y.buffered.length===0&&!Y.finished&&!Y.writing&&!Y.errorEmitted&&!Y.closeEmitted}function S(Y,C){let u=!1;function e(r){if(u){g(Y,r!==null&&r!==void 0?r:v());return}if(u=!0,C.pendingcb--,r){let s=C[h].splice(0);for(let T=0;T{if(w0(r))E(e,r);else r.pendingcb--},Y,C);else if(w0(C))C.pendingcb++,E(Y,C)}}}function E(Y,C){C.pendingcb--,C.finished=!0;let u=C[h].splice(0);for(let e=0;e{var Q=D1(),K=(t0(),X0(K2)),{isReadable:J,isWritable:Z,isIterable:G,isNodeStream:W,isReadableNodeStream:B,isWritableNodeStream:V,isDuplexNodeStream:U,isReadableStream:w,isWritableStream:F}=b2(),M=s2(),{AbortError:k,codes:{ERR_INVALID_ARG_TYPE:f,ERR_INVALID_RETURN_VALUE:L}}=a0(),{destroyer:D}=o1(),z=c2(),N=v8(),H=b5(),{createDeferredPromise:v}=e0(),j=a9(),n=globalThis.Blob||K.Blob,d=typeof n<"u"?function(h){return h instanceof n}:function(h){return!1},_=globalThis.AbortController||O6().AbortController,{FunctionPrototypeCall:X}=P0();class P extends z{constructor(h){super(h);if((h===null||h===void 0?void 0:h.readable)===!1)this._readableState.readable=!1,this._readableState.ended=!0,this._readableState.endEmitted=!0;if((h===null||h===void 0?void 0:h.writable)===!1)this._writableState.writable=!1,this._writableState.ending=!0,this._writableState.ended=!0,this._writableState.finished=!0}}q.exports=function h(x,l){if(U(x))return x;if(B(x))return c({readable:x});if(V(x))return c({writable:x});if(W(x))return c({writable:!1,readable:!1});if(w(x))return c({readable:N.fromWeb(x)});if(F(x))return c({writable:H.fromWeb(x)});if(typeof x==="function"){let{value:Z0,write:F0,final:p,destroy:W0}=g(x);if(G(Z0))return j(P,Z0,{objectMode:!0,write:F0,final:p,destroy:W0});let y=Z0===null||Z0===void 0?void 0:Z0.then;if(typeof y==="function"){let i,U0=X(y,Z0,(m)=>{if(m!=null)throw new L("nully","body",m)},(m)=>{D(i,m)});return i=new P({objectMode:!0,readable:!1,write:F0,final(m){p(async()=>{try{await U0,Q.nextTick(m,null)}catch(V0){Q.nextTick(m,V0)}})},destroy:W0})}throw new L("Iterable, AsyncIterable or AsyncFunction",l,Z0)}if(d(x))return h(x.arrayBuffer());if(G(x))return j(P,x,{objectMode:!0,writable:!1});if(w(x===null||x===void 0?void 0:x.readable)&&F(x===null||x===void 0?void 0:x.writable))return P.fromWeb(x);if(typeof(x===null||x===void 0?void 0:x.writable)==="object"||typeof(x===null||x===void 0?void 0:x.readable)==="object"){let Z0=x!==null&&x!==void 0&&x.readable?B(x===null||x===void 0?void 0:x.readable)?x===null||x===void 0?void 0:x.readable:h(x.readable):void 0,F0=x!==null&&x!==void 0&&x.writable?V(x===null||x===void 0?void 0:x.writable)?x===null||x===void 0?void 0:x.writable:h(x.writable):void 0;return c({readable:Z0,writable:F0})}let $0=x===null||x===void 0?void 0:x.then;if(typeof $0==="function"){let Z0;return X($0,x,(F0)=>{if(F0!=null)Z0.push(F0);Z0.push(null)},(F0)=>{D(Z0,F0)}),Z0=new P({objectMode:!0,writable:!1,read(){}})}throw new f(l,["Blob","ReadableStream","WritableStream","Stream","Iterable","AsyncIterable","Function","{ readable, writable } pair","Promise"],x)};function g(h){let{promise:x,resolve:l}=v(),$0=new _,Z0=$0.signal;return{value:h(async function*(){while(!0){let F0=x;x=null;let{chunk:p,done:W0,cb:y}=await F0;if(Q.nextTick(y),W0)return;if(Z0.aborted)throw new k(void 0,{cause:Z0.reason});({promise:x,resolve:l}=v()),yield p}}(),{signal:Z0}),write(F0,p,W0){let y=l;l=null,y({chunk:F0,done:!1,cb:W0})},final(F0){let p=l;l=null,p({done:!0,cb:F0})},destroy(F0,p){$0.abort(),p(F0)}}}function c(h){let x=h.readable&&typeof h.readable.read!=="function"?N.wrap(h.readable):h.readable,l=h.writable,$0=!!J(x),Z0=!!Z(l),F0,p,W0,y,i;function U0(m){let V0=y;if(y=null,V0)V0(m);else if(m)i.destroy(m)}if(i=new P({readableObjectMode:!!(x!==null&&x!==void 0&&x.readableObjectMode),writableObjectMode:!!(l!==null&&l!==void 0&&l.writableObjectMode),readable:$0,writable:Z0}),Z0)M(l,(m)=>{if(Z0=!1,m)D(x,m);U0(m)}),i._write=function(m,V0,w0){if(l.write(m,V0))w0();else F0=w0},i._final=function(m){l.end(),p=m},l.on("drain",function(){if(F0){let m=F0;F0=null,m()}}),l.on("finish",function(){if(p){let m=p;p=null,m()}});if($0)M(x,(m)=>{if($0=!1,m)D(x,m);U0(m)}),x.on("readable",function(){if(W0){let m=W0;W0=null,m()}}),x.on("end",function(){i.push(null)}),i._read=function(){while(!0){let m=x.read();if(m===null){W0=i._read;return}if(!i.push(m))return}};return i._destroy=function(m,V0){if(!m&&y!==null)m=new k;if(W0=null,F0=null,p=null,y===null)V0(m);else y=V0,D(l,m),D(x,m)},i}}),c2=g0(($,q)=>{var{ObjectDefineProperties:Q,ObjectGetOwnPropertyDescriptor:K,ObjectKeys:J,ObjectSetPrototypeOf:Z}=P0();q.exports=B;var G=v8(),W=b5();Z(B.prototype,G.prototype),Z(B,G);{let F=J(W.prototype);for(let M=0;M{var{ObjectSetPrototypeOf:Q,Symbol:K}=P0();q.exports=B;var{ERR_METHOD_NOT_IMPLEMENTED:J}=a0().codes,Z=c2(),{getHighWaterMark:G}=H8();Q(B.prototype,Z.prototype),Q(B,Z);var W=K("kCallback");function B(w){if(!(this instanceof B))return new B(w);let F=w?G(this,w,"readableHighWaterMark",!0):null;if(F===0)w={...w,highWaterMark:null,readableHighWaterMark:F,writableHighWaterMark:w.writableHighWaterMark||0};if(Z.call(this,w),this._readableState.sync=!1,this[W]=null,w){if(typeof w.transform==="function")this._transform=w.transform;if(typeof w.flush==="function")this._flush=w.flush}this.on("prefinish",U)}function V(w){if(typeof this._flush==="function"&&!this.destroyed)this._flush((F,M)=>{if(F){if(w)w(F);else this.destroy(F);return}if(M!=null)this.push(M);if(this.push(null),w)w()});else if(this.push(null),w)w()}function U(){if(this._final!==V)V.call(this)}B.prototype._final=V,B.prototype._transform=function(w,F,M){throw new J("_transform()")},B.prototype._write=function(w,F,M){let k=this._readableState,f=this._writableState,L=k.length;this._transform(w,F,(D,z)=>{if(D){M(D);return}if(z!=null)this.push(z);if(f.ended||L===k.length||k.length{var{ObjectSetPrototypeOf:Q}=P0();q.exports=J;var K=l9();Q(J.prototype,K.prototype),Q(J,K);function J(Z){if(!(this instanceof J))return new J(Z);K.call(this,Z)}J.prototype._transform=function(Z,G,W){W(null,Z)}}),n5=g0(($,q)=>{var Q=D1(),{ArrayIsArray:K,Promise:J,SymbolAsyncIterator:Z,SymbolDispose:G}=P0(),W=s2(),{once:B}=e0(),V=o1(),U=c2(),{aggregateTwoErrors:w,codes:{ERR_INVALID_ARG_TYPE:F,ERR_INVALID_RETURN_VALUE:M,ERR_MISSING_ARGS:k,ERR_STREAM_DESTROYED:f,ERR_STREAM_PREMATURE_CLOSE:L},AbortError:D}=a0(),{validateFunction:z,validateAbortSignal:N}=P6(),{isIterable:H,isReadable:v,isReadableNodeStream:j,isNodeStream:n,isTransformStream:d,isWebStream:_,isReadableStream:X,isReadableFinished:P}=b2(),g=globalThis.AbortController||O6().AbortController,c,h,x;function l(m,V0,w0){let S=!1;m.on("close",()=>{S=!0});let b=W(m,{readable:V0,writable:w0},(O)=>{S=!O});return{destroy:(O)=>{if(S)return;S=!0,V.destroyer(m,O||new f("pipe"))},cleanup:b}}function $0(m){return z(m[m.length-1],"streams[stream.length - 1]"),m.pop()}function Z0(m){if(H(m))return m;else if(j(m))return F0(m);throw new F("val",["Readable","Iterable","AsyncIterable"],m)}async function*F0(m){if(!h)h=v8();yield*h.prototype[Z].call(m)}async function p(m,V0,w0,{end:S}){let b,O=null,E=(R)=>{if(R)b=R;if(O){let Y=O;O=null,Y()}},a=()=>new J((R,Y)=>{if(b)Y(b);else O=()=>{if(b)Y(b);else R()}});V0.on("drain",E);let K0=W(V0,{readable:!1},E);try{if(V0.writableNeedDrain)await a();for await(let R of m)if(!V0.write(R))await a();if(S)V0.end(),await a();w0()}catch(R){w0(b!==R?w(b,R):R)}finally{K0(),V0.off("drain",E)}}async function W0(m,V0,w0,{end:S}){if(d(V0))V0=V0.writable;let b=V0.getWriter();try{for await(let O of m)await b.ready,b.write(O).catch(()=>{});if(await b.ready,S)await b.close();w0()}catch(O){try{await b.abort(O),w0(O)}catch(E){w0(E)}}}function y(...m){return i(m,B($0(m)))}function i(m,V0,w0){if(m.length===1&&K(m[0]))m=m[0];if(m.length<2)throw new k("streams");let S=new g,b=S.signal,O=w0===null||w0===void 0?void 0:w0.signal,E=[];N(O,"options.signal");function a(){r(new D)}x=x||e0().addAbortListener;let K0;if(O)K0=x(O,a);let R,Y,C=[],u=0;function e(Q0){r(Q0,--u===0)}function r(Q0,M0){var I0;if(Q0&&(!R||R.code==="ERR_STREAM_PREMATURE_CLOSE"))R=Q0;if(!R&&!M0)return;while(C.length)C.shift()(R);if((I0=K0)===null||I0===void 0||I0[G](),S.abort(),M0){if(!R)E.forEach((m0)=>m0());Q.nextTick(V0,R,Y)}}let s;for(let Q0=0;Q00,p0=I0||(w0===null||w0===void 0?void 0:w0.end)!==!1,q2=Q0===m.length-1;if(n(M0)){let O0=function(u0){if(u0&&u0.name!=="AbortError"&&u0.code!=="ERR_STREAM_PREMATURE_CLOSE")e(u0)};var T=O0;if(p0){let{destroy:u0,cleanup:E1}=l(M0,I0,m0);if(C.push(u0),v(M0)&&q2)E.push(E1)}if(M0.on("error",O0),v(M0)&&q2)E.push(()=>{M0.removeListener("error",O0)})}if(Q0===0)if(typeof M0==="function"){if(s=M0({signal:b}),!H(s))throw new M("Iterable, AsyncIterable or Stream","source",s)}else if(H(M0)||j(M0)||d(M0))s=M0;else s=U.from(M0);else if(typeof M0==="function"){if(d(s)){var t;s=Z0((t=s)===null||t===void 0?void 0:t.readable)}else s=Z0(s);if(s=M0(s,{signal:b}),I0){if(!H(s,!0))throw new M("AsyncIterable",`transform[${Q0-1}]`,s)}else{var G0;if(!c)c=r9();let O0=new c({objectMode:!0}),u0=(G0=s)===null||G0===void 0?void 0:G0.then;if(typeof u0==="function")u++,u0.call(s,(R2)=>{if(Y=R2,R2!=null)O0.write(R2);if(p0)O0.end();Q.nextTick(e)},(R2)=>{O0.destroy(R2),Q.nextTick(e,R2)});else if(H(s,!0))u++,p(s,O0,e,{end:p0});else if(X(s)||d(s)){let R2=s.readable||s;u++,p(R2,O0,e,{end:p0})}else throw new M("AsyncIterable or Promise","destination",s);s=O0;let{destroy:E1,cleanup:_1}=l(s,!1,!0);if(C.push(E1),q2)E.push(_1)}}else if(n(M0)){if(j(s)){u+=2;let O0=U0(s,M0,e,{end:p0});if(v(M0)&&q2)E.push(O0)}else if(d(s)||X(s)){let O0=s.readable||s;u++,p(O0,M0,e,{end:p0})}else if(H(s))u++,p(s,M0,e,{end:p0});else throw new F("val",["Readable","Iterable","AsyncIterable","ReadableStream","TransformStream"],s);s=M0}else if(_(M0)){if(j(s))u++,W0(Z0(s),M0,e,{end:p0});else if(X(s)||H(s))u++,W0(s,M0,e,{end:p0});else if(d(s))u++,W0(s.readable,M0,e,{end:p0});else throw new F("val",["Readable","Iterable","AsyncIterable","ReadableStream","TransformStream"],s);s=M0}else s=U.from(M0)}if(b!==null&&b!==void 0&&b.aborted||O!==null&&O!==void 0&&O.aborted)Q.nextTick(a);return s}function U0(m,V0,w0,{end:S}){let b=!1;if(V0.on("close",()=>{if(!b)w0(new L)}),m.pipe(V0,{end:!1}),S){let E=function(){b=!0,V0.end()};var O=E;if(P(m))Q.nextTick(E);else m.once("end",E)}else w0();return W(m,{readable:!0,writable:!1},(E)=>{let a=m._readableState;if(E&&E.code==="ERR_STREAM_PREMATURE_CLOSE"&&a&&a.ended&&!a.errored&&!a.errorEmitted)m.once("end",w0).once("error",w0);else w0(E)}),W(V0,{readable:!1,writable:!0},w0)}q.exports={pipelineImpl:i,pipeline:y}}),s9=g0(($,q)=>{var{pipeline:Q}=n5(),K=c2(),{destroyer:J}=o1(),{isNodeStream:Z,isReadable:G,isWritable:W,isWebStream:B,isTransformStream:V,isWritableStream:U,isReadableStream:w}=b2(),{AbortError:F,codes:{ERR_INVALID_ARG_VALUE:M,ERR_MISSING_ARGS:k}}=a0(),f=s2();q.exports=function(...L){if(L.length===0)throw new k("streams");if(L.length===1)return K.from(L[0]);let D=[...L];if(typeof L[0]==="function")L[0]=K.from(L[0]);if(typeof L[L.length-1]==="function"){let g=L.length-1;L[g]=K.from(L[g])}for(let g=0;g0&&!(W(L[g])||U(L[g])||V(L[g])))throw new M(`streams[${g}]`,D[g],"must be writable")}let z,N,H,v,j;function n(g){let c=v;if(v=null,c)c(g);else if(g)j.destroy(g);else if(!P&&!X)j.destroy()}let d=L[0],_=Q(L,n),X=!!(W(d)||U(d)||V(d)),P=!!(G(_)||w(_)||V(_));if(j=new K({writableObjectMode:!!(d!==null&&d!==void 0&&d.writableObjectMode),readableObjectMode:!!(_!==null&&_!==void 0&&_.readableObjectMode),writable:X,readable:P}),X){if(Z(d))j._write=function(c,h,x){if(d.write(c,h))x();else z=x},j._final=function(c){d.end(),N=c},d.on("drain",function(){if(z){let c=z;z=null,c()}});else if(B(d)){let c=(V(d)?d.writable:d).getWriter();j._write=async function(h,x,l){try{await c.ready,c.write(h).catch(()=>{}),l()}catch($0){l($0)}},j._final=async function(h){try{await c.ready,c.close().catch(()=>{}),N=h}catch(x){h(x)}}}let g=V(_)?_.readable:_;f(g,()=>{if(N){let c=N;N=null,c()}})}if(P){if(Z(_))_.on("readable",function(){if(H){let g=H;H=null,g()}}),_.on("end",function(){j.push(null)}),j._read=function(){while(!0){let g=_.read();if(g===null){H=j._read;return}if(!j.push(g))return}};else if(B(_)){let g=(V(_)?_.readable:_).getReader();j._read=async function(){while(!0)try{let{value:c,done:h}=await g.read();if(!j.push(c))return;if(h){j.push(null);return}}catch{return}}}}return j._destroy=function(g,c){if(!g&&v!==null)g=new F;if(H=null,z=null,N=null,v===null)c(g);else if(v=c,Z(_))J(_,g)},j}}),hV=g0(($,q)=>{var Q=globalThis.AbortController||O6().AbortController,{codes:{ERR_INVALID_ARG_VALUE:K,ERR_INVALID_ARG_TYPE:J,ERR_MISSING_ARGS:Z,ERR_OUT_OF_RANGE:G},AbortError:W}=a0(),{validateAbortSignal:B,validateInteger:V,validateObject:U}=P6(),w=P0().Symbol("kWeak"),F=P0().Symbol("kResistStopPropagation"),{finished:M}=s2(),k=s9(),{addAbortSignalNoValidate:f}=L8(),{isWritable:L,isNodeStream:D}=b2(),{deprecate:z}=e0(),{ArrayPrototypePush:N,Boolean:H,MathFloor:v,Number:j,NumberIsNaN:n,Promise:d,PromiseReject:_,PromiseResolve:X,PromisePrototypeThen:P,Symbol:g}=P0(),c=g("kEmpty"),h=g("kEof");function x(O,E){if(E!=null)U(E,"options");if((E===null||E===void 0?void 0:E.signal)!=null)B(E.signal,"options.signal");if(D(O)&&!L(O))throw new K("stream",O,"must be writable");let a=k(this,O);if(E!==null&&E!==void 0&&E.signal)f(E.signal,a);return a}function l(O,E){if(typeof O!=="function")throw new J("fn",["Function","AsyncFunction"],O);if(E!=null)U(E,"options");if((E===null||E===void 0?void 0:E.signal)!=null)B(E.signal,"options.signal");let a=1;if((E===null||E===void 0?void 0:E.concurrency)!=null)a=v(E.concurrency);let K0=a-1;if((E===null||E===void 0?void 0:E.highWaterMark)!=null)K0=v(E.highWaterMark);return V(a,"options.concurrency",1),V(K0,"options.highWaterMark",0),K0+=a,async function*(){let R=e0().AbortSignalAny([E===null||E===void 0?void 0:E.signal].filter(H)),Y=this,C=[],u={signal:R},e,r,s=!1,T=0;function t(){s=!0,G0()}function G0(){T-=1,Q0()}function Q0(){if(r&&!s&&T=K0||T>=a))await new d((m0)=>{r=m0})}C.push(h)}catch(I0){let m0=_(I0);P(m0,G0,t),C.push(m0)}finally{if(s=!0,e)e(),e=null}}M0();try{while(!0){while(C.length>0){let I0=await C[0];if(I0===h)return;if(R.aborted)throw new W;if(I0!==c)yield I0;C.shift(),Q0()}await new d((I0)=>{e=I0})}}finally{if(s=!0,r)r(),r=null}}.call(this)}function $0(O=void 0){if(O!=null)U(O,"options");if((O===null||O===void 0?void 0:O.signal)!=null)B(O.signal,"options.signal");return async function*(){let E=0;for await(let K0 of this){var a;if(O!==null&&O!==void 0&&(a=O.signal)!==null&&a!==void 0&&a.aborted)throw new W({cause:O.signal.reason});yield[E++,K0]}}.call(this)}async function Z0(O,E=void 0){for await(let a of y.call(this,O,E))return!0;return!1}async function F0(O,E=void 0){if(typeof O!=="function")throw new J("fn",["Function","AsyncFunction"],O);return!await Z0.call(this,async(...a)=>{return!await O(...a)},E)}async function p(O,E){for await(let a of y.call(this,O,E))return a;return}async function W0(O,E){if(typeof O!=="function")throw new J("fn",["Function","AsyncFunction"],O);async function a(K0,R){return await O(K0,R),c}for await(let K0 of l.call(this,a,E));}function y(O,E){if(typeof O!=="function")throw new J("fn",["Function","AsyncFunction"],O);async function a(K0,R){if(await O(K0,R))return K0;return c}return l.call(this,a,E)}class i extends Z{constructor(){super("reduce");this.message="Reduce of an empty stream requires an initial value"}}async function U0(O,E,a){var K0;if(typeof O!=="function")throw new J("reducer",["Function","AsyncFunction"],O);if(a!=null)U(a,"options");if((a===null||a===void 0?void 0:a.signal)!=null)B(a.signal,"options.signal");let R=arguments.length>1;if(a!==null&&a!==void 0&&(K0=a.signal)!==null&&K0!==void 0&&K0.aborted){let r=new W(void 0,{cause:a.signal.reason});throw this.once("error",()=>{}),await M(this.destroy(r)),r}let Y=new Q,C=Y.signal;if(a!==null&&a!==void 0&&a.signal){let r={once:!0,[w]:this,[F]:!0};a.signal.addEventListener("abort",()=>Y.abort(),r)}let u=!1;try{for await(let r of this){var e;if(u=!0,a!==null&&a!==void 0&&(e=a.signal)!==null&&e!==void 0&&e.aborted)throw new W;if(!R)E=r,R=!0;else E=await O(E,r,{signal:C})}if(!u&&!R)throw new i}finally{Y.abort()}return E}async function m(O){if(O!=null)U(O,"options");if((O===null||O===void 0?void 0:O.signal)!=null)B(O.signal,"options.signal");let E=[];for await(let K0 of this){var a;if(O!==null&&O!==void 0&&(a=O.signal)!==null&&a!==void 0&&a.aborted)throw new W(void 0,{cause:O.signal.reason});N(E,K0)}return E}function V0(O,E){let a=l.call(this,O,E);return async function*(){for await(let K0 of a)yield*K0}.call(this)}function w0(O){if(O=j(O),n(O))return 0;if(O<0)throw new G("number",">= 0",O);return O}function S(O,E=void 0){if(E!=null)U(E,"options");if((E===null||E===void 0?void 0:E.signal)!=null)B(E.signal,"options.signal");return O=w0(O),async function*(){var a;if(E!==null&&E!==void 0&&(a=E.signal)!==null&&a!==void 0&&a.aborted)throw new W;for await(let R of this){var K0;if(E!==null&&E!==void 0&&(K0=E.signal)!==null&&K0!==void 0&&K0.aborted)throw new W;if(O--<=0)yield R}}.call(this)}function b(O,E=void 0){if(E!=null)U(E,"options");if((E===null||E===void 0?void 0:E.signal)!=null)B(E.signal,"options.signal");return O=w0(O),async function*(){var a;if(E!==null&&E!==void 0&&(a=E.signal)!==null&&a!==void 0&&a.aborted)throw new W;for await(let R of this){var K0;if(E!==null&&E!==void 0&&(K0=E.signal)!==null&&K0!==void 0&&K0.aborted)throw new W;if(O-- >0)yield R;if(O<=0)return}}.call(this)}q.exports.streamReturningOperators={asIndexedPairs:z($0,"readable.asIndexedPairs will be removed in a future version."),drop:S,filter:y,flatMap:V0,map:l,take:b,compose:x},q.exports.promiseReturningOperators={every:F0,forEach:W0,reduce:U0,toArray:m,some:Z0,find:p}}),t9=g0(($,q)=>{var{ArrayPrototypePop:Q,Promise:K}=P0(),{isIterable:J,isNodeStream:Z,isWebStream:G}=b2(),{pipelineImpl:W}=n5(),{finished:B}=s2();e9();function V(...U){return new K((w,F)=>{let M,k,f=U[U.length-1];if(f&&typeof f==="object"&&!Z(f)&&!J(f)&&!G(f)){let L=Q(U);M=L.signal,k=L.end}W(U,(L,D)=>{if(L)F(L);else w(D)},{signal:M,end:k})})}q.exports={finished:B,pipeline:V}}),e9=g0(($,q)=>{var{Buffer:Q}=(t0(),X0(K2)),{ObjectDefineProperty:K,ObjectKeys:J,ReflectApply:Z}=P0(),{promisify:{custom:G}}=e0(),{streamReturningOperators:W,promiseReturningOperators:B}=hV(),{codes:{ERR_ILLEGAL_CONSTRUCTOR:V}}=a0(),U=s9(),{setDefaultHighWaterMark:w,getDefaultHighWaterMark:F}=H8(),{pipeline:M}=n5(),{destroyer:k}=o1(),f=s2(),L=t9(),D=b2(),z=q.exports=c5().Stream;z.isDestroyed=D.isDestroyed,z.isDisturbed=D.isDisturbed,z.isErrored=D.isErrored,z.isReadable=D.isReadable,z.isWritable=D.isWritable,z.Readable=v8();for(let H of J(W)){let v=function(...n){if(new.target)throw V();return z.Readable.from(Z(j,this,n))},j=W[H];K(v,"name",{__proto__:null,value:j.name}),K(v,"length",{__proto__:null,value:j.length}),K(z.Readable.prototype,H,{__proto__:null,value:v,enumerable:!1,configurable:!0,writable:!0})}for(let H of J(B)){let v=function(...n){if(new.target)throw V();return Z(j,this,n)},j=B[H];K(v,"name",{__proto__:null,value:j.name}),K(v,"length",{__proto__:null,value:j.length}),K(z.Readable.prototype,H,{__proto__:null,value:v,enumerable:!1,configurable:!0,writable:!0})}z.Writable=b5(),z.Duplex=c2(),z.Transform=l9(),z.PassThrough=r9(),z.pipeline=M;var{addAbortSignal:N}=L8();z.addAbortSignal=N,z.finished=f,z.destroy=k,z.compose=U,z.setDefaultHighWaterMark=w,z.getDefaultHighWaterMark=F,K(z,"promises",{__proto__:null,configurable:!0,enumerable:!0,get(){return L}}),K(M,G,{__proto__:null,enumerable:!0,get(){return L.pipeline}}),K(f,G,{__proto__:null,enumerable:!0,get(){return L.finished}}),z.Stream=z,z._isUint8Array=function(H){return H instanceof Uint8Array},z._uint8ArrayToBuffer=function(H){return Q.from(H.buffer,H.byteOffset,H.byteLength)}}),xV=g0(($,q)=>{var Q=a1();{let K=e9(),J=t9(),Z=K.Readable.destroy;q.exports=K.Readable,q.exports._uint8ArrayToBuffer=K._uint8ArrayToBuffer,q.exports._isUint8Array=K._isUint8Array,q.exports.isDisturbed=K.isDisturbed,q.exports.isErrored=K.isErrored,q.exports.isReadable=K.isReadable,q.exports.Readable=K.Readable,q.exports.Writable=K.Writable,q.exports.Duplex=K.Duplex,q.exports.Transform=K.Transform,q.exports.PassThrough=K.PassThrough,q.exports.addAbortSignal=K.addAbortSignal,q.exports.finished=K.finished,q.exports.destroy=K.destroy,q.exports.destroy=Z,q.exports.pipeline=K.pipeline,q.exports.compose=K.compose,Object.defineProperty(K,"promises",{configurable:!0,enumerable:!0,get(){return J}}),q.exports.Stream=K.Stream}q.exports.default=q.exports});$$.exports=xV()});var d5=N0((Fz,Q$)=>{Q$.exports=a1()});var n2=N0((J2)=>{J2.base64=!0;J2.array=!0;J2.string=!0;J2.arraybuffer=typeof ArrayBuffer<"u"&&typeof Uint8Array<"u";J2.nodebuffer=typeof Buffer<"u";J2.uint8array=typeof Uint8Array<"u";if(typeof ArrayBuffer>"u")J2.blob=!1;else{f8=new ArrayBuffer(0);try{J2.blob=new Blob([f8],{type:"application/zip"}).size===0}catch($){try{m5=self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder,R8=new m5,R8.append(f8),J2.blob=R8.getBlob("application/zip").size===0}catch(q){J2.blob=!1}}}var f8,m5,R8;try{J2.nodestream=!!d5().Readable}catch($){J2.nodestream=!1}});var i5=N0((p5)=>{var OV=T0(),PV=n2(),A2="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";p5.encode=function($){var q=[],Q,K,J,Z,G,W,B,V=0,U=$.length,w=U,F=OV.getTypeOf($)!=="string";while(V<$.length){if(w=U-V,!F)Q=$.charCodeAt(V++),K=V>2,G=(Q&3)<<4|K>>4,W=w>1?(K&15)<<2|J>>6:64,B=w>2?J&63:64,q.push(A2.charAt(Z)+A2.charAt(G)+A2.charAt(W)+A2.charAt(B))}return q.join("")};p5.decode=function($){var q,Q,K,J,Z,G,W,B=0,V=0,U="data:";if($.substr(0,U.length)===U)throw Error("Invalid base64 input, it looks like a data url.");$=$.replace(/[^A-Za-z0-9+/=]/g,"");var w=$.length*3/4;if($.charAt($.length-1)===A2.charAt(64))w--;if($.charAt($.length-2)===A2.charAt(64))w--;if(w%1!==0)throw Error("Invalid base64 input, bad content length.");var F;if(PV.uint8array)F=new Uint8Array(w|0);else F=Array(w|0);while(B<$.length){if(J=A2.indexOf($.charAt(B++)),Z=A2.indexOf($.charAt(B++)),G=A2.indexOf($.charAt(B++)),W=A2.indexOf($.charAt(B++)),q=J<<2|Z>>4,Q=(Z&15)<<4|G>>2,K=(G&3)<<6|W,F[V++]=q,G!==64)F[V++]=Q;if(W!==64)F[V++]=K}return F}});var T6=N0((Nz,q$)=>{q$.exports={isNode:typeof Buffer<"u",newBufferFrom:function($,q){if(Buffer.from&&Buffer.from!==Uint8Array.from)return Buffer.from($,q);else{if(typeof $==="number")throw Error('The "data" argument must not be a number');return new Buffer($,q)}},allocBuffer:function($){if(Buffer.alloc)return Buffer.alloc($);else{var q=new Buffer($);return q.fill(0),q}},isBuffer:function($){return Buffer.isBuffer($)},isStream:function($){return $&&typeof $.on==="function"&&typeof $.pause==="function"&&typeof $.resume==="function"}}});var V$=N0((Yz,J$)=>{var K$=global.MutationObserver||global.WebKitMutationObserver,u6;if(K$)C8=0,o5=new K$(I8),j8=global.document.createTextNode(""),o5.observe(j8,{characterData:!0}),u6=function(){j8.data=C8=++C8%2};else if(!global.setImmediate&&typeof global.MessageChannel<"u")g8=new global.MessageChannel,g8.port1.onmessage=I8,u6=function(){g8.port2.postMessage(0)};else if("document"in global&&"onreadystatechange"in global.document.createElement("script"))u6=function(){var $=global.document.createElement("script");$.onreadystatechange=function(){I8(),$.onreadystatechange=null,$.parentNode.removeChild($),$=null},global.document.documentElement.appendChild($)};else u6=function(){setTimeout(I8,0)};var C8,o5,j8,g8,a5,S6=[];function I8(){a5=!0;var $,q,Q=S6.length;while(Q){q=S6,S6=[],$=-1;while(++${var uV=V$();function l1(){}var o0={},U$=["REJECTED"],l5=["FULFILLED"],Z$=["PENDING"];B$.exports=t2;function t2($){if(typeof $!=="function")throw TypeError("resolver must be a function");if(this.state=Z$,this.queue=[],this.outcome=void 0,$!==l1)G$(this,$)}t2.prototype.finally=function($){if(typeof $!=="function")return this;var q=this.constructor;return this.then(Q,K);function Q(J){function Z(){return J}return q.resolve($()).then(Z)}function K(J){function Z(){throw J}return q.resolve($()).then(Z)}};t2.prototype.catch=function($){return this.then(null,$)};t2.prototype.then=function($,q){if(typeof $!=="function"&&this.state===l5||typeof q!=="function"&&this.state===U$)return this;var Q=new this.constructor(l1);if(this.state!==Z$){var K=this.state===l5?$:q;r5(Q,K,this.outcome)}else this.queue.push(new E6(Q,$,q));return Q};function E6($,q,Q){if(this.promise=$,typeof q==="function")this.onFulfilled=q,this.callFulfilled=this.otherCallFulfilled;if(typeof Q==="function")this.onRejected=Q,this.callRejected=this.otherCallRejected}E6.prototype.callFulfilled=function($){o0.resolve(this.promise,$)};E6.prototype.otherCallFulfilled=function($){r5(this.promise,this.onFulfilled,$)};E6.prototype.callRejected=function($){o0.reject(this.promise,$)};E6.prototype.otherCallRejected=function($){r5(this.promise,this.onRejected,$)};function r5($,q,Q){uV(function(){var K;try{K=q(Q)}catch(J){return o0.reject($,J)}if(K===$)o0.reject($,TypeError("Cannot resolve promise with itself"));else o0.resolve($,K)})}o0.resolve=function($,q){var Q=W$(SV,q);if(Q.status==="error")return o0.reject($,Q.value);var K=Q.value;if(K)G$($,K);else{$.state=l5,$.outcome=q;var J=-1,Z=$.queue.length;while(++J{var s5=null;if(typeof Promise<"u")s5=Promise;else s5=z$();F$.exports={Promise:s5}});var w$=N0((M$)=>{(function($,q){if($.setImmediate)return;var Q=1,K={},J=!1,Z=$.document,G;function W(z){if(typeof z!=="function")z=Function(""+z);var N=Array(arguments.length-1);for(var H=0;H"u"?typeof global>"u"?M$:global:self)});var T0=N0((_0)=>{var e2=n2(),nV=i5(),s1=T6(),t5=r1();w$();function dV($){var q=null;if(e2.uint8array)q=new Uint8Array($.length);else q=Array($.length);return X8($,q)}_0.newBlob=function($,q){_0.checkSupport("blob");try{return new Blob([$],{type:q})}catch(J){try{var Q=self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder,K=new Q;return K.append($),K.getBlob(q)}catch(Z){throw Error("Bug : can't construct the Blob.")}}};function _6($){return $}function X8($,q){for(var Q=0;Q<$.length;++Q)q[Q]=$.charCodeAt(Q)&255;return q}var A8={stringifyByChunk:function($,q,Q){var K=[],J=0,Z=$.length;if(Z<=Q)return String.fromCharCode.apply(null,$);while(J1)try{return A8.stringifyByChunk($,Q,q)}catch(J){q=Math.floor(q/2)}return A8.stringifyByChar($)}_0.applyFromCharCode=c6;function y8($,q){for(var Q=0;Q<$.length;Q++)q[Q]=$[Q];return q}var $1={};$1.string={string:_6,array:function($){return X8($,Array($.length))},arraybuffer:function($){return $1.string.uint8array($).buffer},uint8array:function($){return X8($,new Uint8Array($.length))},nodebuffer:function($){return X8($,s1.allocBuffer($.length))}};$1.array={string:c6,array:_6,arraybuffer:function($){return new Uint8Array($).buffer},uint8array:function($){return new Uint8Array($)},nodebuffer:function($){return s1.newBufferFrom($)}};$1.arraybuffer={string:function($){return c6(new Uint8Array($))},array:function($){return y8(new Uint8Array($),Array($.byteLength))},arraybuffer:_6,uint8array:function($){return new Uint8Array($)},nodebuffer:function($){return s1.newBufferFrom(new Uint8Array($))}};$1.uint8array={string:c6,array:function($){return y8($,Array($.length))},arraybuffer:function($){return $.buffer},uint8array:_6,nodebuffer:function($){return s1.newBufferFrom($)}};$1.nodebuffer={string:c6,array:function($){return y8($,Array($.length))},arraybuffer:function($){return $1.nodebuffer.uint8array($).buffer},uint8array:function($){return y8($,new Uint8Array($.length))},nodebuffer:_6};_0.transformTo=function($,q){if(!q)q="";if(!$)return q;_0.checkSupport($);var Q=_0.getTypeOf(q),K=$1[Q][$](q);return K};_0.resolve=function($){var q=$.split("/"),Q=[];for(var K=0;K"u")$[Q]=arguments[q][Q];return $};_0.prepareContent=function($,q,Q,K,J){var Z=t5.Promise.resolve(q).then(function(G){var W=e2.blob&&(G instanceof Blob||["[object File]","[object Blob]"].indexOf(Object.prototype.toString.call(G))!==-1);if(W&&typeof FileReader<"u")return new t5.Promise(function(B,V){var U=new FileReader;U.onload=function(w){B(w.target.result)},U.onerror=function(w){V(w.target.error)},U.readAsArrayBuffer(G)});else return G});return Z.then(function(G){var W=_0.getTypeOf(G);if(!W)return t5.Promise.reject(Error("Can't read the data of '"+$+"'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?"));if(W==="arraybuffer")G=_0.transformTo("uint8array",G);else if(W==="string"){if(J)G=nV.decode(G);else if(Q){if(K!==!0)G=dV(G)}}return G})}});var V2=N0((vz,Y$)=>{function N$($){this.name=$||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}N$.prototype={push:function($){this.emit("data",$)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch($){this.emit("error",$)}return!0},error:function($){if(this.isFinished)return!1;if(this.isPaused)this.generatedError=$;else{if(this.isFinished=!0,this.emit("error",$),this.previous)this.previous.error($);this.cleanUp()}return!0},on:function($,q){return this._listeners[$].push(q),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function($,q){if(this._listeners[$])for(var Q=0;Q "+$;else return $}};Y$.exports=N$});var e1=N0((Q1)=>{var t1=T0(),L1=n2(),mV=T6(),h8=V2(),b6=Array(256);for(X2=0;X2<256;X2++)b6[X2]=X2>=252?6:X2>=248?5:X2>=240?4:X2>=224?3:X2>=192?2:1;var X2;b6[254]=b6[254]=1;var pV=function($){var q,Q,K,J,Z,G=$.length,W=0;for(J=0;J>>6,q[Z++]=128|Q&63;else if(Q<65536)q[Z++]=224|Q>>>12,q[Z++]=128|Q>>>6&63,q[Z++]=128|Q&63;else q[Z++]=240|Q>>>18,q[Z++]=128|Q>>>12&63,q[Z++]=128|Q>>>6&63,q[Z++]=128|Q&63}return q},iV=function($,q){var Q;if(q=q||$.length,q>$.length)q=$.length;Q=q-1;while(Q>=0&&($[Q]&192)===128)Q--;if(Q<0)return q;if(Q===0)return q;return Q+b6[$[Q]]>q?Q:q},oV=function($){var q,Q,K,J,Z=$.length,G=Array(Z*2);for(Q=0,q=0;q4){G[Q++]=65533,q+=J-1;continue}K&=J===2?31:J===3?15:7;while(J>1&&q1){G[Q++]=65533;continue}if(K<65536)G[Q++]=K;else K-=65536,G[Q++]=55296|K>>10&1023,G[Q++]=56320|K&1023}if(G.length!==Q)if(G.subarray)G=G.subarray(0,Q);else G.length=Q;return t1.applyFromCharCode(G)};Q1.utf8encode=function(q){if(L1.nodebuffer)return mV.newBufferFrom(q,"utf-8");return pV(q)};Q1.utf8decode=function(q){if(L1.nodebuffer)return t1.transformTo("nodebuffer",q).toString("utf-8");return q=t1.transformTo(L1.uint8array?"uint8array":"array",q),oV(q)};function x8(){h8.call(this,"utf-8 decode"),this.leftOver=null}t1.inherits(x8,h8);x8.prototype.processChunk=function($){var q=t1.transformTo(L1.uint8array?"uint8array":"array",$.data);if(this.leftOver&&this.leftOver.length){if(L1.uint8array){var Q=q;q=new Uint8Array(Q.length+this.leftOver.length),q.set(this.leftOver,0),q.set(Q,this.leftOver.length)}else q=this.leftOver.concat(q);this.leftOver=null}var K=iV(q),J=q;if(K!==q.length)if(L1.uint8array)J=q.subarray(0,K),this.leftOver=q.subarray(K,q.length);else J=q.slice(0,K),this.leftOver=q.slice(K,q.length);this.push({data:Q1.utf8decode(J),meta:$.meta})};x8.prototype.flush=function(){if(this.leftOver&&this.leftOver.length)this.push({data:Q1.utf8decode(this.leftOver),meta:{}}),this.leftOver=null};Q1.Utf8DecodeWorker=x8;function e5(){h8.call(this,"utf-8 encode")}t1.inherits(e5,h8);e5.prototype.processChunk=function($){this.push({data:Q1.utf8encode($.data),meta:$.meta})};Q1.Utf8EncodeWorker=e5});var H$=N0((Rz,L$)=>{var k$=V2(),D$=T0();function $4($){k$.call(this,"ConvertWorker to "+$),this.destType=$}D$.inherits($4,k$);$4.prototype.processChunk=function($){this.push({data:D$.transformTo(this.destType,$.data),meta:$.meta})};L$.exports=$4});var R$=N0((Iz,f$)=>{var v$=d5().Readable,aV=T0();aV.inherits(Q4,v$);function Q4($,q,Q){v$.call(this,q),this._helper=$;var K=this;$.on("data",function(J,Z){if(!K.push(J))K._helper.pause();if(Q)Q(Z)}).on("error",function(J){K.emit("error",J)}).on("end",function(){K.push(null)})}Q4.prototype._read=function(){this._helper.resume()};f$.exports=Q4});var q4=N0((Cz,j$)=>{var H1=T0(),lV=H$(),rV=V2(),sV=i5(),tV=n2(),eV=r1(),I$=null;if(tV.nodestream)try{I$=R$()}catch($){}function $U($,q,Q){switch($){case"blob":return H1.newBlob(H1.transformTo("arraybuffer",q),Q);case"base64":return sV.encode(q);default:return H1.transformTo($,q)}}function QU($,q){var Q,K=0,J=null,Z=0;for(Q=0;Q{D2.base64=!1;D2.binary=!1;D2.dir=!1;D2.createFolders=!0;D2.date=null;D2.compression=null;D2.compressionOptions=null;D2.comment=null;D2.unixPermissions=null;D2.dosPermissions=null});var J4=N0((gz,g$)=>{var O8=T0(),P8=V2(),KU=16384;function $6($){P8.call(this,"DataWorker");var q=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,$.then(function(Q){if(q.dataIsReady=!0,q.data=Q,q.max=Q&&Q.length||0,q.type=O8.getTypeOf(Q),!q.isPaused)q._tickAndRepeat()},function(Q){q.error(Q)})}O8.inherits($6,P8);$6.prototype.cleanUp=function(){P8.prototype.cleanUp.call(this),this.data=null};$6.prototype.resume=function(){if(!P8.prototype.resume.call(this))return!1;if(!this._tickScheduled&&this.dataIsReady)this._tickScheduled=!0,O8.delay(this._tickAndRepeat,[],this);return!0};$6.prototype._tickAndRepeat=function(){if(this._tickScheduled=!1,this.isPaused||this.isFinished)return;if(this._tick(),!this.isFinished)O8.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0};$6.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var $=KU,q=null,Q=Math.min(this.max,this.index+$);if(this.index>=this.max)return this.end();else{switch(this.type){case"string":q=this.data.substring(this.index,Q);break;case"uint8array":q=this.data.subarray(this.index,Q);break;case"array":case"nodebuffer":q=this.data.slice(this.index,Q);break}return this.index=Q,this.push({data:q,meta:{percent:this.max?this.index/this.max*100:0}})}};g$.exports=$6});var T8=N0((Az,X$)=>{var JU=T0();function VU(){var $,q=[];for(var Q=0;Q<256;Q++){$=Q;for(var K=0;K<8;K++)$=$&1?3988292384^$>>>1:$>>>1;q[Q]=$}return q}var A$=VU();function UU($,q,Q,K){var J=A$,Z=K+Q;$=$^-1;for(var G=K;G>>8^J[($^q[G])&255];return $^-1}function ZU($,q,Q,K){var J=A$,Z=K+Q;$=$^-1;for(var G=K;G>>8^J[($^q.charCodeAt(G))&255];return $^-1}X$.exports=function(q,Q){if(typeof q>"u"||!q.length)return 0;var K=JU.getTypeOf(q)!=="string";if(K)return UU(Q|0,q,q.length,0);else return ZU(Q|0,q,q.length,0)}});var U4=N0((Xz,h$)=>{var y$=V2(),GU=T8(),WU=T0();function V4(){y$.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}WU.inherits(V4,y$);V4.prototype.processChunk=function($){this.streamInfo.crc32=GU($.data,this.streamInfo.crc32||0),this.push($)};h$.exports=V4});var O$=N0((yz,x$)=>{var BU=T0(),Z4=V2();function G4($){Z4.call(this,"DataLengthProbe for "+$),this.propName=$,this.withStreamInfo($,0)}BU.inherits(G4,Z4);G4.prototype.processChunk=function($){if($){var q=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=q+$.data.length}Z4.prototype.processChunk.call(this,$)};x$.exports=G4});var u8=N0((hz,u$)=>{var P$=r1(),T$=J4(),zU=U4(),W4=O$();function B4($,q,Q,K,J){this.compressedSize=$,this.uncompressedSize=q,this.crc32=Q,this.compression=K,this.compressedContent=J}B4.prototype={getContentWorker:function(){var $=new T$(P$.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new W4("data_length")),q=this;return $.on("end",function(){if(this.streamInfo.data_length!==q.uncompressedSize)throw Error("Bug : uncompressed data size mismatch")}),$},getCompressedWorker:function(){return new T$(P$.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}};B4.createWorkerFrom=function($,q,Q){return $.pipe(new zU).pipe(new W4("uncompressedSize")).pipe(q.compressWorker(Q)).pipe(new W4("compressedSize")).withStreamInfo("compression",q)};u$.exports=B4});var c$=N0((xz,_$)=>{var FU=q4(),MU=J4(),z4=e1(),F4=u8(),S$=V2(),M4=function($,q,Q){this.name=$,this.dir=Q.dir,this.date=Q.date,this.comment=Q.comment,this.unixPermissions=Q.unixPermissions,this.dosPermissions=Q.dosPermissions,this._data=q,this._dataBinary=Q.binary,this.options={compression:Q.compression,compressionOptions:Q.compressionOptions}};M4.prototype={internalStream:function($){var q=null,Q="string";try{if(!$)throw Error("No output type specified.");Q=$.toLowerCase();var K=Q==="string"||Q==="text";if(Q==="binarystring"||Q==="text")Q="string";q=this._decompressWorker();var J=!this._dataBinary;if(J&&!K)q=q.pipe(new z4.Utf8EncodeWorker);if(!J&&K)q=q.pipe(new z4.Utf8DecodeWorker)}catch(Z){q=new S$("error"),q.error(Z)}return new FU(q,Q,"")},async:function($,q){return this.internalStream($).accumulate(q)},nodeStream:function($,q){return this.internalStream($||"nodebuffer").toNodejsStream(q)},_compressWorker:function($,q){if(this._data instanceof F4&&this._data.compression.magic===$.magic)return this._data.getCompressedWorker();else{var Q=this._decompressWorker();if(!this._dataBinary)Q=Q.pipe(new z4.Utf8EncodeWorker);return F4.createWorkerFrom(Q,$,q)}},_decompressWorker:function(){if(this._data instanceof F4)return this._data.getContentWorker();else if(this._data instanceof S$)return this._data;else return new MU(this._data)}};var E$=["asText","asBinary","asNodeBuffer","asUint8Array","asArrayBuffer"],wU=function(){throw Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")};for(n6=0;n6{var NU=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Int32Array<"u";function YU($,q){return Object.prototype.hasOwnProperty.call($,q)}l0.assign=function($){var q=Array.prototype.slice.call(arguments,1);while(q.length){var Q=q.shift();if(!Q)continue;if(typeof Q!=="object")throw TypeError(Q+"must be non-object");for(var K in Q)if(YU(Q,K))$[K]=Q[K]}return $};l0.shrinkBuf=function($,q){if($.length===q)return $;if($.subarray)return $.subarray(0,q);return $.length=q,$};var kU={arraySet:function($,q,Q,K,J){if(q.subarray&&$.subarray){$.set(q.subarray(Q,Q+K),J);return}for(var Z=0;Z{var LU=d2(),HU=4,b$=0,n$=1,vU=2;function q6($){var q=$.length;while(--q>=0)$[q]=0}var fU=0,a$=1,RU=2,IU=3,CU=258,H4=29,a6=256,m6=a6+1+H4,Q6=30,v4=19,l$=2*m6+1,v1=15,w4=16,jU=7,f4=256,r$=16,s$=17,t$=18,D4=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],S8=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],gU=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],e$=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],AU=512,m2=Array((m6+2)*2);q6(m2);var d6=Array(Q6*2);q6(d6);var p6=Array(AU);q6(p6);var i6=Array(CU-IU+1);q6(i6);var R4=Array(H4);q6(R4);var E8=Array(Q6);q6(E8);function N4($,q,Q,K,J){this.static_tree=$,this.extra_bits=q,this.extra_base=Q,this.elems=K,this.max_length=J,this.has_stree=$&&$.length}var $Q,QQ,qQ;function Y4($,q){this.dyn_tree=$,this.max_code=0,this.stat_desc=q}function KQ($){return $<256?p6[$]:p6[256+($>>>7)]}function o6($,q){$.pending_buf[$.pending++]=q&255,$.pending_buf[$.pending++]=q>>>8&255}function $2($,q,Q){if($.bi_valid>w4-Q)$.bi_buf|=q<<$.bi_valid&65535,o6($,$.bi_buf),$.bi_buf=q>>w4-$.bi_valid,$.bi_valid+=Q-w4;else $.bi_buf|=q<<$.bi_valid&65535,$.bi_valid+=Q}function y2($,q,Q){$2($,Q[q*2],Q[q*2+1])}function JQ($,q){var Q=0;do Q|=$&1,$>>>=1,Q<<=1;while(--q>0);return Q>>>1}function XU($){if($.bi_valid===16)o6($,$.bi_buf),$.bi_buf=0,$.bi_valid=0;else if($.bi_valid>=8)$.pending_buf[$.pending++]=$.bi_buf&255,$.bi_buf>>=8,$.bi_valid-=8}function yU($,q){var{dyn_tree:Q,max_code:K}=q,J=q.stat_desc.static_tree,Z=q.stat_desc.has_stree,G=q.stat_desc.extra_bits,W=q.stat_desc.extra_base,B=q.stat_desc.max_length,V,U,w,F,M,k,f=0;for(F=0;F<=v1;F++)$.bl_count[F]=0;Q[$.heap[$.heap_max]*2+1]=0;for(V=$.heap_max+1;VB)F=B,f++;if(Q[U*2+1]=F,U>K)continue;if($.bl_count[F]++,M=0,U>=W)M=G[U-W];if(k=Q[U*2],$.opt_len+=k*(F+M),Z)$.static_len+=k*(J[U*2+1]+M)}if(f===0)return;do{F=B-1;while($.bl_count[F]===0)F--;$.bl_count[F]--,$.bl_count[F+1]+=2,$.bl_count[B]--,f-=2}while(f>0);for(F=B;F!==0;F--){U=$.bl_count[F];while(U!==0){if(w=$.heap[--V],w>K)continue;if(Q[w*2+1]!==F)$.opt_len+=(F-Q[w*2+1])*Q[w*2],Q[w*2+1]=F;U--}}}function VQ($,q,Q){var K=Array(v1+1),J=0,Z,G;for(Z=1;Z<=v1;Z++)K[Z]=J=J+Q[Z-1]<<1;for(G=0;G<=q;G++){var W=$[G*2+1];if(W===0)continue;$[G*2]=JQ(K[W]++,W)}}function hU(){var $,q,Q,K,J,Z=Array(v1+1);Q=0;for(K=0;K>=7;for(;K8)o6($,$.bi_buf);else if($.bi_valid>0)$.pending_buf[$.pending++]=$.bi_buf;$.bi_buf=0,$.bi_valid=0}function xU($,q,Q,K){if(ZQ($),K)o6($,Q),o6($,~Q);LU.arraySet($.pending_buf,$.window,q,Q,$.pending),$.pending+=Q}function d$($,q,Q,K){var J=q*2,Z=Q*2;return $[J]<$[Z]||$[J]===$[Z]&&K[q]<=K[Q]}function k4($,q,Q){var K=$.heap[Q],J=Q<<1;while(J<=$.heap_len){if(J<$.heap_len&&d$(q,$.heap[J+1],$.heap[J],$.depth))J++;if(d$(q,K,$.heap[J],$.depth))break;$.heap[Q]=$.heap[J],Q=J,J<<=1}$.heap[Q]=K}function m$($,q,Q){var K,J,Z=0,G,W;if($.last_lit!==0)do if(K=$.pending_buf[$.d_buf+Z*2]<<8|$.pending_buf[$.d_buf+Z*2+1],J=$.pending_buf[$.l_buf+Z],Z++,K===0)y2($,J,q);else{if(G=i6[J],y2($,G+a6+1,q),W=D4[G],W!==0)J-=R4[G],$2($,J,W);if(K--,G=KQ(K),y2($,G,Q),W=S8[G],W!==0)K-=E8[G],$2($,K,W)}while(Z<$.last_lit);y2($,f4,q)}function L4($,q){var Q=q.dyn_tree,K=q.stat_desc.static_tree,J=q.stat_desc.has_stree,Z=q.stat_desc.elems,G,W,B=-1,V;$.heap_len=0,$.heap_max=l$;for(G=0;G>1;G>=1;G--)k4($,Q,G);V=Z;do G=$.heap[1],$.heap[1]=$.heap[$.heap_len--],k4($,Q,1),W=$.heap[1],$.heap[--$.heap_max]=G,$.heap[--$.heap_max]=W,Q[V*2]=Q[G*2]+Q[W*2],$.depth[V]=($.depth[G]>=$.depth[W]?$.depth[G]:$.depth[W])+1,Q[G*2+1]=Q[W*2+1]=V,$.heap[1]=V++,k4($,Q,1);while($.heap_len>=2);$.heap[--$.heap_max]=$.heap[1],yU($,q),VQ(Q,B,$.bl_count)}function p$($,q,Q){var K,J=-1,Z,G=q[1],W=0,B=7,V=4;if(G===0)B=138,V=3;q[(Q+1)*2+1]=65535;for(K=0;K<=Q;K++){if(Z=G,G=q[(K+1)*2+1],++W=3;q--)if($.bl_tree[e$[q]*2+1]!==0)break;return $.opt_len+=3*(q+1)+5+5+4,q}function PU($,q,Q,K){var J;$2($,q-257,5),$2($,Q-1,5),$2($,K-4,4);for(J=0;J>>=1)if(q&1&&$.dyn_ltree[Q*2]!==0)return b$;if($.dyn_ltree[18]!==0||$.dyn_ltree[20]!==0||$.dyn_ltree[26]!==0)return n$;for(Q=32;Q0){if($.strm.data_type===vU)$.strm.data_type=TU($);if(L4($,$.l_desc),L4($,$.d_desc),G=OU($),J=$.opt_len+3+7>>>3,Z=$.static_len+3+7>>>3,Z<=J)J=Z}else J=Z=Q+5;if(Q+4<=J&&q!==-1)GQ($,q,Q,K);else if($.strategy===HU||Z===J)$2($,(a$<<1)+(K?1:0),3),m$($,m2,d6);else $2($,(RU<<1)+(K?1:0),3),PU($,$.l_desc.max_code+1,$.d_desc.max_code+1,G+1),m$($,$.dyn_ltree,$.dyn_dtree);if(UQ($),K)ZQ($)}function _U($,q,Q){if($.pending_buf[$.d_buf+$.last_lit*2]=q>>>8&255,$.pending_buf[$.d_buf+$.last_lit*2+1]=q&255,$.pending_buf[$.l_buf+$.last_lit]=Q&255,$.last_lit++,q===0)$.dyn_ltree[Q*2]++;else $.matches++,q--,$.dyn_ltree[(i6[Q]+a6+1)*2]++,$.dyn_dtree[KQ(q)*2]++;return $.last_lit===$.lit_bufsize-1}K6._tr_init=uU;K6._tr_stored_block=GQ;K6._tr_flush_block=EU;K6._tr_tally=_U;K6._tr_align=SU});var I4=N0((Tz,BQ)=>{function cU($,q,Q,K){var J=$&65535|0,Z=$>>>16&65535|0,G=0;while(Q!==0){G=Q>2000?2000:Q,Q-=G;do J=J+q[K++]|0,Z=Z+J|0;while(--G);J%=65521,Z%=65521}return J|Z<<16|0}BQ.exports=cU});var C4=N0((uz,zQ)=>{function bU(){var $,q=[];for(var Q=0;Q<256;Q++){$=Q;for(var K=0;K<8;K++)$=$&1?3988292384^$>>>1:$>>>1;q[Q]=$}return q}var nU=bU();function dU($,q,Q,K){var J=nU,Z=K+Q;$^=-1;for(var G=K;G>>8^J[($^q[G])&255];return $^-1}zQ.exports=dU});var _8=N0((Sz,FQ)=>{FQ.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}});var vQ=N0((O2)=>{var r0=d2(),M2=WQ(),YQ=I4(),q1=C4(),mU=_8(),C1=0,pU=1,iU=3,Z1=4,MQ=5,x2=0,wQ=1,w2=-2,oU=-3,j4=-5,aU=-1,lU=1,c8=2,rU=3,sU=4,tU=0,eU=2,m8=8,$Z=9,QZ=15,qZ=8,KZ=29,JZ=256,A4=JZ+1+KZ,VZ=30,UZ=19,ZZ=2*A4+1,GZ=15,f0=3,V1=258,L2=V1+f0+1,WZ=32,p8=42,X4=69,b8=73,n8=91,d8=103,f1=113,r6=666,c0=1,s6=2,R1=3,U6=4,BZ=3;function U1($,q){return $.msg=mU[q],q}function NQ($){return($<<1)-($>4?9:0)}function J1($){var q=$.length;while(--q>=0)$[q]=0}function K1($){var q=$.state,Q=q.pending;if(Q>$.avail_out)Q=$.avail_out;if(Q===0)return;if(r0.arraySet($.output,q.pending_buf,q.pending_out,Q,$.next_out),$.next_out+=Q,q.pending_out+=Q,$.total_out+=Q,$.avail_out-=Q,q.pending-=Q,q.pending===0)q.pending_out=0}function d0($,q){M2._tr_flush_block($,$.block_start>=0?$.block_start:-1,$.strstart-$.block_start,q),$.block_start=$.strstart,K1($.strm)}function C0($,q){$.pending_buf[$.pending++]=q}function l6($,q){$.pending_buf[$.pending++]=q>>>8&255,$.pending_buf[$.pending++]=q&255}function zZ($,q,Q,K){var J=$.avail_in;if(J>K)J=K;if(J===0)return 0;if($.avail_in-=J,r0.arraySet(q,$.input,$.next_in,J,Q),$.state.wrap===1)$.adler=YQ($.adler,q,J,Q);else if($.state.wrap===2)$.adler=q1($.adler,q,J,Q);return $.next_in+=J,$.total_in+=J,J}function kQ($,q){var{max_chain_length:Q,strstart:K}=$,J,Z,G=$.prev_length,W=$.nice_match,B=$.strstart>$.w_size-L2?$.strstart-($.w_size-L2):0,V=$.window,U=$.w_mask,w=$.prev,F=$.strstart+V1,M=V[K+G-1],k=V[K+G];if($.prev_length>=$.good_match)Q>>=2;if(W>$.lookahead)W=$.lookahead;do{if(J=q,V[J+G]!==k||V[J+G-1]!==M||V[J]!==V[K]||V[++J]!==V[K+1])continue;K+=2,J++;do;while(V[++K]===V[++J]&&V[++K]===V[++J]&&V[++K]===V[++J]&&V[++K]===V[++J]&&V[++K]===V[++J]&&V[++K]===V[++J]&&V[++K]===V[++J]&&V[++K]===V[++J]&&KG){if($.match_start=q,G=Z,Z>=W)break;M=V[K+G-1],k=V[K+G]}}while((q=w[q&U])>B&&--Q!==0);if(G<=$.lookahead)return G;return $.lookahead}function I1($){var q=$.w_size,Q,K,J,Z,G;do{if(Z=$.window_size-$.lookahead-$.strstart,$.strstart>=q+(q-L2)){r0.arraySet($.window,$.window,q,q,0),$.match_start-=q,$.strstart-=q,$.block_start-=q,K=$.hash_size,Q=K;do J=$.head[--Q],$.head[Q]=J>=q?J-q:0;while(--K);K=q,Q=K;do J=$.prev[--Q],$.prev[Q]=J>=q?J-q:0;while(--K);Z+=q}if($.strm.avail_in===0)break;if(K=zZ($.strm,$.window,$.strstart+$.lookahead,Z),$.lookahead+=K,$.lookahead+$.insert>=f0){G=$.strstart-$.insert,$.ins_h=$.window[G],$.ins_h=($.ins_h<<$.hash_shift^$.window[G+1])&$.hash_mask;while($.insert)if($.ins_h=($.ins_h<<$.hash_shift^$.window[G+f0-1])&$.hash_mask,$.prev[G&$.w_mask]=$.head[$.ins_h],$.head[$.ins_h]=G,G++,$.insert--,$.lookahead+$.insert$.pending_buf_size-5)Q=$.pending_buf_size-5;for(;;){if($.lookahead<=1){if(I1($),$.lookahead===0&&q===C1)return c0;if($.lookahead===0)break}$.strstart+=$.lookahead,$.lookahead=0;var K=$.block_start+Q;if($.strstart===0||$.strstart>=K){if($.lookahead=$.strstart-K,$.strstart=K,d0($,!1),$.strm.avail_out===0)return c0}if($.strstart-$.block_start>=$.w_size-L2){if(d0($,!1),$.strm.avail_out===0)return c0}}if($.insert=0,q===Z1){if(d0($,!0),$.strm.avail_out===0)return R1;return U6}if($.strstart>$.block_start){if(d0($,!1),$.strm.avail_out===0)return c0}return c0}function g4($,q){var Q,K;for(;;){if($.lookahead=f0)$.ins_h=($.ins_h<<$.hash_shift^$.window[$.strstart+f0-1])&$.hash_mask,Q=$.prev[$.strstart&$.w_mask]=$.head[$.ins_h],$.head[$.ins_h]=$.strstart;if(Q!==0&&$.strstart-Q<=$.w_size-L2)$.match_length=kQ($,Q);if($.match_length>=f0)if(K=M2._tr_tally($,$.strstart-$.match_start,$.match_length-f0),$.lookahead-=$.match_length,$.match_length<=$.max_lazy_match&&$.lookahead>=f0){$.match_length--;do $.strstart++,$.ins_h=($.ins_h<<$.hash_shift^$.window[$.strstart+f0-1])&$.hash_mask,Q=$.prev[$.strstart&$.w_mask]=$.head[$.ins_h],$.head[$.ins_h]=$.strstart;while(--$.match_length!==0);$.strstart++}else $.strstart+=$.match_length,$.match_length=0,$.ins_h=$.window[$.strstart],$.ins_h=($.ins_h<<$.hash_shift^$.window[$.strstart+1])&$.hash_mask;else K=M2._tr_tally($,0,$.window[$.strstart]),$.lookahead--,$.strstart++;if(K){if(d0($,!1),$.strm.avail_out===0)return c0}}if($.insert=$.strstart=f0)$.ins_h=($.ins_h<<$.hash_shift^$.window[$.strstart+f0-1])&$.hash_mask,Q=$.prev[$.strstart&$.w_mask]=$.head[$.ins_h],$.head[$.ins_h]=$.strstart;if($.prev_length=$.match_length,$.prev_match=$.match_start,$.match_length=f0-1,Q!==0&&$.prev_length<$.max_lazy_match&&$.strstart-Q<=$.w_size-L2){if($.match_length=kQ($,Q),$.match_length<=5&&($.strategy===lU||$.match_length===f0&&$.strstart-$.match_start>4096))$.match_length=f0-1}if($.prev_length>=f0&&$.match_length<=$.prev_length){J=$.strstart+$.lookahead-f0,K=M2._tr_tally($,$.strstart-1-$.prev_match,$.prev_length-f0),$.lookahead-=$.prev_length-1,$.prev_length-=2;do if(++$.strstart<=J)$.ins_h=($.ins_h<<$.hash_shift^$.window[$.strstart+f0-1])&$.hash_mask,Q=$.prev[$.strstart&$.w_mask]=$.head[$.ins_h],$.head[$.ins_h]=$.strstart;while(--$.prev_length!==0);if($.match_available=0,$.match_length=f0-1,$.strstart++,K){if(d0($,!1),$.strm.avail_out===0)return c0}}else if($.match_available){if(K=M2._tr_tally($,0,$.window[$.strstart-1]),K)d0($,!1);if($.strstart++,$.lookahead--,$.strm.avail_out===0)return c0}else $.match_available=1,$.strstart++,$.lookahead--}if($.match_available)K=M2._tr_tally($,0,$.window[$.strstart-1]),$.match_available=0;if($.insert=$.strstart=f0&&$.strstart>0){if(J=$.strstart-1,K=G[J],K===G[++J]&&K===G[++J]&&K===G[++J]){Z=$.strstart+V1;do;while(K===G[++J]&&K===G[++J]&&K===G[++J]&&K===G[++J]&&K===G[++J]&&K===G[++J]&&K===G[++J]&&K===G[++J]&&J$.lookahead)$.match_length=$.lookahead}}if($.match_length>=f0)Q=M2._tr_tally($,1,$.match_length-f0),$.lookahead-=$.match_length,$.strstart+=$.match_length,$.match_length=0;else Q=M2._tr_tally($,0,$.window[$.strstart]),$.lookahead--,$.strstart++;if(Q){if(d0($,!1),$.strm.avail_out===0)return c0}}if($.insert=0,q===Z1){if(d0($,!0),$.strm.avail_out===0)return R1;return U6}if($.last_lit){if(d0($,!1),$.strm.avail_out===0)return c0}return s6}function wZ($,q){var Q;for(;;){if($.lookahead===0){if(I1($),$.lookahead===0){if(q===C1)return c0;break}}if($.match_length=0,Q=M2._tr_tally($,0,$.window[$.strstart]),$.lookahead--,$.strstart++,Q){if(d0($,!1),$.strm.avail_out===0)return c0}}if($.insert=0,q===Z1){if(d0($,!0),$.strm.avail_out===0)return R1;return U6}if($.last_lit){if(d0($,!1),$.strm.avail_out===0)return c0}return s6}function h2($,q,Q,K,J){this.good_length=$,this.max_lazy=q,this.nice_length=Q,this.max_chain=K,this.func=J}var V6;V6=[new h2(0,0,0,0,FZ),new h2(4,4,8,4,g4),new h2(4,5,16,8,g4),new h2(4,6,32,32,g4),new h2(4,4,16,16,J6),new h2(8,16,32,32,J6),new h2(8,16,128,128,J6),new h2(8,32,128,256,J6),new h2(32,128,258,1024,J6),new h2(32,258,258,4096,J6)];function NZ($){$.window_size=2*$.w_size,J1($.head),$.max_lazy_match=V6[$.level].max_lazy,$.good_match=V6[$.level].good_length,$.nice_match=V6[$.level].nice_length,$.max_chain_length=V6[$.level].max_chain,$.strstart=0,$.block_start=0,$.lookahead=0,$.insert=0,$.match_length=$.prev_length=f0-1,$.match_available=0,$.ins_h=0}function YZ(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=m8,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new r0.Buf16(ZZ*2),this.dyn_dtree=new r0.Buf16((2*VZ+1)*2),this.bl_tree=new r0.Buf16((2*UZ+1)*2),J1(this.dyn_ltree),J1(this.dyn_dtree),J1(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new r0.Buf16(GZ+1),this.heap=new r0.Buf16(2*A4+1),J1(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new r0.Buf16(2*A4+1),J1(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function DQ($){var q;if(!$||!$.state)return U1($,w2);if($.total_in=$.total_out=0,$.data_type=eU,q=$.state,q.pending=0,q.pending_out=0,q.wrap<0)q.wrap=-q.wrap;return q.status=q.wrap?p8:f1,$.adler=q.wrap===2?0:1,q.last_flush=C1,M2._tr_init(q),x2}function LQ($){var q=DQ($);if(q===x2)NZ($.state);return q}function kZ($,q){if(!$||!$.state)return w2;if($.state.wrap!==2)return w2;return $.state.gzhead=q,x2}function HQ($,q,Q,K,J,Z){if(!$)return w2;var G=1;if(q===aU)q=6;if(K<0)G=0,K=-K;else if(K>15)G=2,K-=16;if(J<1||J>$Z||Q!==m8||K<8||K>15||q<0||q>9||Z<0||Z>sU)return U1($,w2);if(K===8)K=9;var W=new YZ;return $.state=W,W.strm=$,W.wrap=G,W.gzhead=null,W.w_bits=K,W.w_size=1<MQ||q<0)return $?U1($,w2):w2;if(K=$.state,!$.output||!$.input&&$.avail_in!==0||K.status===r6&&q!==Z1)return U1($,$.avail_out===0?j4:w2);if(K.strm=$,Q=K.last_flush,K.last_flush=q,K.status===p8)if(K.wrap===2)if($.adler=0,C0(K,31),C0(K,139),C0(K,8),!K.gzhead)C0(K,0),C0(K,0),C0(K,0),C0(K,0),C0(K,0),C0(K,K.level===9?2:K.strategy>=c8||K.level<2?4:0),C0(K,BZ),K.status=f1;else{if(C0(K,(K.gzhead.text?1:0)+(K.gzhead.hcrc?2:0)+(!K.gzhead.extra?0:4)+(!K.gzhead.name?0:8)+(!K.gzhead.comment?0:16)),C0(K,K.gzhead.time&255),C0(K,K.gzhead.time>>8&255),C0(K,K.gzhead.time>>16&255),C0(K,K.gzhead.time>>24&255),C0(K,K.level===9?2:K.strategy>=c8||K.level<2?4:0),C0(K,K.gzhead.os&255),K.gzhead.extra&&K.gzhead.extra.length)C0(K,K.gzhead.extra.length&255),C0(K,K.gzhead.extra.length>>8&255);if(K.gzhead.hcrc)$.adler=q1($.adler,K.pending_buf,K.pending,0);K.gzindex=0,K.status=X4}else{var G=m8+(K.w_bits-8<<4)<<8,W=-1;if(K.strategy>=c8||K.level<2)W=0;else if(K.level<6)W=1;else if(K.level===6)W=2;else W=3;if(G|=W<<6,K.strstart!==0)G|=WZ;if(G+=31-G%31,K.status=f1,l6(K,G),K.strstart!==0)l6(K,$.adler>>>16),l6(K,$.adler&65535);$.adler=1}if(K.status===X4)if(K.gzhead.extra){J=K.pending;while(K.gzindex<(K.gzhead.extra.length&65535)){if(K.pending===K.pending_buf_size){if(K.gzhead.hcrc&&K.pending>J)$.adler=q1($.adler,K.pending_buf,K.pending-J,J);if(K1($),J=K.pending,K.pending===K.pending_buf_size)break}C0(K,K.gzhead.extra[K.gzindex]&255),K.gzindex++}if(K.gzhead.hcrc&&K.pending>J)$.adler=q1($.adler,K.pending_buf,K.pending-J,J);if(K.gzindex===K.gzhead.extra.length)K.gzindex=0,K.status=b8}else K.status=b8;if(K.status===b8)if(K.gzhead.name){J=K.pending;do{if(K.pending===K.pending_buf_size){if(K.gzhead.hcrc&&K.pending>J)$.adler=q1($.adler,K.pending_buf,K.pending-J,J);if(K1($),J=K.pending,K.pending===K.pending_buf_size){Z=1;break}}if(K.gzindexJ)$.adler=q1($.adler,K.pending_buf,K.pending-J,J);if(Z===0)K.gzindex=0,K.status=n8}else K.status=n8;if(K.status===n8)if(K.gzhead.comment){J=K.pending;do{if(K.pending===K.pending_buf_size){if(K.gzhead.hcrc&&K.pending>J)$.adler=q1($.adler,K.pending_buf,K.pending-J,J);if(K1($),J=K.pending,K.pending===K.pending_buf_size){Z=1;break}}if(K.gzindexJ)$.adler=q1($.adler,K.pending_buf,K.pending-J,J);if(Z===0)K.status=d8}else K.status=d8;if(K.status===d8)if(K.gzhead.hcrc){if(K.pending+2>K.pending_buf_size)K1($);if(K.pending+2<=K.pending_buf_size)C0(K,$.adler&255),C0(K,$.adler>>8&255),$.adler=0,K.status=f1}else K.status=f1;if(K.pending!==0){if(K1($),$.avail_out===0)return K.last_flush=-1,x2}else if($.avail_in===0&&NQ(q)<=NQ(Q)&&q!==Z1)return U1($,j4);if(K.status===r6&&$.avail_in!==0)return U1($,j4);if($.avail_in!==0||K.lookahead!==0||q!==C1&&K.status!==r6){var B=K.strategy===c8?wZ(K,q):K.strategy===rU?MZ(K,q):V6[K.level].func(K,q);if(B===R1||B===U6)K.status=r6;if(B===c0||B===R1){if($.avail_out===0)K.last_flush=-1;return x2}if(B===s6){if(q===pU)M2._tr_align(K);else if(q!==MQ){if(M2._tr_stored_block(K,0,0,!1),q===iU){if(J1(K.head),K.lookahead===0)K.strstart=0,K.block_start=0,K.insert=0}}if(K1($),$.avail_out===0)return K.last_flush=-1,x2}}if(q!==Z1)return x2;if(K.wrap<=0)return wQ;if(K.wrap===2)C0(K,$.adler&255),C0(K,$.adler>>8&255),C0(K,$.adler>>16&255),C0(K,$.adler>>24&255),C0(K,$.total_in&255),C0(K,$.total_in>>8&255),C0(K,$.total_in>>16&255),C0(K,$.total_in>>24&255);else l6(K,$.adler>>>16),l6(K,$.adler&65535);if(K1($),K.wrap>0)K.wrap=-K.wrap;return K.pending!==0?x2:wQ}function HZ($){var q;if(!$||!$.state)return w2;if(q=$.state.status,q!==p8&&q!==X4&&q!==b8&&q!==n8&&q!==d8&&q!==f1&&q!==r6)return U1($,w2);return $.state=null,q===f1?U1($,oU):x2}function vZ($,q){var Q=q.length,K,J,Z,G,W,B,V,U;if(!$||!$.state)return w2;if(K=$.state,G=K.wrap,G===2||G===1&&K.status!==p8||K.lookahead)return w2;if(G===1)$.adler=YQ($.adler,q,Q,0);if(K.wrap=0,Q>=K.w_size){if(G===0)J1(K.head),K.strstart=0,K.block_start=0,K.insert=0;U=new r0.Buf8(K.w_size),r0.arraySet(U,q,Q-K.w_size,K.w_size,0),q=U,Q=K.w_size}W=$.avail_in,B=$.next_in,V=$.input,$.avail_in=Q,$.next_in=0,$.input=q,I1(K);while(K.lookahead>=f0){J=K.strstart,Z=K.lookahead-(f0-1);do K.ins_h=(K.ins_h<{var i8=d2(),fQ=!0,RQ=!0;try{String.fromCharCode.apply(null,[0])}catch($){fQ=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch($){RQ=!1}var t6=new i8.Buf8(256);for(P2=0;P2<256;P2++)t6[P2]=P2>=252?6:P2>=248?5:P2>=240?4:P2>=224?3:P2>=192?2:1;var P2;t6[254]=t6[254]=1;Z6.string2buf=function($){var q,Q,K,J,Z,G=$.length,W=0;for(J=0;J>>6,q[Z++]=128|Q&63;else if(Q<65536)q[Z++]=224|Q>>>12,q[Z++]=128|Q>>>6&63,q[Z++]=128|Q&63;else q[Z++]=240|Q>>>18,q[Z++]=128|Q>>>12&63,q[Z++]=128|Q>>>6&63,q[Z++]=128|Q&63}return q};function IQ($,q){if(q<65534){if($.subarray&&RQ||!$.subarray&&fQ)return String.fromCharCode.apply(null,i8.shrinkBuf($,q))}var Q="";for(var K=0;K4){W[K++]=65533,Q+=Z-1;continue}J&=Z===2?31:Z===3?15:7;while(Z>1&&Q1){W[K++]=65533;continue}if(J<65536)W[K++]=J;else J-=65536,W[K++]=55296|J>>10&1023,W[K++]=56320|J&1023}return IQ(W,K)};Z6.utf8border=function($,q){var Q;if(q=q||$.length,q>$.length)q=$.length;Q=q-1;while(Q>=0&&($[Q]&192)===128)Q--;if(Q<0)return q;if(Q===0)return q;return Q+t6[$[Q]]>q?Q:q}});var h4=N0((cz,CQ)=>{function fZ(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}CQ.exports=fZ});var XQ=N0((Q8)=>{var e6=vQ(),$8=d2(),O4=y4(),P4=_8(),RZ=h4(),AQ=Object.prototype.toString,IZ=0,x4=4,G6=0,jQ=1,gQ=2,CZ=-1,jZ=0,gZ=8;function j1($){if(!(this instanceof j1))return new j1($);this.options=$8.assign({level:CZ,method:gZ,chunkSize:16384,windowBits:15,memLevel:8,strategy:jZ,to:""},$||{});var q=this.options;if(q.raw&&q.windowBits>0)q.windowBits=-q.windowBits;else if(q.gzip&&q.windowBits>0&&q.windowBits<16)q.windowBits+=16;this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new RZ,this.strm.avail_out=0;var Q=e6.deflateInit2(this.strm,q.level,q.method,q.windowBits,q.memLevel,q.strategy);if(Q!==G6)throw Error(P4[Q]);if(q.header)e6.deflateSetHeader(this.strm,q.header);if(q.dictionary){var K;if(typeof q.dictionary==="string")K=O4.string2buf(q.dictionary);else if(AQ.call(q.dictionary)==="[object ArrayBuffer]")K=new Uint8Array(q.dictionary);else K=q.dictionary;if(Q=e6.deflateSetDictionary(this.strm,K),Q!==G6)throw Error(P4[Q]);this._dict_set=!0}}j1.prototype.push=function($,q){var Q=this.strm,K=this.options.chunkSize,J,Z;if(this.ended)return!1;if(Z=q===~~q?q:q===!0?x4:IZ,typeof $==="string")Q.input=O4.string2buf($);else if(AQ.call($)==="[object ArrayBuffer]")Q.input=new Uint8Array($);else Q.input=$;Q.next_in=0,Q.avail_in=Q.input.length;do{if(Q.avail_out===0)Q.output=new $8.Buf8(K),Q.next_out=0,Q.avail_out=K;if(J=e6.deflate(Q,Z),J!==jQ&&J!==G6)return this.onEnd(J),this.ended=!0,!1;if(Q.avail_out===0||Q.avail_in===0&&(Z===x4||Z===gQ))if(this.options.to==="string")this.onData(O4.buf2binstring($8.shrinkBuf(Q.output,Q.next_out)));else this.onData($8.shrinkBuf(Q.output,Q.next_out))}while((Q.avail_in>0||Q.avail_out===0)&&J!==jQ);if(Z===x4)return J=e6.deflateEnd(this.strm),this.onEnd(J),this.ended=!0,J===G6;if(Z===gQ)return this.onEnd(G6),Q.avail_out=0,!0;return!0};j1.prototype.onData=function($){this.chunks.push($)};j1.prototype.onEnd=function($){if($===G6)if(this.options.to==="string")this.result=this.chunks.join("");else this.result=$8.flattenChunks(this.chunks);this.chunks=[],this.err=$,this.msg=this.strm.msg};function T4($,q){var Q=new j1(q);if(Q.push($,!0),Q.err)throw Q.msg||P4[Q.err];return Q.result}function AZ($,q){return q=q||{},q.raw=!0,T4($,q)}function XZ($,q){return q=q||{},q.gzip=!0,T4($,q)}Q8.Deflate=j1;Q8.deflate=T4;Q8.deflateRaw=AZ;Q8.gzip=XZ});var hQ=N0((nz,yQ)=>{var o8=30,yZ=12;yQ.exports=function(q,Q){var K,J,Z,G,W,B,V,U,w,F,M,k,f,L,D,z,N,H,v,j,n,d,_,X,P;K=q.state,J=q.next_in,X=q.input,Z=J+(q.avail_in-5),G=q.next_out,P=q.output,W=G-(Q-q.avail_out),B=G+(q.avail_out-257),V=K.dmax,U=K.wsize,w=K.whave,F=K.wnext,M=K.window,k=K.hold,f=K.bits,L=K.lencode,D=K.distcode,z=(1<>>24,k>>>=v,f-=v,v=H>>>16&255,v===0)P[G++]=H&65535;else if(v&16){if(j=H&65535,v&=15,v){if(f>>=v,f-=v}if(f<15)k+=X[J++]<>>24,k>>>=v,f-=v,v=H>>>16&255,v&16){if(n=H&65535,v&=15,fV){q.msg="invalid distance too far back",K.mode=o8;break $}if(k>>>=v,f-=v,v=G-W,n>v){if(v=n-v,v>w){if(K.sane){q.msg="invalid distance too far back",K.mode=o8;break $}}if(d=0,_=M,F===0){if(d+=U-v,v2)P[G++]=_[d++],P[G++]=_[d++],P[G++]=_[d++],j-=3;if(j){if(P[G++]=_[d++],j>1)P[G++]=_[d++]}}else{d=G-n;do P[G++]=P[d++],P[G++]=P[d++],P[G++]=P[d++],j-=3;while(j>2);if(j){if(P[G++]=P[d++],j>1)P[G++]=P[d++]}}}else if((v&64)===0){H=D[(H&65535)+(k&(1<>3,J-=j,f-=j<<3,k&=(1<{var xQ=d2(),W6=15,OQ=852,PQ=592,TQ=0,u4=1,uQ=2,hZ=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],xZ=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],OZ=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],PZ=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];SQ.exports=function(q,Q,K,J,Z,G,W,B){var V=B.bits,U=0,w=0,F=0,M=0,k=0,f=0,L=0,D=0,z=0,N=0,H,v,j,n,d,_=null,X=0,P,g=new xQ.Buf16(W6+1),c=new xQ.Buf16(W6+1),h=null,x=0,l,$0,Z0;for(U=0;U<=W6;U++)g[U]=0;for(w=0;w=1;M--)if(g[M]!==0)break;if(k>M)k=M;if(M===0)return Z[G++]=20971520,Z[G++]=20971520,B.bits=1,0;for(F=1;F0&&(q===TQ||M!==1))return-1;c[1]=0;for(U=1;UOQ||q===uQ&&z>PQ)return 1;for(;;){if(l=U-L,W[w]P)$0=h[x+W[w]],Z0=_[X+W[w]];else $0=96,Z0=0;H=1<>L)+v]=l<<24|$0<<16|Z0|0;while(v!==0);H=1<>=1;if(H!==0)N&=H-1,N+=H;else N=0;if(w++,--g[U]===0){if(U===M)break;U=Q[K+W[w]]}if(U>k&&(N&n)!==j){if(L===0)L=k;d+=F,f=U-L,D=1<OQ||q===uQ&&z>PQ)return 1;j=N&n,Z[j]=k<<24|f<<16|d-G|0}}if(N!==0)Z[d+N]=U-L<<24|4194304|0;return B.bits=k,0}});var Lq=N0((H2)=>{var U2=d2(),n4=I4(),T2=C4(),TZ=hQ(),q8=EQ(),uZ=0,Bq=1,zq=2,_Q=4,SZ=5,a8=6,g1=0,EZ=1,_Z=2,N2=-2,Fq=-3,d4=-4,cZ=-5,cQ=8,Mq=1,bQ=2,nQ=3,dQ=4,mQ=5,pQ=6,iQ=7,oQ=8,aQ=9,lQ=10,s8=11,p2=12,S4=13,rQ=14,E4=15,sQ=16,tQ=17,eQ=18,$q=19,l8=20,r8=21,Qq=22,qq=23,Kq=24,Jq=25,Vq=26,_4=27,Uq=28,Zq=29,x0=30,m4=31,bZ=32,nZ=852,dZ=592,mZ=15,pZ=mZ;function Gq($){return($>>>24&255)+($>>>8&65280)+(($&65280)<<8)+(($&255)<<24)}function iZ(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new U2.Buf16(320),this.work=new U2.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function wq($){var q;if(!$||!$.state)return N2;if(q=$.state,$.total_in=$.total_out=q.total=0,$.msg="",q.wrap)$.adler=q.wrap&1;return q.mode=Mq,q.last=0,q.havedict=0,q.dmax=32768,q.head=null,q.hold=0,q.bits=0,q.lencode=q.lendyn=new U2.Buf32(nZ),q.distcode=q.distdyn=new U2.Buf32(dZ),q.sane=1,q.back=-1,g1}function Nq($){var q;if(!$||!$.state)return N2;return q=$.state,q.wsize=0,q.whave=0,q.wnext=0,wq($)}function Yq($,q){var Q,K;if(!$||!$.state)return N2;if(K=$.state,q<0)Q=0,q=-q;else if(Q=(q>>4)+1,q<48)q&=15;if(q&&(q<8||q>15))return N2;if(K.window!==null&&K.wbits!==q)K.window=null;return K.wrap=Q,K.wbits=q,Nq($)}function kq($,q){var Q,K;if(!$)return N2;if(K=new iZ,$.state=K,K.window=null,Q=Yq($,q),Q!==g1)$.state=null;return Q}function oZ($){return kq($,pZ)}var Wq=!0,c4,b4;function aZ($){if(Wq){var q;c4=new U2.Buf32(512),b4=new U2.Buf32(32),q=0;while(q<144)$.lens[q++]=8;while(q<256)$.lens[q++]=9;while(q<280)$.lens[q++]=7;while(q<288)$.lens[q++]=8;q8(Bq,$.lens,0,288,c4,0,$.work,{bits:9}),q=0;while(q<32)$.lens[q++]=5;q8(zq,$.lens,0,32,b4,0,$.work,{bits:5}),Wq=!1}$.lencode=c4,$.lenbits=9,$.distcode=b4,$.distbits=5}function Dq($,q,Q,K){var J,Z=$.state;if(Z.window===null)Z.wsize=1<=Z.wsize)U2.arraySet(Z.window,q,Q-Z.wsize,Z.wsize,0),Z.wnext=0,Z.whave=Z.wsize;else{if(J=Z.wsize-Z.wnext,J>K)J=K;if(U2.arraySet(Z.window,q,Q-K,J,Z.wnext),K-=J,K)U2.arraySet(Z.window,q,Q-K,K,0),Z.wnext=K,Z.whave=Z.wsize;else{if(Z.wnext+=J,Z.wnext===Z.wsize)Z.wnext=0;if(Z.whave>>8&255,Q.check=T2(Q.check,_,2,0),V=0,U=0,Q.mode=bQ;break}if(Q.flags=0,Q.head)Q.head.done=!1;if(!(Q.wrap&1)||(((V&255)<<8)+(V>>8))%31){$.msg="incorrect header check",Q.mode=x0;break}if((V&15)!==cQ){$.msg="unknown compression method",Q.mode=x0;break}if(V>>>=4,U-=4,n=(V&15)+8,Q.wbits===0)Q.wbits=n;else if(n>Q.wbits){$.msg="invalid window size",Q.mode=x0;break}Q.dmax=1<>8&1;if(Q.flags&512)_[0]=V&255,_[1]=V>>>8&255,Q.check=T2(Q.check,_,2,0);V=0,U=0,Q.mode=nQ;case nQ:while(U<32){if(W===0)break $;W--,V+=K[Z++]<>>8&255,_[2]=V>>>16&255,_[3]=V>>>24&255,Q.check=T2(Q.check,_,4,0);V=0,U=0,Q.mode=dQ;case dQ:while(U<16){if(W===0)break $;W--,V+=K[Z++]<>8;if(Q.flags&512)_[0]=V&255,_[1]=V>>>8&255,Q.check=T2(Q.check,_,2,0);V=0,U=0,Q.mode=mQ;case mQ:if(Q.flags&1024){while(U<16){if(W===0)break $;W--,V+=K[Z++]<>>8&255,Q.check=T2(Q.check,_,2,0);V=0,U=0}else if(Q.head)Q.head.extra=null;Q.mode=pQ;case pQ:if(Q.flags&1024){if(M=Q.length,M>W)M=W;if(M){if(Q.head){if(n=Q.head.extra_len-Q.length,!Q.head.extra)Q.head.extra=Array(Q.head.extra_len);U2.arraySet(Q.head.extra,K,Z,M,n)}if(Q.flags&512)Q.check=T2(Q.check,K,M,Z);W-=M,Z+=M,Q.length-=M}if(Q.length)break $}Q.length=0,Q.mode=iQ;case iQ:if(Q.flags&2048){if(W===0)break $;M=0;do if(n=K[Z+M++],Q.head&&n&&Q.length<65536)Q.head.name+=String.fromCharCode(n);while(n&&M>9&1,Q.head.done=!0;$.adler=Q.check=0,Q.mode=p2;break;case lQ:while(U<32){if(W===0)break $;W--,V+=K[Z++]<>>=U&7,U-=U&7,Q.mode=_4;break}while(U<3){if(W===0)break $;W--,V+=K[Z++]<>>=1,U-=1,V&3){case 0:Q.mode=rQ;break;case 1:if(aZ(Q),Q.mode=l8,q===a8){V>>>=2,U-=2;break $}break;case 2:Q.mode=tQ;break;case 3:$.msg="invalid block type",Q.mode=x0}V>>>=2,U-=2;break;case rQ:V>>>=U&7,U-=U&7;while(U<32){if(W===0)break $;W--,V+=K[Z++]<>>16^65535)){$.msg="invalid stored block lengths",Q.mode=x0;break}if(Q.length=V&65535,V=0,U=0,Q.mode=E4,q===a8)break $;case E4:Q.mode=sQ;case sQ:if(M=Q.length,M){if(M>W)M=W;if(M>B)M=B;if(M===0)break $;U2.arraySet(J,K,Z,M,G),W-=M,Z+=M,B-=M,G+=M,Q.length-=M;break}Q.mode=p2;break;case tQ:while(U<14){if(W===0)break $;W--,V+=K[Z++]<>>=5,U-=5,Q.ndist=(V&31)+1,V>>>=5,U-=5,Q.ncode=(V&15)+4,V>>>=4,U-=4,Q.nlen>286||Q.ndist>30){$.msg="too many length or distance symbols",Q.mode=x0;break}Q.have=0,Q.mode=eQ;case eQ:while(Q.have>>=3,U-=3}while(Q.have<19)Q.lens[g[Q.have++]]=0;if(Q.lencode=Q.lendyn,Q.lenbits=7,X={bits:Q.lenbits},d=q8(uZ,Q.lens,0,19,Q.lencode,0,Q.work,X),Q.lenbits=X.bits,d){$.msg="invalid code lengths set",Q.mode=x0;break}Q.have=0,Q.mode=$q;case $q:while(Q.have>>24,z=L>>>16&255,N=L&65535,D<=U)break;if(W===0)break $;W--,V+=K[Z++]<>>=D,U-=D,Q.lens[Q.have++]=N;else{if(N===16){P=D+2;while(U>>=D,U-=D,Q.have===0){$.msg="invalid bit length repeat",Q.mode=x0;break}n=Q.lens[Q.have-1],M=3+(V&3),V>>>=2,U-=2}else if(N===17){P=D+3;while(U>>=D,U-=D,n=0,M=3+(V&7),V>>>=3,U-=3}else{P=D+7;while(U>>=D,U-=D,n=0,M=11+(V&127),V>>>=7,U-=7}if(Q.have+M>Q.nlen+Q.ndist){$.msg="invalid bit length repeat",Q.mode=x0;break}while(M--)Q.lens[Q.have++]=n}}if(Q.mode===x0)break;if(Q.lens[256]===0){$.msg="invalid code -- missing end-of-block",Q.mode=x0;break}if(Q.lenbits=9,X={bits:Q.lenbits},d=q8(Bq,Q.lens,0,Q.nlen,Q.lencode,0,Q.work,X),Q.lenbits=X.bits,d){$.msg="invalid literal/lengths set",Q.mode=x0;break}if(Q.distbits=6,Q.distcode=Q.distdyn,X={bits:Q.distbits},d=q8(zq,Q.lens,Q.nlen,Q.ndist,Q.distcode,0,Q.work,X),Q.distbits=X.bits,d){$.msg="invalid distances set",Q.mode=x0;break}if(Q.mode=l8,q===a8)break $;case l8:Q.mode=r8;case r8:if(W>=6&&B>=258){if($.next_out=G,$.avail_out=B,$.next_in=Z,$.avail_in=W,Q.hold=V,Q.bits=U,TZ($,F),G=$.next_out,J=$.output,B=$.avail_out,Z=$.next_in,K=$.input,W=$.avail_in,V=Q.hold,U=Q.bits,Q.mode===p2)Q.back=-1;break}Q.back=0;for(;;){if(L=Q.lencode[V&(1<>>24,z=L>>>16&255,N=L&65535,D<=U)break;if(W===0)break $;W--,V+=K[Z++]<>H)],D=L>>>24,z=L>>>16&255,N=L&65535,H+D<=U)break;if(W===0)break $;W--,V+=K[Z++]<>>=H,U-=H,Q.back+=H}if(V>>>=D,U-=D,Q.back+=D,Q.length=N,z===0){Q.mode=Vq;break}if(z&32){Q.back=-1,Q.mode=p2;break}if(z&64){$.msg="invalid literal/length code",Q.mode=x0;break}Q.extra=z&15,Q.mode=Qq;case Qq:if(Q.extra){P=Q.extra;while(U>>=Q.extra,U-=Q.extra,Q.back+=Q.extra}Q.was=Q.length,Q.mode=qq;case qq:for(;;){if(L=Q.distcode[V&(1<>>24,z=L>>>16&255,N=L&65535,D<=U)break;if(W===0)break $;W--,V+=K[Z++]<>H)],D=L>>>24,z=L>>>16&255,N=L&65535,H+D<=U)break;if(W===0)break $;W--,V+=K[Z++]<>>=H,U-=H,Q.back+=H}if(V>>>=D,U-=D,Q.back+=D,z&64){$.msg="invalid distance code",Q.mode=x0;break}Q.offset=N,Q.extra=z&15,Q.mode=Kq;case Kq:if(Q.extra){P=Q.extra;while(U>>=Q.extra,U-=Q.extra,Q.back+=Q.extra}if(Q.offset>Q.dmax){$.msg="invalid distance too far back",Q.mode=x0;break}Q.mode=Jq;case Jq:if(B===0)break $;if(M=F-B,Q.offset>M){if(M=Q.offset-M,M>Q.whave){if(Q.sane){$.msg="invalid distance too far back",Q.mode=x0;break}}if(M>Q.wnext)M-=Q.wnext,k=Q.wsize-M;else k=Q.wnext-M;if(M>Q.length)M=Q.length;f=Q.window}else f=J,k=G-Q.offset,M=Q.length;if(M>B)M=B;B-=M,Q.length-=M;do J[G++]=f[k++];while(--M);if(Q.length===0)Q.mode=r8;break;case Vq:if(B===0)break $;J[G++]=Q.length,B--,Q.mode=r8;break;case _4:if(Q.wrap){while(U<32){if(W===0)break $;W--,V|=K[Z++]<{Hq.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}});var fq=N0((iz,vq)=>{function eZ(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}vq.exports=eZ});var Iq=N0((J8)=>{var B6=Lq(),K8=d2(),t8=y4(),E0=p4(),i4=_8(),$G=h4(),QG=fq(),Rq=Object.prototype.toString;function A1($){if(!(this instanceof A1))return new A1($);this.options=K8.assign({chunkSize:16384,windowBits:0,to:""},$||{});var q=this.options;if(q.raw&&q.windowBits>=0&&q.windowBits<16){if(q.windowBits=-q.windowBits,q.windowBits===0)q.windowBits=-15}if(q.windowBits>=0&&q.windowBits<16&&!($&&$.windowBits))q.windowBits+=32;if(q.windowBits>15&&q.windowBits<48){if((q.windowBits&15)===0)q.windowBits|=15}this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new $G,this.strm.avail_out=0;var Q=B6.inflateInit2(this.strm,q.windowBits);if(Q!==E0.Z_OK)throw Error(i4[Q]);if(this.header=new QG,B6.inflateGetHeader(this.strm,this.header),q.dictionary){if(typeof q.dictionary==="string")q.dictionary=t8.string2buf(q.dictionary);else if(Rq.call(q.dictionary)==="[object ArrayBuffer]")q.dictionary=new Uint8Array(q.dictionary);if(q.raw){if(Q=B6.inflateSetDictionary(this.strm,q.dictionary),Q!==E0.Z_OK)throw Error(i4[Q])}}}A1.prototype.push=function($,q){var Q=this.strm,K=this.options.chunkSize,J=this.options.dictionary,Z,G,W,B,V,U=!1;if(this.ended)return!1;if(G=q===~~q?q:q===!0?E0.Z_FINISH:E0.Z_NO_FLUSH,typeof $==="string")Q.input=t8.binstring2buf($);else if(Rq.call($)==="[object ArrayBuffer]")Q.input=new Uint8Array($);else Q.input=$;Q.next_in=0,Q.avail_in=Q.input.length;do{if(Q.avail_out===0)Q.output=new K8.Buf8(K),Q.next_out=0,Q.avail_out=K;if(Z=B6.inflate(Q,E0.Z_NO_FLUSH),Z===E0.Z_NEED_DICT&&J)Z=B6.inflateSetDictionary(this.strm,J);if(Z===E0.Z_BUF_ERROR&&U===!0)Z=E0.Z_OK,U=!1;if(Z!==E0.Z_STREAM_END&&Z!==E0.Z_OK)return this.onEnd(Z),this.ended=!0,!1;if(Q.next_out){if(Q.avail_out===0||Z===E0.Z_STREAM_END||Q.avail_in===0&&(G===E0.Z_FINISH||G===E0.Z_SYNC_FLUSH))if(this.options.to==="string"){if(W=t8.utf8border(Q.output,Q.next_out),B=Q.next_out-W,V=t8.buf2string(Q.output,W),Q.next_out=B,Q.avail_out=K-B,B)K8.arraySet(Q.output,Q.output,W,B,0);this.onData(V)}else this.onData(K8.shrinkBuf(Q.output,Q.next_out))}if(Q.avail_in===0&&Q.avail_out===0)U=!0}while((Q.avail_in>0||Q.avail_out===0)&&Z!==E0.Z_STREAM_END);if(Z===E0.Z_STREAM_END)G=E0.Z_FINISH;if(G===E0.Z_FINISH)return Z=B6.inflateEnd(this.strm),this.onEnd(Z),this.ended=!0,Z===E0.Z_OK;if(G===E0.Z_SYNC_FLUSH)return this.onEnd(E0.Z_OK),Q.avail_out=0,!0;return!0};A1.prototype.onData=function($){this.chunks.push($)};A1.prototype.onEnd=function($){if($===E0.Z_OK)if(this.options.to==="string")this.result=this.chunks.join("");else this.result=K8.flattenChunks(this.chunks);this.chunks=[],this.err=$,this.msg=this.strm.msg};function o4($,q){var Q=new A1(q);if(Q.push($,!0),Q.err)throw Q.msg||i4[Q.err];return Q.result}function qG($,q){return q=q||{},q.raw=!0,o4($,q)}J8.Inflate=A1;J8.inflate=o4;J8.inflateRaw=qG;J8.ungzip=o4});var gq=N0((az,jq)=>{var KG=d2().assign,JG=XQ(),VG=Iq(),UG=p4(),Cq={};KG(Cq,JG,VG,UG);jq.exports=Cq});var Xq=N0(($5)=>{var ZG=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Uint32Array<"u",GG=gq(),Aq=T0(),e8=V2(),WG=ZG?"uint8array":"array";$5.magic="\b\x00";function X1($,q){e8.call(this,"FlateWorker/"+$),this._pako=null,this._pakoAction=$,this._pakoOptions=q,this.meta={}}Aq.inherits(X1,e8);X1.prototype.processChunk=function($){if(this.meta=$.meta,this._pako===null)this._createPako();this._pako.push(Aq.transformTo(WG,$.data),!1)};X1.prototype.flush=function(){if(e8.prototype.flush.call(this),this._pako===null)this._createPako();this._pako.push([],!0)};X1.prototype.cleanUp=function(){e8.prototype.cleanUp.call(this),this._pako=null};X1.prototype._createPako=function(){this._pako=new GG[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var $=this;this._pako.onData=function(q){$.push({data:q,meta:$.meta})}};$5.compressWorker=function($){return new X1("Deflate",$)};$5.uncompressWorker=function(){return new X1("Inflate",{})}});var l4=N0((a4)=>{var yq=V2();a4.STORE={magic:"\x00\x00",compressWorker:function(){return new yq("STORE compression")},uncompressWorker:function(){return new yq("STORE decompression")}};a4.DEFLATE=Xq()});var r4=N0((y1)=>{y1.LOCAL_FILE_HEADER="PK\x03\x04";y1.CENTRAL_FILE_HEADER="PK\x01\x02";y1.CENTRAL_DIRECTORY_END="PK\x05\x06";y1.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK\x06\x07";y1.ZIP64_CENTRAL_DIRECTORY_END="PK\x06\x06";y1.DATA_DESCRIPTOR="PK\x07\b"});var Pq=N0((tz,Oq)=>{var z6=T0(),F6=V2(),s4=e1(),hq=T8(),Q5=r4(),A0=function($,q){var Q="",K;for(K=0;K>>8;return Q},BG=function($,q){var Q=$;if(!$)Q=q?16893:33204;return(Q&65535)<<16},zG=function($){return($||0)&63},xq=function($,q,Q,K,J,Z){var{file:G,compression:W}=$,B=Z!==s4.utf8encode,V=z6.transformTo("string",Z(G.name)),U=z6.transformTo("string",s4.utf8encode(G.name)),w=G.comment,F=z6.transformTo("string",Z(w)),M=z6.transformTo("string",s4.utf8encode(w)),k=U.length!==G.name.length,f=M.length!==w.length,L,D,z="",N="",H="",v=G.dir,j=G.date,n={crc32:0,compressedSize:0,uncompressedSize:0};if(!q||Q)n.crc32=$.crc32,n.compressedSize=$.compressedSize,n.uncompressedSize=$.uncompressedSize;var d=0;if(q)d|=8;if(!B&&(k||f))d|=2048;var _=0,X=0;if(v)_|=16;if(J==="UNIX")X=798,_|=BG(G.unixPermissions,v);else X=20,_|=zG(G.dosPermissions,v);if(L=j.getUTCHours(),L=L<<6,L=L|j.getUTCMinutes(),L=L<<5,L=L|j.getUTCSeconds()/2,D=j.getUTCFullYear()-1980,D=D<<4,D=D|j.getUTCMonth()+1,D=D<<5,D=D|j.getUTCDate(),k)N=A0(1,1)+A0(hq(V),4)+U,z+="up"+A0(N.length,2)+N;if(f)H=A0(1,1)+A0(hq(F),4)+M,z+="uc"+A0(H.length,2)+H;var P="";P+=` -\x00`,P+=A0(d,2),P+=W.magic,P+=A0(L,2),P+=A0(D,2),P+=A0(n.crc32,4),P+=A0(n.compressedSize,4),P+=A0(n.uncompressedSize,4),P+=A0(V.length,2),P+=A0(z.length,2);var g=Q5.LOCAL_FILE_HEADER+P+V+z,c=Q5.CENTRAL_FILE_HEADER+A0(X,2)+P+A0(F.length,2)+"\x00\x00\x00\x00"+A0(_,4)+A0(K,4)+V+z+F;return{fileRecord:g,dirRecord:c}},FG=function($,q,Q,K,J){var Z="",G=z6.transformTo("string",J(K));return Z=Q5.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+A0($,2)+A0($,2)+A0(q,4)+A0(Q,4)+A0(G.length,2)+G,Z},MG=function($){var q="";return q=Q5.DATA_DESCRIPTOR+A0($.crc32,4)+A0($.compressedSize,4)+A0($.uncompressedSize,4),q};function v2($,q,Q,K){F6.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=q,this.zipPlatform=Q,this.encodeFileName=K,this.streamFiles=$,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}z6.inherits(v2,F6);v2.prototype.push=function($){var q=$.meta.percent||0,Q=this.entriesCount,K=this._sources.length;if(this.accumulate)this.contentBuffer.push($);else this.bytesWritten+=$.data.length,F6.prototype.push.call(this,{data:$.data,meta:{currentFile:this.currentFile,percent:Q?(q+100*(Q-K-1))/Q:100}})};v2.prototype.openedSource=function($){this.currentSourceOffset=this.bytesWritten,this.currentFile=$.file.name;var q=this.streamFiles&&!$.file.dir;if(q){var Q=xq($,q,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:Q.fileRecord,meta:{percent:0}})}else this.accumulate=!0};v2.prototype.closedSource=function($){this.accumulate=!1;var q=this.streamFiles&&!$.file.dir,Q=xq($,q,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(Q.dirRecord),q)this.push({data:MG($),meta:{percent:100}});else{this.push({data:Q.fileRecord,meta:{percent:0}});while(this.contentBuffer.length)this.push(this.contentBuffer.shift())}this.currentFile=null};v2.prototype.flush=function(){var $=this.bytesWritten;for(var q=0;q{var wG=l4(),NG=Pq(),YG=function($,q){var Q=$||q,K=wG[Q];if(!K)throw Error(Q+" is not a valid compression method !");return K};Tq.generateWorker=function($,q,Q){var K=new NG(q.streamFiles,Q,q.platform,q.encodeFileName),J=0;try{$.forEach(function(Z,G){J++;var W=YG(G.options.compression,q.compression),B=G.options.compressionOptions||q.compressionOptions||{},V=G.dir,U=G.date;G._compressWorker(W,B).withStreamInfo("file",{name:Z,dir:V,date:U,comment:G.comment||"",unixPermissions:G.unixPermissions,dosPermissions:G.dosPermissions}).pipe(K)}),K.entriesCount=J}catch(Z){K.error(Z)}return K}});var Eq=N0(($F,Sq)=>{var kG=T0(),q5=V2();function V8($,q){q5.call(this,"Nodejs stream input adapter for "+$),this._upstreamEnded=!1,this._bindStream(q)}kG.inherits(V8,q5);V8.prototype._bindStream=function($){var q=this;this._stream=$,$.pause(),$.on("data",function(Q){q.push({data:Q,meta:{percent:0}})}).on("error",function(Q){if(q.isPaused)this.generatedError=Q;else q.error(Q)}).on("end",function(){if(q.isPaused)q._upstreamEnded=!0;else q.end()})};V8.prototype.pause=function(){if(!q5.prototype.pause.call(this))return!1;return this._stream.pause(),!0};V8.prototype.resume=function(){if(!q5.prototype.resume.call(this))return!1;if(this._upstreamEnded)this.end();else this._stream.resume();return!0};Sq.exports=V8});var aq=N0((QF,oq)=>{var DG=e1(),U8=T0(),nq=V2(),LG=q4(),dq=K4(),_q=u8(),HG=c$(),vG=uq(),cq=T6(),fG=Eq(),mq=function($,q,Q){var K=U8.getTypeOf(q),J,Z=U8.extend(Q||{},dq);if(Z.date=Z.date||new Date,Z.compression!==null)Z.compression=Z.compression.toUpperCase();if(typeof Z.unixPermissions==="string")Z.unixPermissions=parseInt(Z.unixPermissions,8);if(Z.unixPermissions&&Z.unixPermissions&16384)Z.dir=!0;if(Z.dosPermissions&&Z.dosPermissions&16)Z.dir=!0;if(Z.dir)$=pq($);if(Z.createFolders&&(J=RG($)))iq.call(this,J,!0);var G=K==="string"&&Z.binary===!1&&Z.base64===!1;if(!Q||typeof Q.binary>"u")Z.binary=!G;var W=q instanceof _q&&q.uncompressedSize===0;if(W||Z.dir||!q||q.length===0)Z.base64=!1,Z.binary=!0,q="",Z.compression="STORE",K="string";var B=null;if(q instanceof _q||q instanceof nq)B=q;else if(cq.isNode&&cq.isStream(q))B=new fG($,q);else B=U8.prepareContent($,q,Z.binary,Z.optimizedBinaryString,Z.base64);var V=new HG($,B,Z);this.files[$]=V},RG=function($){if($.slice(-1)==="/")$=$.substring(0,$.length-1);var q=$.lastIndexOf("/");return q>0?$.substring(0,q):""},pq=function($){if($.slice(-1)!=="/")$+="/";return $},iq=function($,q){if(q=typeof q<"u"?q:dq.createFolders,$=pq($),!this.files[$])mq.call(this,$,null,{dir:!0,createFolders:q});return this.files[$]};function bq($){return Object.prototype.toString.call($)==="[object RegExp]"}var IG={load:function(){throw Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},forEach:function($){var q,Q,K;for(q in this.files)if(K=this.files[q],Q=q.slice(this.root.length,q.length),Q&&q.slice(0,this.root.length)===this.root)$(Q,K)},filter:function($){var q=[];return this.forEach(function(Q,K){if($(Q,K))q.push(K)}),q},file:function($,q,Q){if(arguments.length===1)if(bq($)){var K=$;return this.filter(function(Z,G){return!G.dir&&K.test(Z)})}else{var J=this.files[this.root+$];if(J&&!J.dir)return J;else return null}else $=this.root+$,mq.call(this,$,q,Q);return this},folder:function($){if(!$)return this;if(bq($))return this.filter(function(J,Z){return Z.dir&&$.test(J)});var q=this.root+$,Q=iq.call(this,q),K=this.clone();return K.root=Q.name,K},remove:function($){$=this.root+$;var q=this.files[$];if(!q){if($.slice(-1)!=="/")$+="/";q=this.files[$]}if(q&&!q.dir)delete this.files[$];else{var Q=this.filter(function(J,Z){return Z.name.slice(0,$.length)===$});for(var K=0;K{var CG=T0();function lq($){this.data=$,this.length=$.length,this.index=0,this.zero=0}lq.prototype={checkOffset:function($){this.checkIndex(this.index+$)},checkIndex:function($){if(this.length=this.index;Q--)q=(q<<8)+this.byteAt(Q);return this.index+=$,q},readString:function($){return CG.transformTo("string",this.readData($))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var $=this.readInt(4);return new Date(Date.UTC(($>>25&127)+1980,($>>21&15)-1,$>>16&31,$>>11&31,$>>5&63,($&31)<<1))}};rq.exports=lq});var e4=N0((KF,tq)=>{var sq=t4(),jG=T0();function M6($){sq.call(this,$);for(var q=0;q=0;--Z)if(this.data[Z]===q&&this.data[Z+1]===Q&&this.data[Z+2]===K&&this.data[Z+3]===J)return Z-this.zero;return-1};M6.prototype.readAndCheckSignature=function($){var q=$.charCodeAt(0),Q=$.charCodeAt(1),K=$.charCodeAt(2),J=$.charCodeAt(3),Z=this.readData(4);return q===Z[0]&&Q===Z[1]&&K===Z[2]&&J===Z[3]};M6.prototype.readData=function($){if(this.checkOffset($),$===0)return[];var q=this.data.slice(this.zero+this.index,this.zero+this.index+$);return this.index+=$,q};tq.exports=M6});var QK=N0((JF,$K)=>{var eq=t4(),gG=T0();function w6($){eq.call(this,$)}gG.inherits(w6,eq);w6.prototype.byteAt=function($){return this.data.charCodeAt(this.zero+$)};w6.prototype.lastIndexOfSignature=function($){return this.data.lastIndexOf($)-this.zero};w6.prototype.readAndCheckSignature=function($){var q=this.readData(4);return $===q};w6.prototype.readData=function($){this.checkOffset($);var q=this.data.slice(this.zero+this.index,this.zero+this.index+$);return this.index+=$,q};$K.exports=w6});var Q7=N0((VF,KK)=>{var qK=e4(),AG=T0();function $7($){qK.call(this,$)}AG.inherits($7,qK);$7.prototype.readData=function($){if(this.checkOffset($),$===0)return new Uint8Array(0);var q=this.data.subarray(this.zero+this.index,this.zero+this.index+$);return this.index+=$,q};KK.exports=$7});var UK=N0((UF,VK)=>{var JK=Q7(),XG=T0();function q7($){JK.call(this,$)}XG.inherits(q7,JK);q7.prototype.readData=function($){this.checkOffset($);var q=this.data.slice(this.zero+this.index,this.zero+this.index+$);return this.index+=$,q};VK.exports=q7});var K7=N0((ZF,GK)=>{var K5=T0(),ZK=n2(),yG=e4(),hG=QK(),xG=UK(),OG=Q7();GK.exports=function($){var q=K5.getTypeOf($);if(K5.checkSupport(q),q==="string"&&!ZK.uint8array)return new hG($);if(q==="nodebuffer")return new xG($);if(ZK.uint8array)return new OG(K5.transformTo("uint8array",$));return new yG(K5.transformTo("array",$))}});var FK=N0((GF,zK)=>{var J7=K7(),G1=T0(),PG=u8(),WK=T8(),J5=e1(),V5=l4(),TG=n2(),uG=0,SG=3,EG=function($){for(var q in V5){if(!Object.prototype.hasOwnProperty.call(V5,q))continue;if(V5[q].magic===$)return V5[q]}return null};function BK($,q){this.options=$,this.loadOptions=q}BK.prototype={isEncrypted:function(){return(this.bitFlag&1)===1},useUTF8:function(){return(this.bitFlag&2048)===2048},readLocalPart:function($){var q,Q;if($.skip(22),this.fileNameLength=$.readInt(2),Q=$.readInt(2),this.fileName=$.readData(this.fileNameLength),$.skip(Q),this.compressedSize===-1||this.uncompressedSize===-1)throw Error("Bug or corrupted zip : didn't get enough information from the central directory (compressedSize === -1 || uncompressedSize === -1)");if(q=EG(this.compressionMethod),q===null)throw Error("Corrupted zip : compression "+G1.pretty(this.compressionMethod)+" unknown (inner file : "+G1.transformTo("string",this.fileName)+")");this.decompressed=new PG(this.compressedSize,this.uncompressedSize,this.crc32,q,$.readData(this.compressedSize))},readCentralPart:function($){this.versionMadeBy=$.readInt(2),$.skip(2),this.bitFlag=$.readInt(2),this.compressionMethod=$.readString(2),this.date=$.readDate(),this.crc32=$.readInt(4),this.compressedSize=$.readInt(4),this.uncompressedSize=$.readInt(4);var q=$.readInt(2);if(this.extraFieldsLength=$.readInt(2),this.fileCommentLength=$.readInt(2),this.diskNumberStart=$.readInt(2),this.internalFileAttributes=$.readInt(2),this.externalFileAttributes=$.readInt(4),this.localHeaderOffset=$.readInt(4),this.isEncrypted())throw Error("Encrypted zip are not supported");$.skip(q),this.readExtraFields($),this.parseZIP64ExtraField($),this.fileComment=$.readData(this.fileCommentLength)},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var $=this.versionMadeBy>>8;if(this.dir=this.externalFileAttributes&16?!0:!1,$===uG)this.dosPermissions=this.externalFileAttributes&63;if($===SG)this.unixPermissions=this.externalFileAttributes>>16&65535;if(!this.dir&&this.fileNameStr.slice(-1)==="/")this.dir=!0},parseZIP64ExtraField:function(){if(!this.extraFields[1])return;var $=J7(this.extraFields[1].value);if(this.uncompressedSize===G1.MAX_VALUE_32BITS)this.uncompressedSize=$.readInt(8);if(this.compressedSize===G1.MAX_VALUE_32BITS)this.compressedSize=$.readInt(8);if(this.localHeaderOffset===G1.MAX_VALUE_32BITS)this.localHeaderOffset=$.readInt(8);if(this.diskNumberStart===G1.MAX_VALUE_32BITS)this.diskNumberStart=$.readInt(4)},readExtraFields:function($){var q=$.index+this.extraFieldsLength,Q,K,J;if(!this.extraFields)this.extraFields={};while($.index+4{var _G=K7(),i2=T0(),f2=r4(),cG=FK(),bG=n2();function MK($){this.files=[],this.loadOptions=$}MK.prototype={checkSignature:function($){if(!this.reader.readAndCheckSignature($)){this.reader.index-=4;var q=this.reader.readString(4);throw Error("Corrupted zip or bug: unexpected signature ("+i2.pretty(q)+", expected "+i2.pretty($)+")")}},isSignature:function($,q){var Q=this.reader.index;this.reader.setIndex($);var K=this.reader.readString(4),J=K===q;return this.reader.setIndex(Q),J},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2);var $=this.reader.readData(this.zipCommentLength),q=bG.uint8array?"uint8array":"array",Q=i2.transformTo(q,$);this.zipComment=this.loadOptions.decodeFileName(Q)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.reader.skip(4),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};var $=this.zip64EndOfCentralSize-44,q=0,Q,K,J;while(q<$)Q=this.reader.readInt(2),K=this.reader.readInt(4),J=this.reader.readData(K),this.zip64ExtensibleData[Q]={id:Q,length:K,value:J}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var $,q;for($=0;$0)if(this.isSignature(Q,f2.CENTRAL_FILE_HEADER));else this.reader.zero=J;else if(J<0)throw Error("Corrupted zip: missing "+Math.abs(J)+" bytes.")},prepareReader:function($){this.reader=_G($)},load:function($){this.prepareReader($),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}};wK.exports=MK});var DK=N0((BF,kK)=>{var V7=T0(),U5=r1(),nG=e1(),dG=NK(),mG=U4(),YK=T6();function pG($){return new U5.Promise(function(q,Q){var K=$.decompressed.getContentWorker().pipe(new mG);K.on("error",function(J){Q(J)}).on("end",function(){if(K.streamInfo.crc32!==$.decompressed.crc32)Q(Error("Corrupted zip : CRC32 mismatch"));else q()}).resume()})}kK.exports=function($,q){var Q=this;if(q=V7.extend(q||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:nG.utf8decode}),YK.isNode&&YK.isStream($))return U5.Promise.reject(Error("JSZip can't accept a stream when loading a zip file."));return V7.prepareContent("the loaded zip file",$,!0,q.optimizedBinaryString,q.base64).then(function(K){var J=new dG(q);return J.load(K),J}).then(function(J){var Z=[U5.Promise.resolve(J)],G=J.files;if(q.checkCRC32)for(var W=0;W{function Y2(){if(!(this instanceof Y2))return new Y2;if(arguments.length)throw Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");this.files=Object.create(null),this.comment=null,this.root="",this.clone=function(){var $=new Y2;for(var q in this)if(typeof this[q]!=="function")$[q]=this[q];return $}}Y2.prototype=aq();Y2.prototype.loadAsync=DK();Y2.support=n2();Y2.defaults=K4();Y2.version="3.10.1";Y2.loadAsync=function($,q){return new Y2().loadAsync($,q)};Y2.external=r1();LK.exports=Y2});var Z8={};c1(Z8,{types:()=>QW,promisify:()=>jK,log:()=>RK,isUndefined:()=>N6,isSymbol:()=>KW,isString:()=>F5,isRegExp:()=>Z5,isPrimitive:()=>JW,isObject:()=>Y6,isNumber:()=>fK,isNullOrUndefined:()=>qW,isNull:()=>z5,isFunction:()=>W5,isError:()=>G5,isDate:()=>W7,isBuffer:()=>VW,isBoolean:()=>z7,isArray:()=>vK,inspect:()=>h1,inherits:()=>IK,format:()=>B7,deprecate:()=>oG,default:()=>GW,debuglog:()=>aG,callbackifyOnRejected:()=>w7,callbackify:()=>gK,_extend:()=>M7,TextEncoder:()=>AK,TextDecoder:()=>XK});function B7($,...q){if(!F5($)){var Q=[$];for(var K=0;K=J)return W;switch(W){case"%s":return String(q[K++]);case"%d":return Number(q[K++]);case"%j":try{return JSON.stringify(q[K++])}catch(B){return"[Circular]"}default:return W}});for(var G=q[K];K"u"||process?.noDeprecation===!0)return $;var Q=!1;function K(...J){if(!Q){if(process.throwDeprecation)throw Error(q);else if(process.traceDeprecation)console.trace(q);else console.error(q);Q=!0}return $.apply(this,...J)}return K}function lG($,q){var Q=h1.styles[q];if(Q)return"\x1B["+h1.colors[Q][0]+"m"+$+"\x1B["+h1.colors[Q][1]+"m";else return $}function rG($,q){return $}function sG($){var q={};return $.forEach(function(Q,K){q[Q]=!0}),q}function B5($,q,Q){if($.customInspect&&q&&W5(q.inspect)&&q.inspect!==h1&&!(q.constructor&&q.constructor.prototype===q)){var K=q.inspect(Q,$);if(!F5(K))K=B5($,K,Q);return K}var J=tG($,q);if(J)return J;var Z=Object.keys(q),G=sG(Z);if($.showHidden)Z=Object.getOwnPropertyNames(q);if(G5(q)&&(Z.indexOf("message")>=0||Z.indexOf("description")>=0))return U7(q);if(Z.length===0){if(W5(q)){var W=q.name?": "+q.name:"";return $.stylize("[Function"+W+"]","special")}if(Z5(q))return $.stylize(RegExp.prototype.toString.call(q),"regexp");if(W7(q))return $.stylize(Date.prototype.toString.call(q),"date");if(G5(q))return U7(q)}var B="",V=!1,U=["{","}"];if(vK(q))V=!0,U=["[","]"];if(W5(q)){var w=q.name?": "+q.name:"";B=" [Function"+w+"]"}if(Z5(q))B=" "+RegExp.prototype.toString.call(q);if(W7(q))B=" "+Date.prototype.toUTCString.call(q);if(G5(q))B=" "+U7(q);if(Z.length===0&&(!V||q.length==0))return U[0]+B+U[1];if(Q<0)if(Z5(q))return $.stylize(RegExp.prototype.toString.call(q),"regexp");else return $.stylize("[Object]","special");$.seen.push(q);var F;if(V)F=eG($,q,Q,G,Z);else F=Z.map(function(M){return G7($,q,Q,G,M,V)});return $.seen.pop(),$W(F,B,U)}function tG($,q){if(N6(q))return $.stylize("undefined","undefined");if(F5(q)){var Q="'"+JSON.stringify(q).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return $.stylize(Q,"string")}if(fK(q))return $.stylize(""+q,"number");if(z7(q))return $.stylize(""+q,"boolean");if(z5(q))return $.stylize("null","null")}function U7($){return"["+Error.prototype.toString.call($)+"]"}function eG($,q,Q,K,J){var Z=[];for(var G=0,W=q.length;G-1)if(Z)W=W.split(` -`).map(function(V){return" "+V}).join(` -`).slice(2);else W=` -`+W.split(` -`).map(function(V){return" "+V}).join(` -`)}else W=$.stylize("[Circular]","special");if(N6(G)){if(Z&&J.match(/^\d+$/))return W;if(G=JSON.stringify(""+J),G.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/))G=G.slice(1,-1),G=$.stylize(G,"name");else G=G.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),G=$.stylize(G,"string")}return G+": "+W}function $W($,q,Q){var K=0,J=$.reduce(function(Z,G){if(K++,G.indexOf(` -`)>=0)K++;return Z+G.replace(/\u001b\[\d\d?m/g,"").length+1},0);if(J>60)return Q[0]+(q===""?"":q+` - `)+" "+$.join(`, - `)+" "+Q[1];return Q[0]+q+" "+$.join(", ")+" "+Q[1]}function vK($){return Array.isArray($)}function z7($){return typeof $==="boolean"}function z5($){return $===null}function qW($){return $==null}function fK($){return typeof $==="number"}function F5($){return typeof $==="string"}function KW($){return typeof $==="symbol"}function N6($){return $===void 0}function Z5($){return Y6($)&&F7($)==="[object RegExp]"}function Y6($){return typeof $==="object"&&$!==null}function W7($){return Y6($)&&F7($)==="[object Date]"}function G5($){return Y6($)&&(F7($)==="[object Error]"||$ instanceof Error)}function W5($){return typeof $==="function"}function JW($){return $===null||typeof $==="boolean"||typeof $==="number"||typeof $==="string"||typeof $==="symbol"||typeof $>"u"}function VW($){return $ instanceof Buffer}function F7($){return Object.prototype.toString.call($)}function Z7($){return $<10?"0"+$.toString(10):$.toString(10)}function ZW(){var $=new Date,q=[Z7($.getHours()),Z7($.getMinutes()),Z7($.getSeconds())].join(":");return[$.getDate(),UW[$.getMonth()],q].join(" ")}function RK(...$){console.log("%s - %s",ZW(),B7.apply(null,$))}function IK($,q){if(q)$.super_=q,$.prototype=Object.create(q.prototype,{constructor:{value:$,enumerable:!1,writable:!0,configurable:!0}})}function M7($,q){if(!q||!Y6(q))return $;var Q=Object.keys(q),K=Q.length;while(K--)$[Q[K]]=q[Q[K]];return $}function CK($,q){return Object.prototype.hasOwnProperty.call($,q)}function w7($,q){if(!$){var Q=Error("Promise was rejected with a falsy value");Q.reason=$,$=Q}return q($)}function gK($){if(typeof $!=="function")throw TypeError('The "original" argument must be of type Function');function q(...Q){var K=Q.pop();if(typeof K!=="function")throw TypeError("The last argument must be of type Function");var J=this,Z=function(...G){return K.apply(J,...G)};$.apply(this,Q).then(function(G){process.nextTick(Z.bind(null,null,G))},function(G){process.nextTick(w7.bind(null,G,Z))})}return Object.setPrototypeOf(q,Object.getPrototypeOf($)),Object.defineProperties(q,Object.getOwnPropertyDescriptors($)),q}var iG,aG,h1,QW=()=>{},UW,jK,AK,XK,GW;var G8=b1(()=>{iG=/%[sdj%]/g;aG=(($={},q={},Q)=>((Q=typeof process<"u"&&!1)&&(Q=Q.replace(/[|\\{}()[\]^$+?.]/g,"\\$&").replace(/\*/g,".*").replace(/,/g,"$|^").toUpperCase()),q=new RegExp("^"+Q+"$","i"),(K)=>{if(K=K.toUpperCase(),!$[K])if(q.test(K))$[K]=function(...J){console.error("%s: %s",K,pid,B7.apply(null,...J))};else $[K]=function(){};return $[K]}))(),h1=(($)=>($.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},$.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},$.custom=Symbol.for("nodejs.util.inspect.custom"),$))(function($,q,...Q){var K={seen:[],stylize:rG};if(Q.length>=1)K.depth=Q[0];if(Q.length>=2)K.colors=Q[1];if(z7(q))K.showHidden=q;else if(q)M7(K,q);if(N6(K.showHidden))K.showHidden=!1;if(N6(K.depth))K.depth=2;if(N6(K.colors))K.colors=!1;if(K.colors)K.stylize=lG;return B5(K,$,K.depth)});UW=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];jK=(($)=>($.custom=Symbol.for("nodejs.util.promisify.custom"),$))(function($){if(typeof $!=="function")throw TypeError('The "original" argument must be of type Function');if(kCustomPromisifiedSymbol&&$[kCustomPromisifiedSymbol]){var q=$[kCustomPromisifiedSymbol];if(typeof q!=="function")throw TypeError('The "nodejs.util.promisify.custom" argument must be of type Function');return Object.defineProperty(q,kCustomPromisifiedSymbol,{value:q,enumerable:!1,writable:!1,configurable:!0}),q}function q(...Q){var K,J,Z=new Promise(function(G,W){K=G,J=W});Q.push(function(G,W){if(G)J(G);else K(W)});try{$.apply(this,Q)}catch(G){J(G)}return Z}if(Object.setPrototypeOf(q,Object.getPrototypeOf($)),kCustomPromisifiedSymbol)Object.defineProperty(q,kCustomPromisifiedSymbol,{value:q,enumerable:!1,writable:!1,configurable:!0});return Object.defineProperties(q,Object.getOwnPropertyDescriptors($))});({TextEncoder:AK,TextDecoder:XK}=globalThis),GW={TextEncoder:AK,TextDecoder:XK,promisify:jK,log:RK,inherits:IK,_extend:M7,callbackifyOnRejected:w7,callbackify:gK}});var H7={};c1(H7,{resolveObject:()=>SK,resolve:()=>uK,parse:()=>D6,format:()=>TK,default:()=>DW,Url:()=>Z2,URLSearchParams:()=>OK,URL:()=>D7});function L7($){return typeof $==="string"}function PK($){return typeof $==="object"&&$!==null}function M5($){return $===null}function WW($){return $==null}function Z2(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}function D6($,q,Q){if($&&PK($)&&$ instanceof Z2)return $;var K=new Z2;return K.parse($,q,Q),K}function TK($){if(L7($))$=D6($);if(!($ instanceof Z2))return Z2.prototype.format.call($);return $.format()}function uK($,q){return D6($,!1,!0).resolve(q)}function SK($,q){if(!$)return q;return D6($,!1,!0).resolveObject(q)}var D7,OK,BW,zW,FW,MW,wW,N7,yK,hK,NW=255,xK,YW,kW,Y7,k6,k7,DW;var v7=b1(()=>{({URL:D7,URLSearchParams:OK}=globalThis);BW=/^([a-z0-9.+-]+:)/i,zW=/:[0-9]*$/,FW=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,MW=["<",">",'"',"`"," ","\r",` -`,"\t"],wW=["{","}","|","\\","^","`"].concat(MW),N7=["'"].concat(wW),yK=["%","/","?",";","#"].concat(N7),hK=["/","?","#"],xK=/^[+a-z0-9A-Z_-]{0,63}$/,YW=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,kW={javascript:!0,"javascript:":!0},Y7={javascript:!0,"javascript:":!0},k6={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},k7={parse($){var q=decodeURIComponent;return($+"").replace(/\+/g," ").split("&").filter(Boolean).reduce(function(Q,K,J){var Z=K.split("="),G=q(Z[0]||""),W=q(Z[1]||""),B=Q[G];return Q[G]=B===void 0?W:[].concat(B,W),Q},{})},stringify($){var q=encodeURIComponent;return Object.keys($||{}).reduce(function(Q,K){return[].concat($[K]).forEach(function(J){Q.push(q(K)+"="+q(J))}),Q},[]).join("&").replace(/\s/g,"+")}};Z2.prototype.parse=function($,q,Q){if(!L7($))throw TypeError("Parameter 'url' must be a string, not "+typeof $);var K=$.indexOf("?"),J=K!==-1&&K<$.indexOf("#")?"?":"#",Z=$.split(J),G=/\\/g;Z[0]=Z[0].replace(G,"/"),$=Z.join(J);var W=$;if(W=W.trim(),!Q&&$.split("#").length===1){var B=FW.exec(W);if(B){if(this.path=W,this.href=W,this.pathname=B[1],B[2])if(this.search=B[2],q)this.query=k7.parse(this.search.substr(1));else this.query=this.search.substr(1);else if(q)this.search="",this.query={};return this}}var V=BW.exec(W);if(V){V=V[0];var U=V.toLowerCase();this.protocol=U,W=W.substr(V.length)}if(Q||V||W.match(/^\/\/[^@\/]+@[^@\/]+/)){var w=W.substr(0,2)==="//";if(w&&!(V&&Y7[V]))W=W.substr(2),this.slashes=!0}if(!Y7[V]&&(w||V&&!k6[V])){var F=-1;for(var M=0;M127)v+="x";else v+=H[j];if(!v.match(xK)){var d=z.slice(0,M),_=z.slice(M+1),X=H.match(YW);if(X)d.push(X[1]),_.unshift(X[2]);if(_.length)W="/"+_.join(".")+W;this.hostname=d.join(".");break}}}}if(this.hostname.length>NW)this.hostname="";else this.hostname=this.hostname.toLowerCase();if(!D)this.hostname=new D7(`https://${this.hostname}`).hostname;var P=this.port?":"+this.port:"",g=this.hostname||"";if(this.host=g+P,this.href+=this.host,D){if(this.hostname=this.hostname.substr(1,this.hostname.length-2),W[0]!=="/")W="/"+W}}if(!kW[U])for(var M=0,N=N7.length;M0?Q.host.split("@"):!1;if(v)Q.auth=v.shift(),Q.host=Q.hostname=v.shift()}if(Q.search=$.search,Q.query=$.query,!M5(Q.pathname)||!M5(Q.search))Q.path=(Q.pathname?Q.pathname:"")+(Q.search?Q.search:"");return Q.href=Q.format(),Q}if(!z.length){if(Q.pathname=null,Q.search)Q.path="/"+Q.search;else Q.path=null;return Q.href=Q.format(),Q}var j=z.slice(-1)[0],n=(Q.host||$.host||z.length>1)&&(j==="."||j==="..")||j==="",d=0;for(var _=z.length;_>=0;_--)if(j=z[_],j===".")z.splice(_,1);else if(j==="..")z.splice(_,1),d++;else if(d)z.splice(_,1),d--;if(!L&&!D)for(;d--;d)z.unshift("..");if(L&&z[0]!==""&&(!z[0]||z[0].charAt(0)!=="/"))z.unshift("");if(n&&z.join("/").substr(-1)!=="/")z.push("");var X=z[0]===""||z[0]&&z[0].charAt(0)==="/";if(H){Q.hostname=Q.host=X?"":z.length?z.shift():"";var v=Q.host&&Q.host.indexOf("@")>0?Q.host.split("@"):!1;if(v)Q.auth=v.shift(),Q.host=Q.hostname=v.shift()}if(L=L||Q.host&&z.length,L&&!X)z.unshift("");if(!z.length)Q.pathname=null,Q.path=null;else Q.pathname=z.join("/");if(!M5(Q.pathname)||!M5(Q.search))Q.path=(Q.pathname?Q.pathname:"")+(Q.search?Q.search:"");return Q.auth=$.auth||Q.auth,Q.slashes=Q.slashes||$.slashes,Q.href=Q.format(),Q};Z2.prototype.parseHost=function(){var $=this.host,q=zW.exec($);if(q){if(q=q[0],q!==":")this.port=q.substr(1);$=$.substr(0,$.length-q.length)}if($)this.hostname=$};DW={parse:D6,resolve:uK,resolveObject:SK,format:TK,Url:Z2,URL:D7,URLSearchParams:OK}});var R7={};c1(R7,{request:()=>uW,globalAgent:()=>bW,get:()=>SW,default:()=>mW,STATUS_CODES:()=>nW,METHODS:()=>dW,IncomingMessage:()=>_W,ClientRequest:()=>EW,Agent:()=>cW});var LW,HW,EK,vW,fW,RW=($,q,Q)=>{Q=$!=null?LW(HW($)):{};let K=q||!$||!$.__esModule?EK(Q,"default",{value:$,enumerable:!0}):Q;for(let J of vW($))if(!fW.call(K,J))EK(K,J,{get:()=>$[J],enumerable:!0});return K},h0=($,q)=>()=>(q||$((q={exports:{}}).exports,q),q.exports),cK,IW,x1,CW,bK,O1,nK,jW,dK,L6,gW,_K,f7,AW,XW,mK,pK,yW,hW,iK,oK,xW,OW,PW,TW,aK,uW,SW,EW,_W,cW,bW,nW,dW,mW;var I7=b1(()=>{LW=Object.create,{getPrototypeOf:HW,defineProperty:EK,getOwnPropertyNames:vW}=Object,fW=Object.prototype.hasOwnProperty,cK=h0(($)=>{$.fetch=J(globalThis.fetch)&&J(globalThis.ReadableStream),$.writableStream=J(globalThis.WritableStream),$.abortController=J(globalThis.AbortController);var q;function Q(){if(q!==void 0)return q;if(globalThis.XMLHttpRequest){q=new globalThis.XMLHttpRequest;try{q.open("GET",globalThis.XDomainRequest?"/":"https://example.com")}catch(Z){q=null}}else q=null;return q}function K(Z){var G=Q();if(!G)return!1;try{return G.responseType=Z,G.responseType===Z}catch(W){}return!1}$.arraybuffer=$.fetch||K("arraybuffer"),$.msstream=!$.fetch&&K("ms-stream"),$.mozchunkedarraybuffer=!$.fetch&&K("moz-chunked-arraybuffer"),$.overrideMimeType=$.fetch||(Q()?J(Q().overrideMimeType):!1);function J(Z){return typeof Z==="function"}q=null}),IW=h0(($,q)=>{if(typeof Object.create==="function")q.exports=function(Q,K){if(K)Q.super_=K,Q.prototype=Object.create(K.prototype,{constructor:{value:Q,enumerable:!1,writable:!0,configurable:!0}})};else q.exports=function(Q,K){if(K){Q.super_=K;var J=function(){};J.prototype=K.prototype,Q.prototype=new J,Q.prototype.constructor=Q}}}),x1=h0(($,q)=>{try{if(Q=(G8(),X0(Z8)),typeof Q.inherits!=="function")throw"";q.exports=Q.inherits}catch(K){q.exports=IW()}var Q}),CW=h0(($,q)=>{function Q(L,D){var z=Object.keys(L);if(Object.getOwnPropertySymbols){var N=Object.getOwnPropertySymbols(L);D&&(N=N.filter(function(H){return Object.getOwnPropertyDescriptor(L,H).enumerable})),z.push.apply(z,N)}return z}function K(L){for(var D=1;D0)this.tail.next=z;else this.head=z;this.tail=z,++this.length}},{key:"unshift",value:function(D){var z={data:D,next:this.head};if(this.length===0)this.tail=z;this.head=z,++this.length}},{key:"shift",value:function(){if(this.length===0)return;var D=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;return--this.length,D}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(D){if(this.length===0)return"";var z=this.head,N=""+z.data;while(z=z.next)N+=D+z.data;return N}},{key:"concat",value:function(D){if(this.length===0)return w.alloc(0);var z=w.allocUnsafe(D>>>0),N=this.head,H=0;while(N)f(N.data,z,H),H+=N.data.length,N=N.next;return z}},{key:"consume",value:function(D,z){var N;if(Dv.length?v.length:D;if(j===v.length)H+=v;else H+=v.slice(0,D);if(D-=j,D===0){if(j===v.length)if(++N,z.next)this.head=z.next;else this.head=this.tail=null;else this.head=z,z.data=v.slice(j);break}++N}return this.length-=N,H}},{key:"_getBuffer",value:function(D){var z=w.allocUnsafe(D),N=this.head,H=1;N.data.copy(z),D-=N.data.length;while(N=N.next){var v=N.data,j=D>v.length?v.length:D;if(v.copy(z,z.length-D,0,j),D-=j,D===0){if(j===v.length)if(++H,N.next)this.head=N.next;else this.head=this.tail=null;else this.head=N,N.data=v.slice(j);break}++H}return this.length-=H,z}},{key:k,value:function(D,z){return M(this,K(K({},z),{},{depth:0,customInspect:!1}))}}]),L}()}),bK=h0(($,q)=>{function Q(B,V){var U=this,w=this._readableState&&this._readableState.destroyed,F=this._writableState&&this._writableState.destroyed;if(w||F){if(V)V(B);else if(B){if(!this._writableState)process.nextTick(G,this,B);else if(!this._writableState.errorEmitted)this._writableState.errorEmitted=!0,process.nextTick(G,this,B)}return this}if(this._readableState)this._readableState.destroyed=!0;if(this._writableState)this._writableState.destroyed=!0;return this._destroy(B||null,function(M){if(!V&&M)if(!U._writableState)process.nextTick(K,U,M);else if(!U._writableState.errorEmitted)U._writableState.errorEmitted=!0,process.nextTick(K,U,M);else process.nextTick(J,U);else if(V)process.nextTick(J,U),V(M);else process.nextTick(J,U)}),this}function K(B,V){G(B,V),J(B)}function J(B){if(B._writableState&&!B._writableState.emitClose)return;if(B._readableState&&!B._readableState.emitClose)return;B.emit("close")}function Z(){if(this._readableState)this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1;if(this._writableState)this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1}function G(B,V){B.emit("error",V)}function W(B,V){var{_readableState:U,_writableState:w}=B;if(U&&U.autoDestroy||w&&w.autoDestroy)B.destroy(V);else B.emit("error",V)}q.exports={destroy:Q,undestroy:Z,errorOrDestroy:W}}),O1=h0(($,q)=>{var Q={};function K(B,V,U){if(!U)U=Error;function w(M,k,f){if(typeof V==="string")return V;else return V(M,k,f)}class F extends U{constructor(M,k,f){super(w(M,k,f))}}F.prototype.name=U.name,F.prototype.code=B,Q[B]=F}function J(B,V){if(Array.isArray(B)){let U=B.length;if(B=B.map((w)=>String(w)),U>2)return`one of ${V} ${B.slice(0,U-1).join(", ")}, or `+B[U-1];else if(U===2)return`one of ${V} ${B[0]} or ${B[1]}`;else return`of ${V} ${B[0]}`}else return`of ${V} ${String(B)}`}function Z(B,V,U){return B.substr(!U||U<0?0:+U,V.length)===V}function G(B,V,U){if(U===void 0||U>B.length)U=B.length;return B.substring(U-V.length,U)===V}function W(B,V,U){if(typeof U!=="number")U=0;if(U+V.length>B.length)return!1;else return B.indexOf(V,U)!==-1}K("ERR_INVALID_OPT_VALUE",function(B,V){return'The value "'+V+'" is invalid for option "'+B+'"'},TypeError),K("ERR_INVALID_ARG_TYPE",function(B,V,U){let w;if(typeof V==="string"&&Z(V,"not "))w="must not be",V=V.replace(/^not /,"");else w="must be";let F;if(G(B," argument"))F=`The ${B} ${w} ${J(V,"type")}`;else{let M=W(B,".")?"property":"argument";F=`The "${B}" ${M} ${w} ${J(V,"type")}`}return F+=`. Received type ${typeof U}`,F},TypeError),K("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF"),K("ERR_METHOD_NOT_IMPLEMENTED",function(B){return"The "+B+" method is not implemented"}),K("ERR_STREAM_PREMATURE_CLOSE","Premature close"),K("ERR_STREAM_DESTROYED",function(B){return"Cannot call "+B+" after a stream was destroyed"}),K("ERR_MULTIPLE_CALLBACK","Callback called multiple times"),K("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable"),K("ERR_STREAM_WRITE_AFTER_END","write after end"),K("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),K("ERR_UNKNOWN_ENCODING",function(B){return"Unknown encoding: "+B},TypeError),K("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event"),$.codes=Q}),nK=h0(($,q)=>{var Q=O1().codes.ERR_INVALID_OPT_VALUE;function K(Z,G,W){return Z.highWaterMark!=null?Z.highWaterMark:G?Z[W]:null}function J(Z,G,W,B){var V=K(G,B,W);if(V!=null){if(!(isFinite(V)&&Math.floor(V)===V)||V<0){var U=B?W:"highWaterMark";throw new Q(U,V)}return Math.floor(V)}return Z.objectMode?16:16384}q.exports={getHighWaterMark:J}}),jW=h0(($,q)=>{q.exports=(G8(),X0(Z8)).deprecate}),dK=h0(($,q)=>{q.exports=X;function Q(S){var b=this;this.next=null,this.entry=null,this.finish=function(){w0(b,S)}}var K;X.WritableState=d;var J={deprecate:jW()},Z=a1(),G=(t0(),X0(K2)).Buffer,W=(typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof self<"u"?self:{}).Uint8Array||function(){};function B(S){return G.from(S)}function V(S){return G.isBuffer(S)||S instanceof W}var U=bK(),w=nK(),F=w.getHighWaterMark,M=O1().codes,k=M.ERR_INVALID_ARG_TYPE,f=M.ERR_METHOD_NOT_IMPLEMENTED,L=M.ERR_MULTIPLE_CALLBACK,D=M.ERR_STREAM_CANNOT_PIPE,z=M.ERR_STREAM_DESTROYED,N=M.ERR_STREAM_NULL_VALUES,H=M.ERR_STREAM_WRITE_AFTER_END,v=M.ERR_UNKNOWN_ENCODING,j=U.errorOrDestroy;x1()(X,Z);function n(){}function d(S,b,O){if(K=K||L6(),S=S||{},typeof O!=="boolean")O=b instanceof K;if(this.objectMode=!!S.objectMode,O)this.objectMode=this.objectMode||!!S.writableObjectMode;this.highWaterMark=F(this,S,"writableHighWaterMark",O),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var E=S.decodeStrings===!1;this.decodeStrings=!E,this.defaultEncoding=S.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(a){Z0(b,a)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=S.emitClose!==!1,this.autoDestroy=!!S.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new Q(this)}d.prototype.getBuffer=function(){var S=this.bufferedRequest,b=[];while(S)b.push(S),S=S.next;return b},function(){try{Object.defineProperty(d.prototype,"buffer",{get:J.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(S){}}();var _;if(typeof Symbol==="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]==="function")_=Function.prototype[Symbol.hasInstance],Object.defineProperty(X,Symbol.hasInstance,{value:function(S){if(_.call(this,S))return!0;if(this!==X)return!1;return S&&S._writableState instanceof d}});else _=function(S){return S instanceof this};function X(S){K=K||L6();var b=this instanceof K;if(!b&&!_.call(X,this))return new X(S);if(this._writableState=new d(S,this,b),this.writable=!0,S){if(typeof S.write==="function")this._write=S.write;if(typeof S.writev==="function")this._writev=S.writev;if(typeof S.destroy==="function")this._destroy=S.destroy;if(typeof S.final==="function")this._final=S.final}Z.call(this)}X.prototype.pipe=function(){j(this,new D)};function P(S,b){var O=new H;j(S,O),process.nextTick(b,O)}function g(S,b,O,E){var a;if(O===null)a=new N;else if(typeof O!=="string"&&!b.objectMode)a=new k("chunk",["string","Buffer"],O);if(a)return j(S,a),process.nextTick(E,a),!1;return!0}X.prototype.write=function(S,b,O){var E=this._writableState,a=!1,K0=!E.objectMode&&V(S);if(K0&&!G.isBuffer(S))S=B(S);if(typeof b==="function")O=b,b=null;if(K0)b="buffer";else if(!b)b=E.defaultEncoding;if(typeof O!=="function")O=n;if(E.ending)P(this,O);else if(K0||g(this,E,S,O))E.pendingcb++,a=h(this,E,K0,S,b,O);return a},X.prototype.cork=function(){this._writableState.corked++},X.prototype.uncork=function(){var S=this._writableState;if(S.corked){if(S.corked--,!S.writing&&!S.corked&&!S.bufferProcessing&&S.bufferedRequest)W0(this,S)}},X.prototype.setDefaultEncoding=function(S){if(typeof S==="string")S=S.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((S+"").toLowerCase())>-1))throw new v(S);return this._writableState.defaultEncoding=S,this},Object.defineProperty(X.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});function c(S,b,O){if(!S.objectMode&&S.decodeStrings!==!1&&typeof b==="string")b=G.from(b,O);return b}Object.defineProperty(X.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});function h(S,b,O,E,a,K0){if(!O){var R=c(b,E,a);if(E!==R)O=!0,a="buffer",E=R}var Y=b.objectMode?1:E.length;b.length+=Y;var C=b.length{var Q=Object.keys||function(w){var F=[];for(var M in w)F.push(M);return F};q.exports=B;var K=mK(),J=dK();x1()(B,K);{Z=Q(J.prototype);for(W=0;W{/*! safe-buffer. MIT License. Feross Aboukhadijeh */var Q=(t0(),X0(K2)),K=Q.Buffer;function J(G,W){for(var B in G)W[B]=G[B]}if(K.from&&K.alloc&&K.allocUnsafe&&K.allocUnsafeSlow)q.exports=Q;else J(Q,$),$.Buffer=Z;function Z(G,W,B){return K(G,W,B)}Z.prototype=Object.create(K.prototype),J(K,Z),Z.from=function(G,W,B){if(typeof G==="number")throw TypeError("Argument must not be a number");return K(G,W,B)},Z.alloc=function(G,W,B){if(typeof G!=="number")throw TypeError("Argument must be a number");var V=K(G);if(W!==void 0)if(typeof B==="string")V.fill(W,B);else V.fill(W);else V.fill(0);return V},Z.allocUnsafe=function(G){if(typeof G!=="number")throw TypeError("Argument must be a number");return K(G)},Z.allocUnsafeSlow=function(G){if(typeof G!=="number")throw TypeError("Argument must be a number");return Q.SlowBuffer(G)}}),_K=h0(($)=>{var q=gW().Buffer,Q=q.isEncoding||function(z){switch(z=""+z,z&&z.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function K(z){if(!z)return"utf8";var N;while(!0)switch(z){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return z;default:if(N)return;z=(""+z).toLowerCase(),N=!0}}function J(z){var N=K(z);if(typeof N!=="string"&&(q.isEncoding===Q||!Q(z)))throw Error("Unknown encoding: "+z);return N||z}$.StringDecoder=Z;function Z(z){this.encoding=J(z);var N;switch(this.encoding){case"utf16le":this.text=F,this.end=M,N=4;break;case"utf8":this.fillLast=V,N=4;break;case"base64":this.text=k,this.end=f,N=3;break;default:this.write=L,this.end=D;return}this.lastNeed=0,this.lastTotal=0,this.lastChar=q.allocUnsafe(N)}Z.prototype.write=function(z){if(z.length===0)return"";var N,H;if(this.lastNeed){if(N=this.fillLast(z),N===void 0)return"";H=this.lastNeed,this.lastNeed=0}else H=0;if(H>5===6)return 2;else if(z>>4===14)return 3;else if(z>>3===30)return 4;return z>>6===2?-1:-2}function W(z,N,H){var v=N.length-1;if(v=0){if(j>0)z.lastNeed=j-1;return j}if(--v=0){if(j>0)z.lastNeed=j-2;return j}if(--v=0){if(j>0)if(j===2)j=0;else z.lastNeed=j-3;return j}return 0}function B(z,N,H){if((N[0]&192)!==128)return z.lastNeed=0,"�";if(z.lastNeed>1&&N.length>1){if((N[1]&192)!==128)return z.lastNeed=1,"�";if(z.lastNeed>2&&N.length>2){if((N[2]&192)!==128)return z.lastNeed=2,"�"}}}function V(z){var N=this.lastTotal-this.lastNeed,H=B(this,z,N);if(H!==void 0)return H;if(this.lastNeed<=z.length)return z.copy(this.lastChar,N,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);z.copy(this.lastChar,N,0,z.length),this.lastNeed-=z.length}function U(z,N){var H=W(this,z,N);if(!this.lastNeed)return z.toString("utf8",N);this.lastTotal=H;var v=z.length-(H-this.lastNeed);return z.copy(this.lastChar,0,v),z.toString("utf8",N,v)}function w(z){var N=z&&z.length?this.write(z):"";if(this.lastNeed)return N+"�";return N}function F(z,N){if((z.length-N)%2===0){var H=z.toString("utf16le",N);if(H){var v=H.charCodeAt(H.length-1);if(v>=55296&&v<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=z[z.length-2],this.lastChar[1]=z[z.length-1],H.slice(0,-1)}return H}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=z[z.length-1],z.toString("utf16le",N,z.length-1)}function M(z){var N=z&&z.length?this.write(z):"";if(this.lastNeed){var H=this.lastTotal-this.lastNeed;return N+this.lastChar.toString("utf16le",0,H)}return N}function k(z,N){var H=(z.length-N)%3;if(H===0)return z.toString("base64",N);if(this.lastNeed=3-H,this.lastTotal=3,H===1)this.lastChar[0]=z[z.length-1];else this.lastChar[0]=z[z.length-2],this.lastChar[1]=z[z.length-1];return z.toString("base64",N,z.length-H)}function f(z){var N=z&&z.length?this.write(z):"";if(this.lastNeed)return N+this.lastChar.toString("base64",0,3-this.lastNeed);return N}function L(z){return z.toString(this.encoding)}function D(z){return z&&z.length?this.write(z):""}}),f7=h0(($,q)=>{var Q=O1().codes.ERR_STREAM_PREMATURE_CLOSE;function K(W){var B=!1;return function(){if(B)return;B=!0;for(var V=arguments.length,U=Array(V),w=0;w{var Q;function K(v,j,n){if(j=J(j),j in v)Object.defineProperty(v,j,{value:n,enumerable:!0,configurable:!0,writable:!0});else v[j]=n;return v}function J(v){var j=Z(v,"string");return typeof j==="symbol"?j:String(j)}function Z(v,j){if(typeof v!=="object"||v===null)return v;var n=v[Symbol.toPrimitive];if(n!==void 0){var d=n.call(v,j||"default");if(typeof d!=="object")return d;throw TypeError("@@toPrimitive must return a primitive value.")}return(j==="string"?String:Number)(v)}var G=f7(),W=Symbol("lastResolve"),B=Symbol("lastReject"),V=Symbol("error"),U=Symbol("ended"),w=Symbol("lastPromise"),F=Symbol("handlePromise"),M=Symbol("stream");function k(v,j){return{value:v,done:j}}function f(v){var j=v[W];if(j!==null){var n=v[M].read();if(n!==null)v[w]=null,v[W]=null,v[B]=null,j(k(n,!1))}}function L(v){process.nextTick(f,v)}function D(v,j){return function(n,d){v.then(function(){if(j[U]){n(k(void 0,!0));return}j[F](n,d)},d)}}var z=Object.getPrototypeOf(function(){}),N=Object.setPrototypeOf((Q={get stream(){return this[M]},next:function(){var v=this,j=this[V];if(j!==null)return Promise.reject(j);if(this[U])return Promise.resolve(k(void 0,!0));if(this[M].destroyed)return new Promise(function(X,P){process.nextTick(function(){if(v[V])P(v[V]);else X(k(void 0,!0))})});var n=this[w],d;if(n)d=new Promise(D(n,this));else{var _=this[M].read();if(_!==null)return Promise.resolve(k(_,!1));d=new Promise(this[F])}return this[w]=d,d}},K(Q,Symbol.asyncIterator,function(){return this}),K(Q,"return",function(){var v=this;return new Promise(function(j,n){v[M].destroy(null,function(d){if(d){n(d);return}j(k(void 0,!0))})})}),Q),z),H=function(v){var j,n=Object.create(N,(j={},K(j,M,{value:v,writable:!0}),K(j,W,{value:null,writable:!0}),K(j,B,{value:null,writable:!0}),K(j,V,{value:null,writable:!0}),K(j,U,{value:v._readableState.endEmitted,writable:!0}),K(j,F,{value:function(d,_){var X=n[M].read();if(X)n[w]=null,n[W]=null,n[B]=null,d(k(X,!1));else n[W]=d,n[B]=_},writable:!0}),j));return n[w]=null,G(v,function(d){if(d&&d.code!=="ERR_STREAM_PREMATURE_CLOSE"){var _=n[B];if(_!==null)n[w]=null,n[W]=null,n[B]=null,_(d);n[V]=d;return}var X=n[W];if(X!==null)n[w]=null,n[W]=null,n[B]=null,X(k(void 0,!0));n[U]=!0}),v.on("readable",L.bind(null,n)),n};q.exports=H}),XW=h0(($,q)=>{function Q(w,F,M,k,f,L,D){try{var z=w[L](D),N=z.value}catch(H){M(H);return}if(z.done)F(N);else Promise.resolve(N).then(k,f)}function K(w){return function(){var F=this,M=arguments;return new Promise(function(k,f){var L=w.apply(F,M);function D(N){Q(L,k,f,D,z,"next",N)}function z(N){Q(L,k,f,D,z,"throw",N)}D(void 0)})}}function J(w,F){var M=Object.keys(w);if(Object.getOwnPropertySymbols){var k=Object.getOwnPropertySymbols(w);F&&(k=k.filter(function(f){return Object.getOwnPropertyDescriptor(w,f).enumerable})),M.push.apply(M,k)}return M}function Z(w){for(var F=1;F{q.exports=g;var Q;g.ReadableState=P;var K=(i1(),X0(p1)).EventEmitter,J=function(R,Y){return R.listeners(Y).length},Z=a1(),G=(t0(),X0(K2)).Buffer,W=(typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof self<"u"?self:{}).Uint8Array||function(){};function B(R){return G.from(R)}function V(R){return G.isBuffer(R)||R instanceof W}var U=(G8(),X0(Z8)),w;if(U&&U.debuglog)w=U.debuglog("stream");else w=function(){};var F=CW(),M=bK(),k=nK(),f=k.getHighWaterMark,L=O1().codes,D=L.ERR_INVALID_ARG_TYPE,z=L.ERR_STREAM_PUSH_AFTER_EOF,N=L.ERR_METHOD_NOT_IMPLEMENTED,H=L.ERR_STREAM_UNSHIFT_AFTER_END_EVENT,v,j,n;x1()(g,Z);var d=M.errorOrDestroy,_=["error","close","destroy","pause","resume"];function X(R,Y,C){if(typeof R.prependListener==="function")return R.prependListener(Y,C);if(!R._events||!R._events[Y])R.on(Y,C);else if(Array.isArray(R._events[Y]))R._events[Y].unshift(C);else R._events[Y]=[C,R._events[Y]]}function P(R,Y,C){if(Q=Q||L6(),R=R||{},typeof C!=="boolean")C=Y instanceof Q;if(this.objectMode=!!R.objectMode,C)this.objectMode=this.objectMode||!!R.readableObjectMode;if(this.highWaterMark=f(this,R,"readableHighWaterMark",C),this.buffer=new F,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=R.emitClose!==!1,this.autoDestroy=!!R.autoDestroy,this.destroyed=!1,this.defaultEncoding=R.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,R.encoding){if(!v)v=_K().StringDecoder;this.decoder=new v(R.encoding),this.encoding=R.encoding}}function g(R){if(Q=Q||L6(),!(this instanceof g))return new g(R);var Y=this instanceof Q;if(this._readableState=new P(R,this,Y),this.readable=!0,R){if(typeof R.read==="function")this._read=R.read;if(typeof R.destroy==="function")this._destroy=R.destroy}Z.call(this)}Object.defineProperty(g.prototype,"destroyed",{enumerable:!1,get:function(){if(this._readableState===void 0)return!1;return this._readableState.destroyed},set:function(R){if(!this._readableState)return;this._readableState.destroyed=R}}),g.prototype.destroy=M.destroy,g.prototype._undestroy=M.undestroy,g.prototype._destroy=function(R,Y){Y(R)},g.prototype.push=function(R,Y){var C=this._readableState,u;if(!C.objectMode){if(typeof R==="string"){if(Y=Y||C.defaultEncoding,Y!==C.encoding)R=G.from(R,Y),Y="";u=!0}}else u=!0;return c(this,R,Y,!1,u)},g.prototype.unshift=function(R){return c(this,R,null,!0,!1)};function c(R,Y,C,u,e){w("readableAddChunk",Y);var r=R._readableState;if(Y===null)r.reading=!1,F0(R,r);else{var s;if(!e)s=x(r,Y);if(s)d(R,s);else if(r.objectMode||Y&&Y.length>0){if(typeof Y!=="string"&&!r.objectMode&&Object.getPrototypeOf(Y)!==G.prototype)Y=B(Y);if(u)if(r.endEmitted)d(R,new H);else h(R,r,Y,!0);else if(r.ended)d(R,new z);else if(r.destroyed)return!1;else if(r.reading=!1,r.decoder&&!C)if(Y=r.decoder.write(Y),r.objectMode||Y.length!==0)h(R,r,Y,!1);else y(R,r);else h(R,r,Y,!1)}else if(!u)r.reading=!1,y(R,r)}return!r.ended&&(r.length=l)R=l;else R--,R|=R>>>1,R|=R>>>2,R|=R>>>4,R|=R>>>8,R|=R>>>16,R++;return R}function Z0(R,Y){if(R<=0||Y.length===0&&Y.ended)return 0;if(Y.objectMode)return 1;if(R!==R)if(Y.flowing&&Y.length)return Y.buffer.head.data.length;else return Y.length;if(R>Y.highWaterMark)Y.highWaterMark=$0(R);if(R<=Y.length)return R;if(!Y.ended)return Y.needReadable=!0,0;return Y.length}g.prototype.read=function(R){w("read",R),R=parseInt(R,10);var Y=this._readableState,C=R;if(R!==0)Y.emittedReadable=!1;if(R===0&&Y.needReadable&&((Y.highWaterMark!==0?Y.length>=Y.highWaterMark:Y.length>0)||Y.ended)){if(w("read: emitReadable",Y.length,Y.ended),Y.length===0&&Y.ended)E(this);else p(this);return null}if(R=Z0(R,Y),R===0&&Y.ended){if(Y.length===0)E(this);return null}var u=Y.needReadable;if(w("need readable",u),Y.length===0||Y.length-R0)e=O(R,Y);else e=null;if(e===null)Y.needReadable=Y.length<=Y.highWaterMark,R=0;else Y.length-=R,Y.awaitDrain=0;if(Y.length===0){if(!Y.ended)Y.needReadable=!0;if(C!==R&&Y.ended)E(this)}if(e!==null)this.emit("data",e);return e};function F0(R,Y){if(w("onEofChunk"),Y.ended)return;if(Y.decoder){var C=Y.decoder.end();if(C&&C.length)Y.buffer.push(C),Y.length+=Y.objectMode?1:C.length}if(Y.ended=!0,Y.sync)p(R);else if(Y.needReadable=!1,!Y.emittedReadable)Y.emittedReadable=!0,W0(R)}function p(R){var Y=R._readableState;if(w("emitReadable",Y.needReadable,Y.emittedReadable),Y.needReadable=!1,!Y.emittedReadable)w("emitReadable",Y.flowing),Y.emittedReadable=!0,process.nextTick(W0,R)}function W0(R){var Y=R._readableState;if(w("emitReadable_",Y.destroyed,Y.length,Y.ended),!Y.destroyed&&(Y.length||Y.ended))R.emit("readable"),Y.emittedReadable=!1;Y.needReadable=!Y.flowing&&!Y.ended&&Y.length<=Y.highWaterMark,b(R)}function y(R,Y){if(!Y.readingMore)Y.readingMore=!0,process.nextTick(i,R,Y)}function i(R,Y){while(!Y.reading&&!Y.ended&&(Y.length1&&K0(u.pipes,R)!==-1)&&!G0)w("false write response, pause",u.awaitDrain),u.awaitDrain++;C.pause()}}function I0(O0){if(w("onerror",O0),q2(),R.removeListener("error",I0),J(R,"error")===0)d(R,O0)}X(R,"error",I0);function m0(){R.removeListener("finish",p0),q2()}R.once("close",m0);function p0(){w("onfinish"),R.removeListener("close",m0),q2()}R.once("finish",p0);function q2(){w("unpipe"),C.unpipe(R)}if(R.emit("pipe",C),!u.flowing)w("pipe resume"),C.resume();return R};function U0(R){return function(){var Y=R._readableState;if(w("pipeOnDrain",Y.awaitDrain),Y.awaitDrain)Y.awaitDrain--;if(Y.awaitDrain===0&&J(R,"data"))Y.flowing=!0,b(R)}}g.prototype.unpipe=function(R){var Y=this._readableState,C={hasUnpiped:!1};if(Y.pipesCount===0)return this;if(Y.pipesCount===1){if(R&&R!==Y.pipes)return this;if(!R)R=Y.pipes;if(Y.pipes=null,Y.pipesCount=0,Y.flowing=!1,R)R.emit("unpipe",this,C);return this}if(!R){var{pipes:u,pipesCount:e}=Y;Y.pipes=null,Y.pipesCount=0,Y.flowing=!1;for(var r=0;r0,u.flowing!==!1)this.resume()}else if(R==="readable"){if(!u.endEmitted&&!u.readableListening){if(u.readableListening=u.needReadable=!0,u.flowing=!1,u.emittedReadable=!1,w("on readable",u.length,u.reading),u.length)p(this);else if(!u.reading)process.nextTick(V0,this)}}return C},g.prototype.addListener=g.prototype.on,g.prototype.removeListener=function(R,Y){var C=Z.prototype.removeListener.call(this,R,Y);if(R==="readable")process.nextTick(m,this);return C},g.prototype.removeAllListeners=function(R){var Y=Z.prototype.removeAllListeners.apply(this,arguments);if(R==="readable"||R===void 0)process.nextTick(m,this);return Y};function m(R){var Y=R._readableState;if(Y.readableListening=R.listenerCount("readable")>0,Y.resumeScheduled&&!Y.paused)Y.flowing=!0;else if(R.listenerCount("data")>0)R.resume()}function V0(R){w("readable nexttick read 0"),R.read(0)}g.prototype.resume=function(){var R=this._readableState;if(!R.flowing)w("resume"),R.flowing=!R.readableListening,w0(this,R);return R.paused=!1,this};function w0(R,Y){if(!Y.resumeScheduled)Y.resumeScheduled=!0,process.nextTick(S,R,Y)}function S(R,Y){if(w("resume",Y.reading),!Y.reading)R.read(0);if(Y.resumeScheduled=!1,R.emit("resume"),b(R),Y.flowing&&!Y.reading)R.read(0)}g.prototype.pause=function(){if(w("call pause flowing=%j",this._readableState.flowing),this._readableState.flowing!==!1)w("pause"),this._readableState.flowing=!1,this.emit("pause");return this._readableState.paused=!0,this};function b(R){var Y=R._readableState;w("flow",Y.flowing);while(Y.flowing&&R.read()!==null);}if(g.prototype.wrap=function(R){var Y=this,C=this._readableState,u=!1;R.on("end",function(){if(w("wrapped end"),C.decoder&&!C.ended){var s=C.decoder.end();if(s&&s.length)Y.push(s)}Y.push(null)}),R.on("data",function(s){if(w("wrapped data"),C.decoder)s=C.decoder.write(s);if(C.objectMode&&(s===null||s===void 0))return;else if(!C.objectMode&&(!s||!s.length))return;var T=Y.push(s);if(!T)u=!0,R.pause()});for(var e in R)if(this[e]===void 0&&typeof R[e]==="function")this[e]=function(s){return function(){return R[s].apply(R,arguments)}}(e);for(var r=0;r<_.length;r++)R.on(_[r],this.emit.bind(this,_[r]));return this._read=function(s){if(w("wrapped _read",s),u)u=!1,R.resume()},this},typeof Symbol==="function")g.prototype[Symbol.asyncIterator]=function(){if(j===void 0)j=AW();return j(this)};Object.defineProperty(g.prototype,"readableHighWaterMark",{enumerable:!1,get:function(){return this._readableState.highWaterMark}}),Object.defineProperty(g.prototype,"readableBuffer",{enumerable:!1,get:function(){return this._readableState&&this._readableState.buffer}}),Object.defineProperty(g.prototype,"readableFlowing",{enumerable:!1,get:function(){return this._readableState.flowing},set:function(R){if(this._readableState)this._readableState.flowing=R}}),g._fromList=O,Object.defineProperty(g.prototype,"readableLength",{enumerable:!1,get:function(){return this._readableState.length}});function O(R,Y){if(Y.length===0)return null;var C;if(Y.objectMode)C=Y.buffer.shift();else if(!R||R>=Y.length){if(Y.decoder)C=Y.buffer.join("");else if(Y.buffer.length===1)C=Y.buffer.first();else C=Y.buffer.concat(Y.length);Y.buffer.clear()}else C=Y.buffer.consume(R,Y.decoder);return C}function E(R){var Y=R._readableState;if(w("endReadable",Y.endEmitted),!Y.endEmitted)Y.ended=!0,process.nextTick(a,Y,R)}function a(R,Y){if(w("endReadableNT",R.endEmitted,R.length),!R.endEmitted&&R.length===0){if(R.endEmitted=!0,Y.readable=!1,Y.emit("end"),R.autoDestroy){var C=Y._writableState;if(!C||C.autoDestroy&&C.finished)Y.destroy()}}}if(typeof Symbol==="function")g.from=function(R,Y){if(n===void 0)n=XW();return n(g,R,Y)};function K0(R,Y){for(var C=0,u=R.length;C{q.exports=V;var Q=O1().codes,K=Q.ERR_METHOD_NOT_IMPLEMENTED,J=Q.ERR_MULTIPLE_CALLBACK,Z=Q.ERR_TRANSFORM_ALREADY_TRANSFORMING,G=Q.ERR_TRANSFORM_WITH_LENGTH_0,W=L6();x1()(V,W);function B(F,M){var k=this._transformState;k.transforming=!1;var f=k.writecb;if(f===null)return this.emit("error",new J);if(k.writechunk=null,k.writecb=null,M!=null)this.push(M);f(F);var L=this._readableState;if(L.reading=!1,L.needReadable||L.length{q.exports=K;var Q=pK();x1()(K,Q);function K(J){if(!(this instanceof K))return new K(J);Q.call(this,J)}K.prototype._transform=function(J,Z,G){G(null,J)}}),hW=h0(($,q)=>{var Q;function K(k){var f=!1;return function(){if(f)return;f=!0,k.apply(void 0,arguments)}}var J=O1().codes,Z=J.ERR_MISSING_ARGS,G=J.ERR_STREAM_DESTROYED;function W(k){if(k)throw k}function B(k){return k.setHeader&&typeof k.abort==="function"}function V(k,f,L,D){D=K(D);var z=!1;if(k.on("close",function(){z=!0}),Q===void 0)Q=f7();Q(k,{readable:f,writable:L},function(H){if(H)return D(H);z=!0,D()});var N=!1;return function(H){if(z)return;if(N)return;if(N=!0,B(k))return k.abort();if(typeof k.destroy==="function")return k.destroy();D(H||new G("pipe"))}}function U(k){k()}function w(k,f){return k.pipe(f)}function F(k){if(!k.length)return W;if(typeof k[k.length-1]!=="function")return W;return k.pop()}function M(){for(var k=arguments.length,f=Array(k),L=0;L0;return V(H,j,n,function(d){if(!z)z=d;if(d)N.forEach(U);if(j)return;N.forEach(U),D(z)})});return f.reduce(w)}q.exports=M}),iK=h0(($,q)=>{var Q=a1();$=q.exports=mK(),$.Stream=Q||$,$.Readable=$,$.Writable=dK(),$.Duplex=L6(),$.Transform=pK(),$.PassThrough=yW(),$.finished=f7(),$.pipeline=hW()}),oK=h0(($)=>{var q=cK(),Q=x1(),K=iK(),J=$.readyStates={UNSENT:0,OPENED:1,HEADERS_RECEIVED:2,LOADING:3,DONE:4},Z=$.IncomingMessage=function(G,W,B,V){var U=this;if(K.Readable.call(U),U._mode=B,U.headers={},U.rawHeaders=[],U.trailers={},U.rawTrailers=[],U.on("end",function(){process.nextTick(function(){U.emit("close")})}),B==="fetch"){let D=function(){M.read().then(function(z){if(U._destroyed)return;if(V(z.done),z.done){U.push(null);return}U.push(Buffer.from(z.value)),D()}).catch(function(z){if(V(!0),!U._destroyed)U.emit("error",z)})};var w=D;if(U._fetchResponse=W,U.url=W.url,U.statusCode=W.status,U.statusMessage=W.statusText,W.headers.forEach(function(z,N){U.headers[N.toLowerCase()]=z,U.rawHeaders.push(N,z)}),q.writableStream){var F=new WritableStream({write:function(z){return V(!1),new Promise(function(N,H){if(U._destroyed)H();else if(U.push(Buffer.from(z)))N();else U._resumeFetch=N})},close:function(){if(V(!0),!U._destroyed)U.push(null)},abort:function(z){if(V(!0),!U._destroyed)U.emit("error",z)}});try{W.body.pipeTo(F).catch(function(z){if(V(!0),!U._destroyed)U.emit("error",z)});return}catch(z){}}var M=W.body.getReader();D()}else{U._xhr=G,U._pos=0,U.url=G.responseURL,U.statusCode=G.status,U.statusMessage=G.statusText;var k=G.getAllResponseHeaders().split(/\r?\n/);if(k.forEach(function(D){var z=D.match(/^([^:]+):\s*(.*)/);if(z){var N=z[1].toLowerCase();if(N==="set-cookie"){if(U.headers[N]===void 0)U.headers[N]=[];U.headers[N].push(z[2])}else if(U.headers[N]!==void 0)U.headers[N]+=", "+z[2];else U.headers[N]=z[2];U.rawHeaders.push(z[1],z[2])}}),U._charset="x-user-defined",!q.overrideMimeType){var f=U.rawHeaders["mime-type"];if(f){var L=f.match(/;\s*charset=([^;])(;|$)/);if(L)U._charset=L[1].toLowerCase()}if(!U._charset)U._charset="utf-8"}}};Q(Z,K.Readable),Z.prototype._read=function(){var G=this,W=G._resumeFetch;if(W)G._resumeFetch=null,W()},Z.prototype._onXHRProgress=function(G){var W=this,B=W._xhr,V=null;switch(W._mode){case"text":if(V=B.responseText,V.length>W._pos){var U=V.substr(W._pos);if(W._charset==="x-user-defined"){var w=Buffer.alloc(U.length);for(var F=0;FW._pos)W.push(Buffer.from(new Uint8Array(M.result.slice(W._pos)))),W._pos=M.result.byteLength},M.onload=function(){G(!0),W.push(null)},M.readAsArrayBuffer(V);break}if(W._xhr.readyState===J.DONE&&W._mode!=="ms-stream")G(!0),W.push(null)}}),xW=h0(($,q)=>{var Q=cK(),K=x1(),J=oK(),Z=iK(),G=J.IncomingMessage,W=J.readyStates;function B(F,M){if(Q.fetch&&M)return"fetch";else if(Q.mozchunkedarraybuffer)return"moz-chunked-arraybuffer";else if(Q.msstream)return"ms-stream";else if(Q.arraybuffer&&F)return"arraybuffer";else return"text"}var V=q.exports=function(F){var M=this;if(Z.Writable.call(M),M._opts=F,M._body=[],M._headers={},F.auth)M.setHeader("Authorization","Basic "+Buffer.from(F.auth).toString("base64"));Object.keys(F.headers).forEach(function(L){M.setHeader(L,F.headers[L])});var k,f=!0;if(F.mode==="disable-fetch"||"requestTimeout"in F&&!Q.abortController)f=!1,k=!0;else if(F.mode==="prefer-streaming")k=!1;else if(F.mode==="allow-wrong-content-type")k=!Q.overrideMimeType;else if(!F.mode||F.mode==="default"||F.mode==="prefer-fast")k=!0;else throw Error("Invalid value for opts.mode");M._mode=B(k,f),M._fetchTimer=null,M._socketTimeout=null,M._socketTimer=null,M.on("finish",function(){M._onFinish()})};K(V,Z.Writable),V.prototype.setHeader=function(F,M){var k=this,f=F.toLowerCase();if(w.indexOf(f)!==-1)return;k._headers[f]={name:F,value:M}},V.prototype.getHeader=function(F){var M=this._headers[F.toLowerCase()];if(M)return M.value;return null},V.prototype.removeHeader=function(F){var M=this;delete M._headers[F.toLowerCase()]},V.prototype._onFinish=function(){var F=this;if(F._destroyed)return;var M=F._opts;if("timeout"in M&&M.timeout!==0)F.setTimeout(M.timeout);var k=F._headers,f=null;if(M.method!=="GET"&&M.method!=="HEAD")f=new Blob(F._body,{type:(k["content-type"]||{}).value||""});var L=[];if(Object.keys(k).forEach(function(H){var v=k[H].name,j=k[H].value;if(Array.isArray(j))j.forEach(function(n){L.push([v,n])});else L.push([v,j])}),F._mode==="fetch"){var D=null;if(Q.abortController){var z=new AbortController;if(D=z.signal,F._fetchAbortController=z,"requestTimeout"in M&&M.requestTimeout!==0)F._fetchTimer=globalThis.setTimeout(function(){if(F.emit("requestTimeout"),F._fetchAbortController)F._fetchAbortController.abort()},M.requestTimeout)}globalThis.fetch(F._opts.url,{method:F._opts.method,headers:L,body:f||void 0,mode:"cors",credentials:M.withCredentials?"include":"same-origin",signal:D}).then(function(H){F._fetchResponse=H,F._resetTimers(!1),F._connect()},function(H){if(F._resetTimers(!0),!F._destroyed)F.emit("error",H)})}else{var N=F._xhr=new globalThis.XMLHttpRequest;try{N.open(F._opts.method,F._opts.url,!0)}catch(H){process.nextTick(function(){F.emit("error",H)});return}if("responseType"in N)N.responseType=F._mode;if("withCredentials"in N)N.withCredentials=!!M.withCredentials;if(F._mode==="text"&&"overrideMimeType"in N)N.overrideMimeType("text/plain; charset=x-user-defined");if("requestTimeout"in M)N.timeout=M.requestTimeout,N.ontimeout=function(){F.emit("requestTimeout")};if(L.forEach(function(H){N.setRequestHeader(H[0],H[1])}),F._response=null,N.onreadystatechange=function(){switch(N.readyState){case W.LOADING:case W.DONE:F._onXHRProgress();break}},F._mode==="moz-chunked-arraybuffer")N.onprogress=function(){F._onXHRProgress()};N.onerror=function(){if(F._destroyed)return;F._resetTimers(!0),F.emit("error",Error("XHR error"))};try{N.send(f)}catch(H){process.nextTick(function(){F.emit("error",H)});return}}};function U(F){try{var M=F.status;return M!==null&&M!==0}catch(k){return!1}}V.prototype._onXHRProgress=function(){var F=this;if(F._resetTimers(!1),!U(F._xhr)||F._destroyed)return;if(!F._response)F._connect();F._response._onXHRProgress(F._resetTimers.bind(F))},V.prototype._connect=function(){var F=this;if(F._destroyed)return;F._response=new G(F._xhr,F._fetchResponse,F._mode,F._resetTimers.bind(F)),F._response.on("error",function(M){F.emit("error",M)}),F.emit("response",F._response)},V.prototype._write=function(F,M,k){var f=this;f._body.push(F),k()},V.prototype._resetTimers=function(F){var M=this;if(globalThis.clearTimeout(M._socketTimer),M._socketTimer=null,F)globalThis.clearTimeout(M._fetchTimer),M._fetchTimer=null;else if(M._socketTimeout)M._socketTimer=globalThis.setTimeout(function(){M.emit("timeout")},M._socketTimeout)},V.prototype.abort=V.prototype.destroy=function(F){var M=this;if(M._destroyed=!0,M._resetTimers(!0),M._response)M._response._destroyed=!0;if(M._xhr)M._xhr.abort();else if(M._fetchAbortController)M._fetchAbortController.abort();if(F)M.emit("error",F)},V.prototype.end=function(F,M,k){var f=this;if(typeof F==="function")k=F,F=void 0;Z.Writable.prototype.end.call(f,F,M,k)},V.prototype.setTimeout=function(F,M){var k=this;if(M)k.once("timeout",M);k._socketTimeout=F,k._resetTimers(!1)},V.prototype.flushHeaders=function(){},V.prototype.setNoDelay=function(){},V.prototype.setSocketKeepAlive=function(){};var w=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","date","dnt","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","via"]}),OW=h0(($,q)=>{q.exports=K;var Q=Object.prototype.hasOwnProperty;function K(){var J={};for(var Z=0;Z{q.exports=(I7(),X0(R7)).STATUS_CODES}),TW=h0(($)=>{var q=xW(),Q=oK(),K=OW(),J=PW(),Z=(v7(),X0(H7)),G=$;G.request=function(W,B){if(typeof W==="string")W=Z.parse(W);else W=K(W);var V=globalThis.location.protocol.search(/^https?:$/)===-1?"http:":"",U=W.protocol||V,w=W.hostname||W.host,F=W.port,M=W.path||"/";if(w&&w.indexOf(":")!==-1)w="["+w+"]";W.url=(w?U+"//"+w:"")+(F?":"+F:"")+M,W.method=(W.method||"GET").toUpperCase(),W.headers=W.headers||{};var k=new q(W);if(B)k.on("response",B);return k},G.get=function(W,B){var V=G.request(W,B);return V.end(),V},G.ClientRequest=q,G.IncomingMessage=Q.IncomingMessage,G.Agent=function(){},G.Agent.defaultMaxSockets=4,G.globalAgent=new G.Agent,G.STATUS_CODES=J,G.METHODS=["CHECKOUT","CONNECT","COPY","DELETE","GET","HEAD","LOCK","M-SEARCH","MERGE","MKACTIVITY","MKCOL","MOVE","NOTIFY","OPTIONS","PATCH","POST","PROPFIND","PROPPATCH","PURGE","PUT","REPORT","SEARCH","SUBSCRIBE","TRACE","UNLOCK","UNSUBSCRIBE"]}),aK=RW(TW(),1),{request:uW,get:SW,ClientRequest:EW,IncomingMessage:_W,Agent:cW,globalAgent:bW,STATUS_CODES:nW,METHODS:dW}=aK.default,mW=aK.default});var sK={};c1(sK,{validateHeaderValue:()=>MB,validateHeaderName:()=>FB,setMaxIdleHTTPParsers:()=>zB,request:()=>BB,maxHeaderSize:()=>WB,globalAgent:()=>GB,get:()=>ZB,default:()=>wB,createServer:()=>UB,ServerResponse:()=>VB,Server:()=>JB,STATUS_CODES:()=>KB,OutgoingMessage:()=>qB,METHODS:()=>QB,IncomingMessage:()=>$B,ClientRequest:()=>eW,Agent:()=>tW});var pW,iW,lK,oW,aW,lW=($,q,Q)=>{Q=$!=null?pW(iW($)):{};let K=q||!$||!$.__esModule?lK(Q,"default",{value:$,enumerable:!0}):Q;for(let J of oW($))if(!aW.call(K,J))lK(K,J,{get:()=>$[J],enumerable:!0});return K},rW=($,q)=>()=>(q||$((q={exports:{}}).exports,q),q.exports),sW,rK,tW,eW,$B,QB,qB,KB,JB,VB,UB,ZB,GB,WB,BB,zB,FB,MB,wB;var tK=b1(()=>{pW=Object.create,{getPrototypeOf:iW,defineProperty:lK,getOwnPropertyNames:oW}=Object,aW=Object.prototype.hasOwnProperty,sW=rW(($,q)=>{var Q=(I7(),X0(R7)),K=(v7(),X0(H7)),J=$;for(Z in Q)if(Q.hasOwnProperty(Z))J[Z]=Q[Z];var Z;J.request=function(W,B){return W=G(W),Q.request.call(this,W,B)},J.get=function(W,B){return W=G(W),Q.get.call(this,W,B)};function G(W){if(typeof W==="string")W=K.parse(W);if(!W.protocol)W.protocol="https:";if(W.protocol!=="https:")throw Error('Protocol "'+W.protocol+'" not supported. Expected "https:"');return W}}),rK=lW(sW(),1),{Agent:tW,ClientRequest:eW,IncomingMessage:$B,METHODS:QB,OutgoingMessage:qB,STATUS_CODES:KB,Server:JB,ServerResponse:VB,createServer:UB,get:ZB,globalAgent:GB,maxHeaderSize:WB,request:BB,setMaxIdleHTTPParsers:zB,validateHeaderName:FB,validateHeaderValue:MB}=rK,wB=rK});var V9=globalThis;if(typeof V9.global>"u")V9.global=globalThis;t0();var Uz=K9(h9(),1);var _7=K9(HK(),1);function W2($,q,Q,K){function J(Z){return Z instanceof Q?Z:new Q(function(G){G(Z)})}return new(Q||(Q=Promise))(function(Z,G){function W(U){try{V(K.next(U))}catch(w){G(w)}}function B(U){try{V(K.throw(U))}catch(w){G(w)}}function V(U){U.done?Z(U.value):J(U.value).then(W,B)}V((K=K.apply($,q||[])).next())})}var L0=914400,w8=12700,n0=`\r -`,NB=2147483649,C7=/^[0-9a-fA-F]{6}$/,YB=1.67,kB=27,H6={type:"solid",color:"666666",pt:1},JJ=[0.05,0.1,0.05,0.1],v6={color:"363636",pt:1},u1={color:"888888",style:"solid",size:1,cap:"flat"},Q2="000000",k2=12,DB=18,f6="LAYOUT_16x9",h7="DEFAULT",VJ="333333",P1={type:"outer",blur:3,offset:1.811023622047244,angle:90,color:"000000",opacity:0.35,rotateWithShape:!0},M8=[0.5,0.5,0.5,0.5],eK={color:"000000"},LB={size:8,color:"FFFFFF",opacity:0.75},o2="2094734552",N5="2094734553",B8="2094734554",x7="2094734555",UJ="2094734556",W8="ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""),z8=["C0504D","4F81BD","9BBB59","8064A2","4BACC6","F79646","628FC6","C86360","C0504D","4F81BD","9BBB59","8064A2","4BACC6","F79646","628FC6","C86360"],HB=["5DA5DA","FAA43A","60BD68","F17CB0","B2912F","B276B2","DECF3F","F15854","A7A7A7","5DA5DA","FAA43A","60BD68","F17CB0","B2912F","B276B2","DECF3F","F15854","A7A7A7"],R6;(function($){$.left="left",$.center="center",$.right="right",$.justify="justify"})(R6||(R6={}));var I6;(function($){$.b="b",$.ctr="ctr",$.t="t"})(I6||(I6={}));var ZJ="{F7021451-1387-4CA6-816F-3879F97B5CBC}",O7;(function($){$.arraybuffer="arraybuffer",$.base64="base64",$.binarystring="binarystring",$.blob="blob",$.nodebuffer="nodebuffer",$.uint8array="uint8array"})(O7||(O7={}));var P7;(function($){$.area="area",$.bar="bar",$.bar3d="bar3D",$.bubble="bubble",$.bubble3d="bubble3D",$.doughnut="doughnut",$.line="line",$.pie="pie",$.radar="radar",$.scatter="scatter"})(P7||(P7={}));var T7;(function($){$.accentBorderCallout1="accentBorderCallout1",$.accentBorderCallout2="accentBorderCallout2",$.accentBorderCallout3="accentBorderCallout3",$.accentCallout1="accentCallout1",$.accentCallout2="accentCallout2",$.accentCallout3="accentCallout3",$.actionButtonBackPrevious="actionButtonBackPrevious",$.actionButtonBeginning="actionButtonBeginning",$.actionButtonBlank="actionButtonBlank",$.actionButtonDocument="actionButtonDocument",$.actionButtonEnd="actionButtonEnd",$.actionButtonForwardNext="actionButtonForwardNext",$.actionButtonHelp="actionButtonHelp",$.actionButtonHome="actionButtonHome",$.actionButtonInformation="actionButtonInformation",$.actionButtonMovie="actionButtonMovie",$.actionButtonReturn="actionButtonReturn",$.actionButtonSound="actionButtonSound",$.arc="arc",$.bentArrow="bentArrow",$.bentUpArrow="bentUpArrow",$.bevel="bevel",$.blockArc="blockArc",$.borderCallout1="borderCallout1",$.borderCallout2="borderCallout2",$.borderCallout3="borderCallout3",$.bracePair="bracePair",$.bracketPair="bracketPair",$.callout1="callout1",$.callout2="callout2",$.callout3="callout3",$.can="can",$.chartPlus="chartPlus",$.chartStar="chartStar",$.chartX="chartX",$.chevron="chevron",$.chord="chord",$.circularArrow="circularArrow",$.cloud="cloud",$.cloudCallout="cloudCallout",$.corner="corner",$.cornerTabs="cornerTabs",$.cube="cube",$.curvedDownArrow="curvedDownArrow",$.curvedLeftArrow="curvedLeftArrow",$.curvedRightArrow="curvedRightArrow",$.curvedUpArrow="curvedUpArrow",$.custGeom="custGeom",$.decagon="decagon",$.diagStripe="diagStripe",$.diamond="diamond",$.dodecagon="dodecagon",$.donut="donut",$.doubleWave="doubleWave",$.downArrow="downArrow",$.downArrowCallout="downArrowCallout",$.ellipse="ellipse",$.ellipseRibbon="ellipseRibbon",$.ellipseRibbon2="ellipseRibbon2",$.flowChartAlternateProcess="flowChartAlternateProcess",$.flowChartCollate="flowChartCollate",$.flowChartConnector="flowChartConnector",$.flowChartDecision="flowChartDecision",$.flowChartDelay="flowChartDelay",$.flowChartDisplay="flowChartDisplay",$.flowChartDocument="flowChartDocument",$.flowChartExtract="flowChartExtract",$.flowChartInputOutput="flowChartInputOutput",$.flowChartInternalStorage="flowChartInternalStorage",$.flowChartMagneticDisk="flowChartMagneticDisk",$.flowChartMagneticDrum="flowChartMagneticDrum",$.flowChartMagneticTape="flowChartMagneticTape",$.flowChartManualInput="flowChartManualInput",$.flowChartManualOperation="flowChartManualOperation",$.flowChartMerge="flowChartMerge",$.flowChartMultidocument="flowChartMultidocument",$.flowChartOfflineStorage="flowChartOfflineStorage",$.flowChartOffpageConnector="flowChartOffpageConnector",$.flowChartOnlineStorage="flowChartOnlineStorage",$.flowChartOr="flowChartOr",$.flowChartPredefinedProcess="flowChartPredefinedProcess",$.flowChartPreparation="flowChartPreparation",$.flowChartProcess="flowChartProcess",$.flowChartPunchedCard="flowChartPunchedCard",$.flowChartPunchedTape="flowChartPunchedTape",$.flowChartSort="flowChartSort",$.flowChartSummingJunction="flowChartSummingJunction",$.flowChartTerminator="flowChartTerminator",$.folderCorner="folderCorner",$.frame="frame",$.funnel="funnel",$.gear6="gear6",$.gear9="gear9",$.halfFrame="halfFrame",$.heart="heart",$.heptagon="heptagon",$.hexagon="hexagon",$.homePlate="homePlate",$.horizontalScroll="horizontalScroll",$.irregularSeal1="irregularSeal1",$.irregularSeal2="irregularSeal2",$.leftArrow="leftArrow",$.leftArrowCallout="leftArrowCallout",$.leftBrace="leftBrace",$.leftBracket="leftBracket",$.leftCircularArrow="leftCircularArrow",$.leftRightArrow="leftRightArrow",$.leftRightArrowCallout="leftRightArrowCallout",$.leftRightCircularArrow="leftRightCircularArrow",$.leftRightRibbon="leftRightRibbon",$.leftRightUpArrow="leftRightUpArrow",$.leftUpArrow="leftUpArrow",$.lightningBolt="lightningBolt",$.line="line",$.lineInv="lineInv",$.mathDivide="mathDivide",$.mathEqual="mathEqual",$.mathMinus="mathMinus",$.mathMultiply="mathMultiply",$.mathNotEqual="mathNotEqual",$.mathPlus="mathPlus",$.moon="moon",$.noSmoking="noSmoking",$.nonIsoscelesTrapezoid="nonIsoscelesTrapezoid",$.notchedRightArrow="notchedRightArrow",$.octagon="octagon",$.parallelogram="parallelogram",$.pentagon="pentagon",$.pie="pie",$.pieWedge="pieWedge",$.plaque="plaque",$.plaqueTabs="plaqueTabs",$.plus="plus",$.quadArrow="quadArrow",$.quadArrowCallout="quadArrowCallout",$.rect="rect",$.ribbon="ribbon",$.ribbon2="ribbon2",$.rightArrow="rightArrow",$.rightArrowCallout="rightArrowCallout",$.rightBrace="rightBrace",$.rightBracket="rightBracket",$.round1Rect="round1Rect",$.round2DiagRect="round2DiagRect",$.round2SameRect="round2SameRect",$.roundRect="roundRect",$.rtTriangle="rtTriangle",$.smileyFace="smileyFace",$.snip1Rect="snip1Rect",$.snip2DiagRect="snip2DiagRect",$.snip2SameRect="snip2SameRect",$.snipRoundRect="snipRoundRect",$.squareTabs="squareTabs",$.star10="star10",$.star12="star12",$.star16="star16",$.star24="star24",$.star32="star32",$.star4="star4",$.star5="star5",$.star6="star6",$.star7="star7",$.star8="star8",$.stripedRightArrow="stripedRightArrow",$.sun="sun",$.swooshArrow="swooshArrow",$.teardrop="teardrop",$.trapezoid="trapezoid",$.triangle="triangle",$.upArrow="upArrow",$.upArrowCallout="upArrowCallout",$.upDownArrow="upDownArrow",$.upDownArrowCallout="upDownArrowCallout",$.uturnArrow="uturnArrow",$.verticalScroll="verticalScroll",$.wave="wave",$.wedgeEllipseCallout="wedgeEllipseCallout",$.wedgeRectCallout="wedgeRectCallout",$.wedgeRoundRectCallout="wedgeRoundRectCallout"})(T7||(T7={}));var G2;(function($){$.text1="tx1",$.text2="tx2",$.background1="bg1",$.background2="bg2",$.accent1="accent1",$.accent2="accent2",$.accent3="accent3",$.accent4="accent4",$.accent5="accent5",$.accent6="accent6"})(G2||(G2={}));var u7;(function($){$.left="left",$.center="center",$.right="right",$.justify="justify"})(u7||(u7={}));var S7;(function($){$.top="top",$.middle="middle",$.bottom="bottom"})(S7||(S7={}));var B1;(function($){$.ACTION_BUTTON_BACK_OR_PREVIOUS="actionButtonBackPrevious",$.ACTION_BUTTON_BEGINNING="actionButtonBeginning",$.ACTION_BUTTON_CUSTOM="actionButtonBlank",$.ACTION_BUTTON_DOCUMENT="actionButtonDocument",$.ACTION_BUTTON_END="actionButtonEnd",$.ACTION_BUTTON_FORWARD_OR_NEXT="actionButtonForwardNext",$.ACTION_BUTTON_HELP="actionButtonHelp",$.ACTION_BUTTON_HOME="actionButtonHome",$.ACTION_BUTTON_INFORMATION="actionButtonInformation",$.ACTION_BUTTON_MOVIE="actionButtonMovie",$.ACTION_BUTTON_RETURN="actionButtonReturn",$.ACTION_BUTTON_SOUND="actionButtonSound",$.ARC="arc",$.BALLOON="wedgeRoundRectCallout",$.BENT_ARROW="bentArrow",$.BENT_UP_ARROW="bentUpArrow",$.BEVEL="bevel",$.BLOCK_ARC="blockArc",$.CAN="can",$.CHART_PLUS="chartPlus",$.CHART_STAR="chartStar",$.CHART_X="chartX",$.CHEVRON="chevron",$.CHORD="chord",$.CIRCULAR_ARROW="circularArrow",$.CLOUD="cloud",$.CLOUD_CALLOUT="cloudCallout",$.CORNER="corner",$.CORNER_TABS="cornerTabs",$.CROSS="plus",$.CUBE="cube",$.CURVED_DOWN_ARROW="curvedDownArrow",$.CURVED_DOWN_RIBBON="ellipseRibbon",$.CURVED_LEFT_ARROW="curvedLeftArrow",$.CURVED_RIGHT_ARROW="curvedRightArrow",$.CURVED_UP_ARROW="curvedUpArrow",$.CURVED_UP_RIBBON="ellipseRibbon2",$.CUSTOM_GEOMETRY="custGeom",$.DECAGON="decagon",$.DIAGONAL_STRIPE="diagStripe",$.DIAMOND="diamond",$.DODECAGON="dodecagon",$.DONUT="donut",$.DOUBLE_BRACE="bracePair",$.DOUBLE_BRACKET="bracketPair",$.DOUBLE_WAVE="doubleWave",$.DOWN_ARROW="downArrow",$.DOWN_ARROW_CALLOUT="downArrowCallout",$.DOWN_RIBBON="ribbon",$.EXPLOSION1="irregularSeal1",$.EXPLOSION2="irregularSeal2",$.FLOWCHART_ALTERNATE_PROCESS="flowChartAlternateProcess",$.FLOWCHART_CARD="flowChartPunchedCard",$.FLOWCHART_COLLATE="flowChartCollate",$.FLOWCHART_CONNECTOR="flowChartConnector",$.FLOWCHART_DATA="flowChartInputOutput",$.FLOWCHART_DECISION="flowChartDecision",$.FLOWCHART_DELAY="flowChartDelay",$.FLOWCHART_DIRECT_ACCESS_STORAGE="flowChartMagneticDrum",$.FLOWCHART_DISPLAY="flowChartDisplay",$.FLOWCHART_DOCUMENT="flowChartDocument",$.FLOWCHART_EXTRACT="flowChartExtract",$.FLOWCHART_INTERNAL_STORAGE="flowChartInternalStorage",$.FLOWCHART_MAGNETIC_DISK="flowChartMagneticDisk",$.FLOWCHART_MANUAL_INPUT="flowChartManualInput",$.FLOWCHART_MANUAL_OPERATION="flowChartManualOperation",$.FLOWCHART_MERGE="flowChartMerge",$.FLOWCHART_MULTIDOCUMENT="flowChartMultidocument",$.FLOWCHART_OFFLINE_STORAGE="flowChartOfflineStorage",$.FLOWCHART_OFFPAGE_CONNECTOR="flowChartOffpageConnector",$.FLOWCHART_OR="flowChartOr",$.FLOWCHART_PREDEFINED_PROCESS="flowChartPredefinedProcess",$.FLOWCHART_PREPARATION="flowChartPreparation",$.FLOWCHART_PROCESS="flowChartProcess",$.FLOWCHART_PUNCHED_TAPE="flowChartPunchedTape",$.FLOWCHART_SEQUENTIAL_ACCESS_STORAGE="flowChartMagneticTape",$.FLOWCHART_SORT="flowChartSort",$.FLOWCHART_STORED_DATA="flowChartOnlineStorage",$.FLOWCHART_SUMMING_JUNCTION="flowChartSummingJunction",$.FLOWCHART_TERMINATOR="flowChartTerminator",$.FOLDED_CORNER="folderCorner",$.FRAME="frame",$.FUNNEL="funnel",$.GEAR_6="gear6",$.GEAR_9="gear9",$.HALF_FRAME="halfFrame",$.HEART="heart",$.HEPTAGON="heptagon",$.HEXAGON="hexagon",$.HORIZONTAL_SCROLL="horizontalScroll",$.ISOSCELES_TRIANGLE="triangle",$.LEFT_ARROW="leftArrow",$.LEFT_ARROW_CALLOUT="leftArrowCallout",$.LEFT_BRACE="leftBrace",$.LEFT_BRACKET="leftBracket",$.LEFT_CIRCULAR_ARROW="leftCircularArrow",$.LEFT_RIGHT_ARROW="leftRightArrow",$.LEFT_RIGHT_ARROW_CALLOUT="leftRightArrowCallout",$.LEFT_RIGHT_CIRCULAR_ARROW="leftRightCircularArrow",$.LEFT_RIGHT_RIBBON="leftRightRibbon",$.LEFT_RIGHT_UP_ARROW="leftRightUpArrow",$.LEFT_UP_ARROW="leftUpArrow",$.LIGHTNING_BOLT="lightningBolt",$.LINE_CALLOUT_1="borderCallout1",$.LINE_CALLOUT_1_ACCENT_BAR="accentCallout1",$.LINE_CALLOUT_1_BORDER_AND_ACCENT_BAR="accentBorderCallout1",$.LINE_CALLOUT_1_NO_BORDER="callout1",$.LINE_CALLOUT_2="borderCallout2",$.LINE_CALLOUT_2_ACCENT_BAR="accentCallout2",$.LINE_CALLOUT_2_BORDER_AND_ACCENT_BAR="accentBorderCallout2",$.LINE_CALLOUT_2_NO_BORDER="callout2",$.LINE_CALLOUT_3="borderCallout3",$.LINE_CALLOUT_3_ACCENT_BAR="accentCallout3",$.LINE_CALLOUT_3_BORDER_AND_ACCENT_BAR="accentBorderCallout3",$.LINE_CALLOUT_3_NO_BORDER="callout3",$.LINE_CALLOUT_4="borderCallout4",$.LINE_CALLOUT_4_ACCENT_BAR="accentCallout3=4",$.LINE_CALLOUT_4_BORDER_AND_ACCENT_BAR="accentBorderCallout4",$.LINE_CALLOUT_4_NO_BORDER="callout4",$.LINE="line",$.LINE_INVERSE="lineInv",$.MATH_DIVIDE="mathDivide",$.MATH_EQUAL="mathEqual",$.MATH_MINUS="mathMinus",$.MATH_MULTIPLY="mathMultiply",$.MATH_NOT_EQUAL="mathNotEqual",$.MATH_PLUS="mathPlus",$.MOON="moon",$.NON_ISOSCELES_TRAPEZOID="nonIsoscelesTrapezoid",$.NOTCHED_RIGHT_ARROW="notchedRightArrow",$.NO_SYMBOL="noSmoking",$.OCTAGON="octagon",$.OVAL="ellipse",$.OVAL_CALLOUT="wedgeEllipseCallout",$.PARALLELOGRAM="parallelogram",$.PENTAGON="homePlate",$.PIE="pie",$.PIE_WEDGE="pieWedge",$.PLAQUE="plaque",$.PLAQUE_TABS="plaqueTabs",$.QUAD_ARROW="quadArrow",$.QUAD_ARROW_CALLOUT="quadArrowCallout",$.RECTANGLE="rect",$.RECTANGULAR_CALLOUT="wedgeRectCallout",$.REGULAR_PENTAGON="pentagon",$.RIGHT_ARROW="rightArrow",$.RIGHT_ARROW_CALLOUT="rightArrowCallout",$.RIGHT_BRACE="rightBrace",$.RIGHT_BRACKET="rightBracket",$.RIGHT_TRIANGLE="rtTriangle",$.ROUNDED_RECTANGLE="roundRect",$.ROUNDED_RECTANGULAR_CALLOUT="wedgeRoundRectCallout",$.ROUND_1_RECTANGLE="round1Rect",$.ROUND_2_DIAG_RECTANGLE="round2DiagRect",$.ROUND_2_SAME_RECTANGLE="round2SameRect",$.SMILEY_FACE="smileyFace",$.SNIP_1_RECTANGLE="snip1Rect",$.SNIP_2_DIAG_RECTANGLE="snip2DiagRect",$.SNIP_2_SAME_RECTANGLE="snip2SameRect",$.SNIP_ROUND_RECTANGLE="snipRoundRect",$.SQUARE_TABS="squareTabs",$.STAR_10_POINT="star10",$.STAR_12_POINT="star12",$.STAR_16_POINT="star16",$.STAR_24_POINT="star24",$.STAR_32_POINT="star32",$.STAR_4_POINT="star4",$.STAR_5_POINT="star5",$.STAR_6_POINT="star6",$.STAR_7_POINT="star7",$.STAR_8_POINT="star8",$.STRIPED_RIGHT_ARROW="stripedRightArrow",$.SUN="sun",$.SWOOSH_ARROW="swooshArrow",$.TEAR="teardrop",$.TRAPEZOID="trapezoid",$.UP_ARROW="upArrow",$.UP_ARROW_CALLOUT="upArrowCallout",$.UP_DOWN_ARROW="upDownArrow",$.UP_DOWN_ARROW_CALLOUT="upDownArrowCallout",$.UP_RIBBON="ribbon2",$.U_TURN_ARROW="uturnArrow",$.VERTICAL_SCROLL="verticalScroll",$.WAVE="wave"})(B1||(B1={}));var q0;(function($){$.AREA="area",$.BAR="bar",$.BAR3D="bar3D",$.BUBBLE="bubble",$.BUBBLE3D="bubble3D",$.DOUGHNUT="doughnut",$.LINE="line",$.PIE="pie",$.RADAR="radar",$.SCATTER="scatter"})(q0||(q0={}));var D5;(function($){$.TEXT1="tx1",$.TEXT2="tx2",$.BACKGROUND1="bg1",$.BACKGROUND2="bg2",$.ACCENT1="accent1",$.ACCENT2="accent2",$.ACCENT3="accent3",$.ACCENT4="accent4",$.ACCENT5="accent5",$.ACCENT6="accent6"})(D5||(D5={}));var W1;(function($){$.chart="chart",$.image="image",$.line="line",$.rect="rect",$.text="text",$.placeholder="placeholder"})(W1||(W1={}));var D0;(function($){$.chart="chart",$.hyperlink="hyperlink",$.image="image",$.media="media",$.online="online",$.placeholder="placeholder",$.table="table",$.tablecell="tablecell",$.text="text",$.notes="notes"})(D0||(D0={}));var F8;(function($){$.title="title",$.body="body",$.image="pic",$.chart="chart",$.table="tbl",$.media="media"})(F8||(F8={}));var C6;(function($){$.DEFAULT="•",$.CHECK="✓",$.STAR="★",$.TRIANGLE="▶"})(C6||(C6={}));var j6="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAB3CAYAAAD1oOVhAAAGAUlEQVR4Xu2dT0xcRRzHf7tAYSsc0EBSIq2xEg8mtTGebVzEqOVIolz0siRE4gGTStqKwdpWsXoyGhMuyAVJOHBgqyvLNgonDkabeCBYW/8kTUr0wsJC+Wfm0bfuvn37Znbem9mR9303mJnf/Pb7ed95M7PDI5JIJPYJV5EC7e3t1N/fT62trdqViQCIu+bVgpIHEo/Hqbe3V/sdYVKHyWSSZmZm8ilVA0oeyNjYmEnaVC2Xvr6+qg5fAOJAz4DU1dURGzFSqZRVqtMpAFIGyMjICC0vL9PExIRWKADiAYTNshYWFrRCARAOEFZcCKWtrY0GBgaUTYkBRACIE4rKZwqACALR5RQAqQCIDqcASIVAVDsFQCSAqHQKgEgCUeUUAPEBRIVTAMQnEBvK5OQkbW9vk991CoAEAMQJxc86BUACAhKUUwAkQCBBOAVAAgbi1ykAogCIH6cAiCIgsk4BEIVAZJwCIIqBVLqiBxANQFgXS0tLND4+zl08AogmIG5OSSQS1gGKwgtANAIRcQqAaAbCe6YASBWA2E6xDyeyDUl7+AKQMkDYYevm5mZHabA/Li4uUiaTsYLau8QA4gLE/hU7wajyYtv1hReDAiAOxQcHBymbzark4BkbQKom/X8dp9Npmpqasn4BIAYAYSnYp+4BBEAMUcCwNOCQsAKZnp62NtQOw8WmwT09PUo+ijaHsOMx7GppaaH6+nolH0Z10K2tLVpdXbW6UfV3mNqBdHd3U1NTk2rtlMRfW1uj2dlZAFGirkRQAJEQTWUTAFGprkRsAJEQTWUTAFGprkRsAJEQTWUTAFGprkRsAJEQTWUTAFGprkRsAJEQTWUTAFGprkRsAJEQTWUTAGHqrm8caPzQ0WC1logbeiC7X3xJm0PvUmRzh45cuki1588FAmVn9BO6P3yF9utrqGH0MtW82S8UN9RA9v/4k7InjhcJFTs/TLVXLwmJV67S7vD7tHF5pKi46fYdosdOcOOGG8j1OcqefbFEJD9Q3GCwDhqT31HklS4A8VRgfYM2Op6k3bt/BQJl58J7lPvwg5JYNccepaMry0LPqFA7hCm39+NNyp2J0172b19QysGINj5CsRtpij57musOViH0QPJQXn6J9u7dlYJSFkbrMYolrwvDAJAC+WWdEpQz7FTgECeUCpzi6YxvvqXoM6eEhqnCSgDikEzUKUE7Aw7xuHctKB5OYU3dZlNR9syQdAaAcAYTC0pXF+39c09o2Ik+3EqxVKqiB7hbYAxZkk4pbBaEM+AQofv+wTrFwylBOQNABIGwavdfe4O2pg5elO+86l99nY58/VUF0byrYsjiSFluNlXYrOHcBar7+EogUADEQ0YRGHbzoKAASBkg2+9cpM1rV0tK2QOcXW7bLEFAARAXIF4w2DrDWoeUWaf4hQIgDiA8GPZ2iNfi0Q8UACkAIgrDbrJ385eDxaPLLrEsFAB5oG6lMPJQPLZZZKAACBGVhcG2Q+bmuLu2nk55e4jqPv1IeEoceiBeX7s2zCa5MAqdstl91vfXwaEGsv/rb5TtOFk6tWXOuJGh6KmnhO9sayrMninPx103JBtXblHkice58cINZP4Hyr5wpkgkdiChEmc4FWazLzenNKa/p0jncwDiqcD6BuWePk07t1asatZGoYQzSqA4nFJ7soNiP/+EUyfc25GI2GG53dHPrKo1g/1Cw4pIXLrzO+1c+/wg7tBbFDle/EbQcjFCPWQJCau5EoBoFpzXHYDwFNJcDiCaBed1ByA8hTSXA4hmwXndAQhPIc3lAKJZcF53AMJTSHM5gGgWnNcdgPAU0lwOIJoF53UHIDyFNJcfSiCdnZ0Ui8U0SxlMd7lcjubn561gh+Y1scFIU/0o/3sgeLO12E2k7UXKYumgFoAYdg8ACIAYpoBh6cAhAGKYAoalA4cAiGEKGJYOHAIghilgWDpwCIAYpoBh6cAhAGKYAoalA4cAiGEKGJYOHAIghilgWDpwCIAYpoBh6ZQ4JB6PKzviYthnNy4d9h+1M5mMlVckkUjsG5dhiBMCEMPg/wuOfrZZ/RSywQAAAABJRU5ErkJggg==",vB="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB4AAAAVnCAYAAACzfHDVAAAAYHpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjaVcjJDYAwDEXBu6ughBfH+YnLQSwSHVA+Yrkwx7HtPHabHuEWrQ+lBBAZ6TMweBWoCwUH8quZH6VWFXVT696zxp12ARkVFEqn8wB8AAAACXBIWXMAAC4jAAAuIwF4pT92AADZLklEQVR42uzdd5hV9Z0/8M+dmcsUZmDovYOhKCiKYhR7JJuoSTCWGFI0WUxijBoTTXazVlyza4maYm9rTRSJigVsqCDNQhHBAogKCEgRMjMMU+7vj93sL8kqClLmnPt6PY+PeXZM9vP9vO8jZ+Y955xMfJLjorBrRMuSgmiViyjN1Ee2oSCyucbIBAAAAAAAAADbXaYgcoWNUZcrirpMbdRsysa69wbF+rggGrf439vSF7seF12aFUTnxvoosGIAAAAAAACAXacgoqEgF++/VRgr4r5o+Kh/pvD//F8uiII+LaPrum/EXzqui2b1ddHGKgEAAAAAAAB2rVxEQWMmWrQtjHZlA6N2w2tR84//zP8pgHu3ib6NBdG+zdqorK6KVUXZaB85j3sGAAAAAAAAaAoaG6OwIBdtyneP2PBabPzbr/1dAdx3VHRtyESHiIhcYzQrLo7WmVzkcjmPgAYAAAAAAABoSgpy0eIfS+D/LYD7fy3abC6Inn/7X2hsjELlLwAAAAAAAEDT9D8lcM1fHwddFBFxyAVR9M686PVp/gfqayKiJiLqLBMAAAAAAABgh8hGRGlEUekn/6PFEb3ikNgQk6O+KCJi6dzoksv83/cB/1X9xoiaJdmoWxlRV1dk2QAAAAAAAAA7QTZbH9muERX96v7n9t7/q6Exinq3i86LI94pjOOisHUu+uYykfmof7h+Y8Sa6aVRt74gGhs9DRoAAAAAAABgZ2lsLIi69QWxeUUmSjs0/vedwR8hk4uydSfE+wVd6qOyMfMx7/mtj9jwUtbjngEAAAAAAAB2obrqolg7IxtR/9Ffb4wo7P5GtCwobRaVH/c/UvNmNuqqPfIZAAAAAAAAYFerqy6KmjezH/v1ktpoVZBr/PgCeMN7yl8AAAAAAACApmJLHW5jUVQWNDSP+Q3ZeLco4i9/+8X6teHRzwAAAAAAAABNSd3/dLn/oLAoqqIuVhXFxhhSGB/xqGjlLwAAAAAAAECTU1eTjaK/KXSLIv7SWB+bc5ko9YxnAAAAAAAAgATJFv393bz1EeV//c8F1gMAAAAAAACQDgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKSEAhgAAAAAAAAgJRTAAAAAAAAAACmhAAYAAAAAAABICQUwAAAAAAAAQEoogAEAAAAAAABSQgEMAAAAAAAAkBIKYAAAAAAAAICUUAADAAAAAAAApIQCGAAAAAAAACAlFMAAAAAAAAAAKaEABgAAAAAAAEgJBTAAAAAAAABASiiAAQAAAAAAAFJCAQwAAAAAAACQEgpgAAAAAAAAgJRQAAMAAAAAAACkhAIYAAAAAAAAICUUwAAAAAAAAAApoQAGAAAAAAAASAkFMAAAAAAAAEBKKIABAAAAAAAAUkIBDAAAAAAAAJASCmAAAAAAAACAlFAAAwAAAAAAAKREkRUAAACwrUpLSwuGDRvWfMCAAS26du3avKysrLiioqKkZcuWzZs1a1bcvHnz0tLS0rJsNtusuLi4ebNmzUoLCgo+8/eijY2N9Zs3b66pra2tqqur21xTU1NdVVVVs2nTptqNGzdWbdiwoeYvf/nL5hUrVlQtWLBgw6xZs6pqamoaJQYAAEDaKYABAACIiIghQ4aUHnTQQW379u3bql27dq3at2/fpkWLFq2bN29eWVpa2qpZs2bNCwsLm2ez2fLCwsLyoqKi8sLCwtKknK+hoaG6vr6+qqGh4S91dXV/aWhoqNq8eXNVTU3NuqqqqvUbNmxYu2rVqjWrV69e99Zbb6177rnnPpgzZ06NTwYAAABJogAGAADIA8OGDWt+xBFHdBwwYECnLl26dGjdunXHFi1adCgtLe1YUlLSvlmzZq0KCgqK07yDwsLCssLCwrKIaPdp/zuNjY21mzdvXrdp06ZVNTU172/YsGHl2rVr31+2bNnKBQsWrHjyySffnzVrVpVPGAAAAE1Fpuexsd9HfaF+ZcSal0ptCAAAIAE6deqUPf744zvtueeeXbp3796lbdu2XSorKzuXlpZ2KS0t7VBYWFhhSztGQ0PDxpqampU1NTXL169fv+yDDz5Y9s477yybPXv2sj/96U8rVqxYUWdLAAAAbE9t9q6Jog4f/TUFMAAAQEJks9nMt7/97Y4jRozo1bdv397t2rXrXl5e3rWsrKxzcXFx+4gosKUmp7G2tnZVTU3Nso0bNy5btWrV0tdff/2tJ598cvG999672noAAADYFgpgAACAhPne977X6a9Fb/v27Xu1bNmyV1lZWa8kvXOXLauvr9/wl7/8ZdG6desWL1u2bNHChQsX/fGPf1w8derUjbYDAADAliiAAQAAmqhsNps59dRTuxx66KH9+/Tp87n27dv3Ly8v719UVOSRzXlq06ZNKzZu3Pj6+++//8abb775xqOPPvrG3XffvcpmAAAA+CsFMAAAQBNx6qmndvniF784qHfv3v3btWv3uYqKis8VFhaW2wxbUl9fv37Dhg1vfPDBB68vXrz4jccee2z+jTfeuNxmAAAA8pMCGAAAYBc45phjWn/rW9/aq3///kPatGnTv6Kiop9HOLO9NDQ0VG/cuPGtNWvWLFy4cOGcO+6445WHHnporc0AAACknwIYAABgJzjjjDO6f+lLX9qrV69eg1u3bj2orKysR0RkbIadJFddXb103bp18xcvXjz30UcffeXqq69+x1oAAADSRwEMAACwnZWWlhb86le/2u3QQw8d1r17931btmw5qLCwsMxmaEoaGhqqP/zww/nvvPPOzGeeeWbW2LFj36ipqWm0GQAAgGRTAAMAAGwHP/7xj7t+9atf3bdXr15D27Ztu1c2m21jKyRJXV3dmg8++OCVRYsWvfznP/95xh/+8IdltgIAAJA8CmAAAIBtcOKJJ7Y75ZRTDujXr9+w1q1bD81ms61shTSpq6tbt3bt2pfffPPNWbfccsvUe++9d7WtAAAANH0KYAAAgE+hoqKi4IILLhg0YsSI/bp27bpfy5YtB2YymUKbIR/kcrmGDz/8cP6777474/nnn59x4YUXvrZx40aPiwYAAGiCFMAAAAAf4/jjj2/7/e9//8D+/fsf2Lp1630KCgpKbAUiGhsbN61fv37eW2+9NeWGG2545u67715lKwAAAE2DAhgAAOB/ZLPZzAUXXPC5I4888sDu3bsfWFFRsVtEFNgMbFl1dfWSd999d8qsWbNmnnvuuS+vW7euwVYAAAB2DQUwAACQ10pLSwsuvfTSQYcccsjBXbt2HVFWVtbDVmDb1dbWrnr//fdfmDp16uRf/vKXL65evbreVgAAAHYeBTAAAJB3Bg0aVHrBBRd8fs899zywQ4cOBxQVFbWwFdj+Ghsba9euXTtrzpw5T59//vmTX3755WpbAQAA2LEUwAAAQF4YNmxY8/POO+/gIUOGHOZ9vrDz/W0ZfNFFFz07a9asKlsBAADY/hTAAABAarVq1arwyiuv3HfEiBEjO3TocFBhYWGZrcCu19DQUP3+++8/O2XKlIk/+clPZm7cuLHRVgAAALYPBTAAAJAqrVq1Kvztb3+7/3777Xd4x44dRxQWFpbbCjRdDQ0NG99///0pM2bMeOqHP/zhC8pgAACAz0YBDAAApMJZZ53V45vf/OaRvXr1GllaWtrVRiB5ampq3l28ePHEO++8c9LVV1/9jo0AAABsPQUwAACQWMOHDy+/6KKLvjB48OCjW7RoMdBGID0+/PDDV+fNmzfhvPPOe3L69Ol/sREAAIBPRwEMAAAkSqtWrQpvuOGGQ/bbb79/atOmzX6ZTCZrK5BeuVyubs2aNTNmzJjx2JgxYyavW7euwVYAAAA+ngIYAABIhB//+Mddv/e9732lZ8+e/1RcXNzWRiD/1NbWfvD2228/dssttzz029/+9l0bAQAA+L8UwAAAQJNVUVFRcO21137+4IMPPrZ169b7ZTKZAlsBIqJxzZo1M59//vnxp5122hR3BQMAAPx/CmAAAKDJOeWUUzqefvrpx/bu3ftL2Wy2jY0AH6e+vn7j0qVLH/vd7373x+uvv36ZjQAAAPlOAQwAADQJ2Ww2c+uttx5wyCGHnNC6deu9I8LdvsDWaFy7du1L06ZN+/OPfvSjZ1evXl1vJQAAQD5SAAMAALtU//79S6655pp/2nPPPY8tLy/vayPAZ1VTU7NswYIF488999wHp06dutFGAACAfKIABgAAdomf//znPU855ZQTu3btemRhYWGZjQDbW2NjY92KFSuevOWWW+689NJLF9kIAACQDxTAAADATuMxz8Cusn79+rlPP/30f5188slT6+rqcjYCAACklQIYAADY4fr27Vv8hz/84a+Pee5nI8CuUlNT8+68efPu/8EPfvDgwoULN9kIAACQNgpgAABghxkyZEjpNddc89XBgwefWFxc3MFGgKaitrZ21dy5c+/5yU9+8uc5c+bU2AgAAJAWWyqAPYoNAADYJqNHj+4wb968n06ZMuXRYcOGnaH8BZqa4uLi9sOGDTtjypQpj86bN++nJ510UntbAQAA0s4dwAAAwFY599xze33/+9//dufOnY/IZDJZGwGSIpfL1S1fvvzJG2644fbLLrvsbRsBAACSyiOgAQCAz+y8887r+53vfOfbHTt2PDyTyRTaCJBUuVyuYcWKFU/cdNNN//XrX/96sY0AAABJowAGAAC22WWXXTboG9/4xg9at249zDaAtFm7du2su++++9pzzjnnNdsAAACSQgEMAABsNcUvkE8UwQAAQJIogAEAgE9N8Qvks7Vr18665557rvv5z38+3zYAAICmaksFcGHlwOj6UV9orIqoWZG1PQAAyBO/+MUvet9xxx3nHHrooT8pLS3tYiNAPiotLe2y7777HvP973+/X1lZ2ZIpU6assxUAAKCpKetcHwXlH/01BTAAAOS5M844o/u99957zpe//OWflZeX94qIjK0AeS5TXl7e8+CDDx71/e9/v3dEvDVjxowPrQUAAGgqFMAAAMD/ceKJJ7a77777fjJq1Kh/KS8v7xOKX4B/lCkvL+99+OGHj/rWt77VfvXq1Qvnz59fbS0AAMCutqUC2DuAAQAgzwwdOrTs+uuvP6l///4nFRYWltkI20NjY2Ns2rQpqquro6amJurr62PTpk2xefPmqK+vj+rq6qivr4/NmzfHpk2boqGhYZv/fxUWFkZJSUk0a9YsioqKoqysLIqKiqJZs2ZRUlISRUVFUVpa+r9/FRQUCIjtoqGhoeq11167a8yYMffMmTOnxkYAAIBdZUvvAFYAAwBAnujUqVP2nnvuGbXXXnudnM1mK22Ej9PQ0BAbN26MDRs2/J+/Nm7cGBs3boyamprYtGlTbNq0KWpqaqK2trbJnqe4uDhKSkqitLT0f/9eUVERFRUV0aJFi//zV0VFRRQWFvog8LHq6urWvvjii7eceOKJf169enW9jQAAADubAhgAAPLcXXfdddAXv/jF00tLS7vZRn7L5XKxYcOGWLt2baxbty7Wrl37d3+tW7cuNmzYkPd7atGiRbRu3TpatWoVrVu3jjZt2vzvf27dunW0aNHCh4morq5e+sgjj1zzne98Z6ptAAAAO5MCGAAA8tTVV189+MQTTzyzoqJioG3kj8bGxli5cmUsX748Pvjgg1i9evX//n3t2rXR2NhoSZ9RYWFhtGrVKtq1axdt27b937937tw5OnTo4LHTeWbDhg3z77333qvOPPPMebYBAADsDApgAADIM1/72tfaXHrppad27979qIjQRKVUQ0NDrFq1KlasWBHvv//+//595cqVTfqRzGlXXFwcHTp0iI4dO0bnzp2jY8eO0alTp2jXrp1HS6dYLpdrfOeddx76+c9/fv2ECRPW2QgAALAjKYABACBP9OrVq9ldd931jT322OM7hYWFZTaSHh9++GG88847sXTp0njvvfdixYoVsXr16mhoaLCchCgsLIz27dtHp06dolu3btG9e/fo3r27x0mnTENDQ9W8efNu++Y3v/nHJUuWbLYRAABgR1AAAwBAHrjrrrtG/NM//dOZJSUlXWwj2davXx9Lly6Nd955539L3w8//NBiUqqysvJ/y+C//tWqVSuLSbiamppljz322G9Gjx49xTYAAIDtTQEMAAAp9qtf/arPD3/4w5+1atVqL9tIno0bN8aSJUvirbfeikWLFsV7770XmzZtspg8V1JSEl27do0+ffpE3759o3fv3lFeXm4xCbRu3bqXr7322ivGjh27yDYAAIDtRQEMAAApNGjQoNI77rjju7vttttJBQUFWRtJhtWrV8ebb74ZixcvjiVLlsTy5cujsbHRYtiigoKC6Ny5c/Tu3Tt69+4d/fr1i7Zt21pMQjQ2Nta98cYbd33rW9+6ff78+TU2AgAAfFYKYAAASJHS0tKCBx988Jj99tvvn7PZbBsbaboaGhri7bffjrfeeisWLFgQS5YscXcv201FRUX06tUr+vbtG3379o2ePXtGYWGhxTRhdXV1a2bMmHHjV77ylYdqamr85gcAALDNFMAAAJASp59+erdf/vKX51ZWVu5jG03T6tWr47XXXouFCxfGm2++GRs3brQUdooWLVpE3759Y8CAATFw4EB3CDdh69evf/E//uM//vPqq69+xzYAAIBtoQAGAICEGzRoUOm99977w969ex+byWTc4teErF+/PubNmxcLFiyIN954Q+FLk9GiRYvo169fDBgwIPbYY4+orKy0lCYkl8s1LF68eNyJJ554rcdCAwAAW0sBDAAACXbNNdcMOemkk35RVlbWyzZ2vVwuF++++27MnTs3XnvttViyZIl3+NLkFRQURK9evWLQoEExePDg6Natm6U0EdXV1UvuvvvuX//kJz+ZYxsAAMCnpQAGAIAEOuqoo1r99re//VmHDh0Ot41da9OmTTF79uyYO3duLFy4MKqqqiyFRGvevHn0798/Bg8eHHvuuWeUlJRYyi62cuXKp04//fTLJ0yYsM42AACAT6IABgCAhBk3btwRRxxxxFnZbLaNbewaVVVVMXfu3Jg7d27Mnz8/amtrLYVUKi4ujoEDB8bgwYNj8ODBUV5ebim7SF1d3ZqnnnrqqlGjRj1hGwAAwJYogAEAICFOOeWUjhdddNEvW7duvZ9t7HwrV66MWbNmxdy5c+Odd96JXC5nKeSdzp07x9577x3Dhg2LDh06WMgusHbt2hnnnXfepbfccsv7tgEAAHwUBTAAADRxpaWlBU899dQ3Bw8e/L2CggLPYt2JVqxYES+99FK89NJLsXz5cguBv/HXMnjvvfeOTp06WchO1NjYuGnu3Lk3H3744XfV1NR40TgAAPB3FMAAANCEjR49usOll176yzZt2gy3jZ1j/fr18eKLL8bMmTNj6dKlFgKfQs+ePWPfffeNYcOGRYsWLSxkJ1mzZs0L55577q/vvvvuVbYBAAD8lQIYAACaoIqKioKJEyd+c/Dgwd8vKCgotpEda8OGDfHiiy/G9OnTlb7wGfXo0SOGDx8ew4YNi4qKCgvZwdwNDAAA/CMFMAAANDGnnHJKx7Fjx/5rZWXlMNvYcerr6+PVV1+NGTNmxLx586Kurs5SYDvKZrMxZMiQ2HfffWP33XePwsJCS9mB1q5dO+MXv/jFv995550rbQMAAPKbAhgAAJqIbDabeeKJJ47fZ599fuSu3x0jl8vFwoULY/r06TF79uzYtGmTpcBOUFpaGkOGDInhw4fHgAEDLGQHaWhoqJ42bdo1Rx555J9tAwAA8pcCGAAAmoDjjz++7ZVXXvmr1q1be9fvDrBmzZqYNm1azJw5M1audHMc7EodO3aMz3/+87H//vt7X/CO+3fetDPPPPOScePGfWAbAACQfxTAAACwi9100037HXvssf9WXFzc1ja2n1wuF6+99lo8//zzMW/evKivr7cUaEKKiopizz33jBEjRsTnPve5yGQylrId1dbWrvrjH/948Q9+8INZtgEAAPlFAQwAALvIkCFDSu+///5zunTp8k+2sf2sXbs2Jk+eHNOnT48PP/zQQiABKisrY8SIEXHIIYdEeXm5hWxHy5Yte+zrX//6f86ZM6fGNgAAID9sqQAurBwYXT/qC41VETUrsrYHAADb6IILLtjt97///VVt2rQZZhvbx+LFi2P8+PFx9913xxtvvBG1tbWWAgmxadOmeOONN+LZZ5+NtWvXRps2bTweejtp0aJFv5NOOumg0tLSuc8+++xaGwEAgPQr61wfBR/zu7XuAAYAgO0sm81mJk2a9PVhw4b9pKCgwG9VfkZ1dXUxY8aMeOaZZ+K9996zEEiRfv36xSGHHBJDhw6NgoICC/mMGhsbN8+YMeOaL37xi+Pq6upyNgIAAOnlEdAAALCTHH/88W2vuuqqCyorK/exjc9mzZo18dRTT8XUqVNj06ZNFgIpVlFREZ///OfjsMMOi8rKSgv5jNavXz/r9NNPv3DcuHEf2AYAAKSTAhgAAHaC22677fNf+9rXzstms5W2se0WLVoUjz/+eMybNy9yOTewQT4pKiqKIUOGxBFHHBG9e/e2kM+grq5u3QMPPHDRySefPM02AAAgfRTAAACwA1VUVBQ8/fTTpwwcOPCUTCbjGabbIJfLxauvvhpPPvlkLFy40EIgz2UymRgwYEAcccQRMWjQIAvZ9n+3Ns6fP/+Www8//JaNGzc22ggAAKTHlgrgwsqB0fWjvtBYFVGzwuvKAABgS0488cR2EyZMuLx79+5fzmQyGRvZOo2NjTFr1qy49dZb48knn4wPPvC0UuC/rV69OmbMmBFz5syJ0tLS6NSpU/jX7NbJZDKZ9u3bD/3+978/dPny5TNfffXValsBAIB0KOtcHwXlH/O9gDuAAQBg29x66637H3vssRcWFRW1sI2tU1NTE0899VQ8++yzsWHDBgsBPlGLFi3i4IMPjsMPPzxKS/28YmvV19d/OG7cuPNPPvnk6bYBAADJ5xHQAACwHWWz2cyzzz77rSFDhvzAI5+3zqZNm2Ly5Mnx1FNPKX6BbdKiRYs47LDD4pBDDlEEb6VcLtfwyiuvXHfooYfeWVdX5yXrAACQYApgAADYTo455pjW11133cWVlZV728ant2HDhnj88cdjypQpUVtbayHAZ1ZcXBwHHnhgfPGLX4wWLTyIYWusWbNm2re//e3zn3nmGb+JAwAACeUdwAAAsB1cfvnlu1900UW/LS8v72cbn05VVVVMmDAhbrnllnjzzTejoaHBUoDtoqGhIZYsWRLPPfdc1NTURI8ePSKb9XOMT6OsrKzb17/+9SPbtm0774knnlhtIwAAkMDreu8ABgCAz+bhhx/+8qGHHnpOQUFBsW18sk2bNsUzzzwTTzzxRFRVVVkIsMOVl5fHkUceGYccckgUF/tX9afR2Ni46emnn/71Mccc87htAABAsngENAAAbKN27doVTZ48+YxevXodZxufrK6uLp5++umYOHGi4hfYJSoqKuKLX/xiHHzwwe4I/pQWLVr0x4MOOuiadevWeUwDAAAkhEdAAwDANjj22GPbPvzww7/p2LHjobaxZXV1dfHkk0/GddddF3Pnzo26ujpLAXaJzZs3x2uvvRbPPfdcRET06NEjCgsLLWYLWrduvfv3vve9fd9+++1pCxYsqLYRAABo+rb0CGgFMAAAfITLL7989wsuuOB3zZs372UbH6+xsTGmTJkS119/fbzyyiuKX6DJ2Lx5cyxYsCCmT58excXF0a1bt8hkMhbzMUpKSjp8+ctfPrJt27ZzvBcYAACaPu8ABgCArTB+/Pgjv/CFL/xLQUFBiW18vAULFsT48eNj6dKllgE0eT169IivfOUrMWjQIMvYgsbGxpqJEydecuyxxz5pGwAA0HR5BzAAAHwK7dq1K3ruued+1qNHj6/axsdbtGhR3H///bF48WLLABKnV69ecdxxx0WfPn0sYwuWLl3654MOOujy1atX19sGAAA0Pd4BDAAAn2DYsGHNn3766V936tTpC7bx0TZs2BD33Xdf/PGPf4y1a9daCJBI69evj2nTpsW6deuiZ8+eUVLiYQ8fpbKysv+3v/3t/lOmTJmyfPlyz/cHAIAmxjuAAQBgC372s5/1uP76669t0aKF54J+hJqamhg/fnzcfPPN8fbbb0cul7MUINFyuVy888478cwzz0RVVVX07t07slk/A/lHZWVl3U488cTD6+rqZkyfPv1DGwEAgCZ0va4ABgCAj3bFFVfscdZZZ11dXFzcwTb+Xi6XixkzZsR1110XCxYsiMbGRksBUqWxsTGWLFkSM2bMiPLy8ujSpUtkMhmL+RvZbLbFQQcddHibNm1mP/HEE6ttBAAAmoYtFcDeAQwAQN6aNGnSqAMOOODsTCZTaBt/b9GiRXHPPffEu+++axlA3ujWrVucdNJJ0bt3b8v4B7lcrm7y5Mm//vKXv/yIbQAAwK63pXcAK4ABAMg7paWlBTNnzjyzT58+x9vG39uwYUOMGzcuZsyY4VHPQF7KZDKx3377xde//vWoqKiwkH+waNGiP+27775X1dTUeCwEAADsQgpgAAD4H926dctOnjz5V506dRppG/9fLpeLqVOnxp///OfYuHGjhQB5r6KiIkaNGhX777+/x0L/g+XLlz9+6KGHXvLuu+/W2QYAAOwaWyqAvQMYAIC8MXz48PInnnjiynbt2o2wjf/vnXfeiWuvvTaee+652Lx5s4UARMTmzZtjzpw58dprr0XPnj2jRYsWlvI/Kioq+n7rW98aMnXq1Ofee+89f3AAAMAusKV3ACuAAQDIC9/+9rc73n777X9o0aLFANv4b1VVVXHXXXfFvffeG+vXr7cQgI+wbt26eP7552P9+vWx2267RVFRkaVERElJSefjjjvuoA8++GDKK6+88hcbAQCAnUsBDABAXjv//PP7XXzxxX8oKSnpbBv/bfr06XHttdfGokWLLAPgU3jnnXdi2rRp0bp16+jc2R8nERHZbLbyC1/4whElJSUvTp48eY2NAADAzqMABgAgb/3ud7/b60c/+tFVRUVFrWwjYs2aNXHzzTfHpEmTora21kIAtkJtbW289NJL8c4770Tfvn2jtLQ073dSWFhYNnz48C/26dNn4UMPPbTMpwQAAHYOBTAAAHnp1ltv3f+b3/zmfxYWFjbP913kcrl4/vnn4/rrr4/ly5f7cAB8BitXroxp06ZFRUVFdOvWLTKZTF7vo6CgIDto0KBDBw0atOiBBx54xycEAAB2vC0VwJmex8Z+H/WF+pURa17ym6wAACTTww8//KXDDjvsXzKZTN6/rPGDDz6I22+/Pd544w0fDIDtbMCAAfGtb30r2rRpk/e7yOVyjVOmTPn1yJEjH/LJAACAHavN3jVR1OGjv6YABgAgdV555ZXTPve5z30r3/fQ0NAQjz32WDz++ONRV1fngwGwg2Sz2Tj66KPjC1/4QhQUFOT9Pl5//fU79tprr9/7ZAAAwI6jAAYAIC9ks9nMyy+/fFafPn2Oz/ddvPvuu3HbbbfFe++954MBsJN069YtvvOd70S3bt3yfhdLliy5f5999rmypqam0ScDAAC2PwUwAACpV1paWjBr1qyzevfufVw+7yGXy8WTTz4ZDz74oLt+AXaBbDYbxxxzTBxxxBF5fzfw0qVLHxg6dOjlSmAAANj+FMAAAKRar169mk2ePHlsu3btDsrnPaxcuTJuueWWePvtt30oAHaxnj17ximnnBIdOnTI6z2sXr16yiGHHPIvS5Ys2exTAQAA28+WCuDCyoHR9aO+0FgVUbMia3sAADRpQ4cOLXvqqacub9Omzf75uoNcLhfPPPNMXH/99bF27VofCoAmYP369TFlypQoKSmJnj17RiaTycs9NG/evPtJJ500ZPLkyc+sWLHCoykAAGA7KetcHwXlH/01BTAAAIk1ZMiQ0kceeeSKVq1a7Z2vO6iuro7bb789nnjiiWhs9IRNgKaksbEx5s+fH++//34MGDAgstn8/DlLaWlpp6997WuDn3rqqadXrlxZ75MBAACfnQIYAIDUOfTQQ1s8+OCDv2/ZsuUe+bqDOXPmxNVXX+2RzwBN3PLly+OFF16Ijh075u0joUtLSzudcMIJ+7/00ktPv/3227U+FQAA8NkogAEASJVhw4Y1v++++37TsmXLQfl4/vr6+hg/fnz88Y9/jNpaP0MHSILNmzfHiy++GJs3b47ddtstCgoK8m4HxcXFbY866qg9n3vuuaeXL1/ucdAAAPAZKIABAEiNI488snLcuHG/b9GixcB8PP97770XV111VcyZM8eHASCBFi1aFC+//HL069cvWrRokXfnLykp6XDcccftP2fOnGcWLVq0yScCAAC2jQIYAIBUOPLIIyvvvPPO35aXl++Wj+d/+umn48Ybb4wPP/zQhwEgwf7yl7/ECy+8ECUlJdGrV6+8O3+zZs3aHHXUUfspgQEAYNspgAEASLxjjz227W233faH5s2b98m3s1dVVcXNN98cTz31VDQ2NvowAKRAY2NjzJ8/P5YtWxYDBgyIZs2a5dX5mzVr1uaYY4458M0333xm4cKFNT4RAACwdRTAAAAk2qGHHtritttuuzofy9+33347rrnmmli8eLEPAkAKvf/++/HKK69Enz59orKyMq/Ons1mK4888sh9Zs6c+dTSpUs3+zQAAMCnpwAGACCxjjjiiJb33nvvteXl5f3y6dy5XC4mTZoUN998c1RVVfkgAKRYVVVVTJ06NbLZbPTp0ycymUzenL24uLjtV7/61c+/8sorTy1evLjWpwEAAD4dBTAAAIl06KGHtrj33nt/l2/lb3V1ddx0000xefLkyOVyPggAeSCXy8WCBQvi3Xffjd133z2y2fz5mUyzZs1aH3300fvNmDHjSXcCAwDAp6MABgAgcYYOHVo2fvz4qysqKgbk07mXLVsWV111lUc+A+SplStXxiuvvBKf+9znoqKiIm/O3axZszZHH3300GeeeebJFStW1PkkAADAlimAAQBIlCFDhpQ++uij17Rs2XL3fDr31KlT49prr42NGzf6EADksaqqqpg+fXq0bds2unTpkjfnLikpaT9q1KihTz755JMrV66s90kAAICPt6UCuMB6AABoSjp16pSdMGHCv1dWVu6RL2dubGyMcePGxR133BF1dW56AiCitrY2br755hg/fnw0NjbmzbkrKyv3mDBhwr9369bNXQkAALCNFMAAADQZrVq1Kpw+ffolbdq02T9fzlxdXR2/+93vYtKkSd73C8DfyeVy8fjjj8fvf//7qK6uzptzt2nTZv8pU6Zc0qpVq0KfAgAA2HoKYAAAmoSKioqC2bNnX9KuXbuD8uXMS5cujYsuuijmz5/vAwDAx3r11VfjoosuiqVLl+bNmdu1a3fQ7Nmz/72iosLPrgAAYCu5iAYAoEmYOXPmz9q1a3dIvpz35ZdfjiuuuCLWrVsnfAA+0bp16+KKK66Il19+OW/O3K5du4Nnzpz5M+kDAMDWUQADALDLvfjii2N69OgxKh/Omsvl4oEHHogbbrghamtrhQ/Ap1ZbWxs33HBDPPDAA3nz2oAePXqMevHFF8dIHwAAPj0FMAAAu9SkSZO+NnDgwFPy4ax1dXVx8803x8SJE73vF4BtksvlYuLEiXHLLbdEXV1dXpx54MCBJ0+aNOlr0gcAgE9HAQwAwC7z6KOPHnXggQeekw9nXbduXfz617+OWbNmCR6Az2zmzJnx61//Ol9eJZA58MADz3n00UePkjwAAHyywsqB0fWjvtBYFVGzImtDAADsEDfeeOO+Rx999EWZTKYw7Wddvnx5XHXVVbFy5UrBA7DdbNiwIWbPnh0DBw6MioqKtB8307179/179uz56sMPP7xc+gAA5LuyzvVRUP7RX1MAAwCw011xxRV7fPe7372qoKCgWdrPOmfOnPjtb38bGzduFDwA2111dXVMmzYtOnfuHB07dkz1WTOZTOHuu+9+eJs2bV6aNGnSKukDAJDPFMAAADQZZ5xxRvef/exnvy0sLCxP+1knTJgQd999d9TX1wsegB2moaEhXnrppchms9G3b99UnzWTyRTttddeB/3lL395dubMmRukDwBAvlIAAwDQJBx00EEVf/jDH64pLi7ulOZz5nK5eOCBB+Kxxx4TOgA77c+eBQsWRF1dXfTv3z8ymUxqz1pQUFBywAEHDJs+ffqkpUuXbpY+AAD5aEsFcIH1AACwMwwaNKj0vvvuu7qsrKxXms9ZV1cX1113XUyaNEnoAOx0EydOjOuvvz7q6upSfc6ysrJef/rTn67u379/idQBAODvKYABANjhKioqCh577LGLKyoqBqb5nNXV1XHNNdfE7NmzhQ7ALvPKK6/ElVdeGVVVVak+Z4sWLQZOnDhxbEVFhZ9vAQDA33CBDADADjdz5syftW3b9sA0n3HdunVx2WWXxRtvvCFwAHa5xYsXx2WXXRZr165N9TnbtWt34MyZM38mcQAA+P8UwAAA7FBPPvnkqB49eoxK8xlXrVoVV1xxRSxfvlzgADQZK1asiCuuuCJWrlyZ6nP26NFj1KRJk0ZJHAAA/lth5cDo+lFfaKyKqFmRtSEAALbZjTfeuO+XvvSlCzOZTGp/8fDdd9+NK6+8MtatWydwAJqc6urqmDVrVvTv3z8qKytTe85u3boN79mz57yHH37Yb2MBAJAXyjrXR0H5R39NAQwAwA5x3nnn9T311FOvLigoKE7rGV977bW45pprorq6WuAANFmbN2+OGTNmRI8ePaJ9+/apPGMmkykYNGjQIYWFhVOee+45v5UFAEDqKYABANipjjrqqFb/8R//8YdmzZq1SusZX3755bj++uujrq5O4AA0eQ0NDfHSSy9Fp06dolOnTqk8Y0FBQXbYsGGfnz9//qQ33nhjk9QBAEizLRXA3gEMAMB21a1bt+wNN9zwnyUlJR3TesYpU6bEjTfeGPX19QIHIDHq6+vjxhtvjKlTp6b2jCUlJZ1uuOGG/+jWrZu7GgAAyFsKYAAAtqunn376XyorK/dI6/kmTZoUd955ZzQ2NgobgMRpbGyMO+64I5588snUnrGysnLw008//UtpAwCQrxTAAABsN88///w3unTp8k9pPd/EiRNj3LhxkcvlhA1AYuVyubj//vtTXQJ36dLlS88+++yJ0gYAIB95BzAAANvFTTfdNPzII488L5PJZNJ4vsceeyzGjx8vaABS47XXXotmzZpF3759U3m+zp0779urV695Dz/88DJpAwCQNlt6B7ACGACAz+wXv/hF7x/+8IdXFxQUNEvj+R544IF45JFHBA1A6ixYsCDq6upiwIABqTtbJpPJDBo06ODGxsbnpk6dul7aAACkiQIYAIAd5oADDqj43e9+99tmzZq1TeP5xo0bF5MmTRI0AKm1aNGi2Lx5cwwcODB1ZysoKMjut99+w5577rnH33vvvc3SBgAgLbZUAHsHMAAA2yybzWbuvPPOfyktLe2exvNNmDBB+QtAXpg0aVI89NBDqTxbaWlpj3vuuedfstlsRtIAAOQDBTAAANvs+eef/06HDh0OTePZHn744Xj44YeFDEDeeOSRR+LPf/5zKs/WoUOHw5599tlvSxkAgHygAAYAYJvcd999hw8ePPjUNJ7t/vvvjwkTJggZgLzz2GOPxX333ZfKs+25554/+NOf/nSYlAEASDvvAAYAYKudccYZ3ceMGXN5QUFBcdrONnHixHjkkUeEDEDeWrx4cWSz2ejbt2/ajpbp06fPvn/5y18mz5w5c4OkAQBIsi29A1gBDADAVhk2bFjzG2+88Q/NmjVrl7azPfroo6l99CUAbI2FCxdGUVFR9OvXL1XnKigoKD7wwAP3e/LJJx9dsWJFnaQBAEiqLRXAHgENAMBWuffee39ZWlraPW3nevzxx+PBBx8UMAD8jz//+c8xceLE1J2rtLS0x3333fdLCQMAkFYKYAAAPrVJkyaN6tSp0xEpPFeMHz9ewADwD8aPHx+TJ09O3bk6der0hUmTJn1VwgAApJFHQAMA8Kmcd955fU888cR/z2QyRWk618yZM+Puu+8WMAB8jNdeey06duwYnTt3TtW5unbtuk9BQcHzzz333DopAwCQNN4BDADAZ3LEEUe0vOKKK67NZrOVaTrXyy+/HDfffHPkcjkhA8DHyOVyMXv27OjSpUt06tQpNefKZDJF++yzz/CpU6c+9u67726WNAAASeIdwAAAbLNsNpu55ZZb/q2kpKRjms61YMGCuPnmm6OxsVHIAPAJGhsb4+abb44333wzVecqLS3tcvfdd5+fzWYzUgYAIC0UwAAAbNGkSZO+3rZt2wPTdKZly5bFDTfcEPX19QIGgE+prq4urr322li+fHmqztWuXbsDH3/88VESBgAgLTwCGgCAj3XZZZcN+upXvzo2k8mk5hcH33///bjyyiujqqpKwACwlerq6uLll1+OIUOGRHl5eWrO1aVLl31LS0unPvPMM2ukDABAEngENAAAW61///4lJ5988q8ymUxRWs60YcOG+P3vfx8bN24UMABso40bN8bvfve7VP15WlBQkP3hD394ft++fYslDABA4q9vrQAAgI/y4IMPnl1WVtYrLeeprq6O3/zmN7Fq1SrhAsBntGrVqrjyyiujuro6NWcqKyvr8/DDD58lXQAAkk4BDADA/zF+/Pgju3XrdnRazlNfX5/KdxYCwK60fPnyuO6666K+vj41Z+rRo8dXx40bd4R0AQBIMgUwAAB/53vf+16nI4444py0nCeXy8Vtt90Wb7zxhnABYDt7/fXX47bbbotcLpeaMx155JHnfvvb3+4oXQAAkkoBDADA/6qoqCi4+OKLLywsLCxPy5nGjx8fs2bNEi4A7CCzZs2Khx56KDXnKSwsrPj1r399QUVFhZ+bAQCQSC5kAQD4XxMnThxdWVk5OC3nef7552PixImCBYAd7LHHHosXXnghNeeprKzc89FHHz1RsgAAJFFh5cDo+lFfaKyKqFmRtSEAgDxxwQUX7DZq1KgLM5lMYRrO8+qrr8Ytt9ySqkdSAkBT/7O3d+/e0a5du1Scp2PHjkNzudxzU6ZMWSddAACamrLO9VHwMc/wcwcwAADRt2/f4h//+McXZzKZVPwG4HvvvRc33HBDNDY2ChcAdpKGhoa47rrrYtmyZak4T0FBQfbss88e27dv32LpAgCQqGtZKwAAYPz48T8qKyvrkYazbNiwIX7/+99HbW2tYAFgJ9u0aVP8/ve/j40bN6biPGVlZb3GjRs3RrIAACSJAhgAIM/ddNNNw/v06XN8Gs5SX18f1157baxdu1awALCLrFmzJq699tqor69PxXn69ev3jd///vdDJQsAQFIogAEA8thBBx1Uceyxx/5rRGTScJ477rgjFi9eLFgA2MUWLVoUd955Z1qOU/CNb3zj34YNG9ZcsgAAJOIC1goAAPLXzTfffFZxcXG7NJxl4sSJMX36dKECQBMxbdq0mDRpUirOUlJS0unOO+88Q6oAACSBAhgAIE/913/914FdunT5UhrO8tprr8Wf//xnoQJAEzN+/PhYsGBBKs7SrVu3o2+66abhUgUAoKlTAAMA5KEvfelLlV/5yld+lYazrFixIq6//vpobGwULAA0MY2NjXHdddfFihUr0nCczHHHHfergw46qEKyAAA0ZQpgAIA8dPXVV5+ezWYrk36OmpqauPbaa2PTpk1CBYAmatOmTXHttddGTU1N4s+SzWbb3njjjT+RKgAATZkCGAAgz9x6663Du3Tp8uWknyOXy8Utt9wSK1euFCoANHErV66MW2+9NXK5XOLP4lHQAAA0dQpgAIA8MnTo0LKvfvWrv0jDWSZMmBBz584VKgAkxJw5c+Kxxx5LxVlGjRr1i6FDh5ZJFQCApkgBDACQR+64444fFRcXd0z6OV5++eV45JFHBAoACfPQQw+l4he4SkpKOt5xxx0/lCgAAE2RAhgAIE9cfvnlu/fs2XNU0s/xwQcfxB133JGKR0gCQL7J5XJx2223xZo1axJ/lp49ex57+eWX7y5VAACaGgUwAEAe6NatW/a73/3uv2YymURf/9XX18cNN9wQ1dXVQgWAhKqqqoobb7wx6uvrE32OTCZT8N3vfvdX3bp1y0oVAICmRAEMAJAHxo8ff0pZWVmvpJ/jnnvuiaVLlwoUABJuyZIlcd999yX+HGVlZT3Hjx9/ikQBAGhKFMAAACn385//vOeAAQNGJ/0c06dPjylTpggUAFJi8uTJMWPGjMSfY8CAAaN//vOf95QoAABNhQIYACDFstls5qyzzjo3k8kk+tGEK1asiLvvvlugAJAyd911V6xYsSLRZ8hkMtmzzjrr3Gw2m5EoAABNgQIYACDFxo0b98XKysq9knyG2trauOGGG6K2tlagAJAyf/1zfvPmzYk+R2Vl5V7jxo0bKVEAAJoCBTAAQEoNHz68/OCDDz4t6ee4//77Y/ny5QIFgJRavnx5jBs3LvHnGDFixI+HDRvWXKIAAOxqCmAAgJS69dZbT8tms22TfIYZM2bEc889J0wASLnJkyfHzJkzE32G4uLitrfffvtp0gQAYFdTAAMApNBVV121R48ePb6S5DOsXLky7rrrLmECQJ64++6744MPPkj0GXr27PnVK664Yg9pAgCwKymAAQBSprS0tOAb3/jGT5N8rdfY2Bi333679/4CQB6pqamJ2267LRobG5N8jIJvfvObZ5aWlvqZGwAAu+6i1AoAANJlwoQJX6uoqBiQ5DOMHz8+Fi1aJEwAyDNvvvlmPPjgg4k+Q4sWLQY9+OCDx0gTAIBdRQEMAJAiRx55ZOWwYcN+kOQzzJ07N5544glhAkCemjhxYixYsCDRZxg+fPiPjjjiiJbSBABgV1AAAwCkyBVXXHFyUVFRRVLnr6qqijvvvDNyuZwwASBP5XK5uP3226O6ujqxZygqKmrxm9/85mRpAgCwKyiAAQBS4vzzz+/Xu3fv45J8httvvz0+/PBDYQJAnlu3bl3cfvvtiT5D7969jz///PP7SRMAgJ1NAQwAkALZbDZz6qmn/jyTyST2+m769OkxZ84cYQIAERExe/bsmDFjRmLnz2QyBaeeeurPs9lsRpoAAOxMCmAAgBT44x//eERlZeXgpM6/du3auPfeewUJAPyde+65J9atW5fY+SsrKwf/6U9/+oIkAQDYmRTAAAAJ17dv3+JDDjnkR0k+w9133x01NTXCBAD+Tk1NTdx9992JPsPBBx/8o759+xZLEwCAnUUBDACQcHfdddc3S0pKOiV1/smTJ8e8efMECQB8pLlz58azzz6b2PlLSko63nPPPd+SJAAAO4sCGAAgwb70pS9VDhw48KSkzr9mzZoYP368IAGALXrggQdizZo1iZ2/f//+Jx111FGtJAkAwM6gAAYASLArrrji1MLCwvIkzp7L5eK2226LTZs2CRIA2KJNmzbFbbfdFrlcLpHzFxYWll1++eU/kCQAADuDAhgAIKF+8Ytf9O7evftXkjr/s88+G2+88YYgAYBP5Y033ojnn38+sfN369bt6F/96ld9JAkAwI6mAAYASKgf/vCHP8pkMom8nvvggw/igQceECIAsFXGjRsX69atS+TsmUym4NRTT/2xFAEA2NEUwAAACXTdddcNa9eu3YFJnD2Xy8Udd9wRtbW1ggQAtsqmTZvizjvvTOz8bdq02f+mm27aT5IAAOxICmAAgIQpLS0t+NrXvnZ6Uud/4YUXYuHChYIEALbJq6++GjNmzEjs/Mccc8zpFRUVfiYHAMAO42ITACBhbr/99oMrKip2S+LsGzZsiHHjxgkRAPhM7r///qiqqkrk7OXl5X3/67/+6wgpAgCwoyiAAQASpKKiouCwww47Nanz33vvvYn9YS0A0HRs2LAh7r///sTOf9BBB/1zq1atCiUJAMCOoAAGAEiQ+++//+iysrKeSZx9zpw58dJLLwkRANguXnjhhViwYEEiZy8tLe32xz/+8StSBABgR1AAAwAkRN++fYv33Xfff07i7LW1tXHvvfcKEQDYru6+++6oq6tL5Oz77bffKf379y+RIgAA25sCGAAgIW6++eZRxcXFbZM4+yOPPBJr164VIgCwXa1atSoee+yxRM6ezWbb3njjjV+TIgAA25sCGAAgAYYOHVq21157fSeJs7/33nvxxBNPCBEA2CEmTpwYK1asSOTsQ4YM+c7QoUPLpAgAwPakAAYASIBrr732xKKiosqkzZ3L5eKee+6JxsZGIQIAO0R9fX3cddddkcvlEjd7UVFR5bXXXnuCFAEA2J4UwAAATdwBBxxQMWDAgG8kcfYZM2bEW2+9JUQAYId6880348UXX0zk7AMGDPjG8OHDy6UIAMD2ogAGAGjirrrqqhOKiooqkjb3pk2b4oEHHhAgALBT3H///VFbW5u4uYuKilpcffXV7gIGAGC7UQADADRhBx10UEX//v0Teffvww8/HB9++KEQAYCdYv369TFhwoREzj5w4MBvHHDAARVSBABge1AAAwA0Yf/5n/95bGFhYfOkzb1q1aqYPHmyAAGAnerpp5+O1atXJ27uwsLC8ssuu2yUBAEA2B4UwAAATdQBBxxQMWjQoNFJnP3uu++O+vp6IQIAO1V9fX3cddddiZx99913/+bQoUPLpAgAwGelAAYAaKIuv/zyYwsLC8uTNvfcuXNjwYIFAgQAdokFCxbE3LlzEzd3UVFRi9/97ndflyAAAJ+VAhgAoAkaOnRo2aBBgxL37t+6urr405/+JEAAYJf605/+FHV1dYmbe/fdd//mkCFDSiUIAMBnoQAGAGiCfvOb33ylqKioZdLmfu655xL53j0AIF1Wr14dzz33XOLmLioqann11VcfLUEAAD4LBTAAQBPTq1evZoMHD/5m0uaurq6ORx55RIAAQJPwyCOPRHV1deLmHjJkyLe6deuWlSAAANtKAQwA0MTcdNNNxxQXF7dN2twTJkyIqqoqAQIATUJVVVUifzmtuLi43a233uouYAAAtpkCGACgCWnVqlXhXnvtdVLS5l61alU8++yzAgQAmpTJkyfHqlWrEjf30KFDR7dq1apQggAAbAsFMABAE3LLLbccXlJS0jlpcz/44INRX18vQACgSamvr48HH3wwcXOXlJR0vummmw6VIAAA20IBDADQRGSz2cwBBxzw7aTNvWjRonjppZcECAA0SS+99FIsXrw4cXOPGDHiO9lsNiNBAAC2lgIYAKCJuOaaa/YuLy/vm7S5H3roocjlcgIEAJqkXC6XyLuAy8vL+1111VV7SRAAgK2lAAYAaCK+8pWvfDdpM8+bNy8WLlwoPACgSVu4cGG8+uqrrg8BAMgLCmAAgCbgsssuG1RZWblPkmbO5XIxfvx44QEAifDAAw8k7qklrVu33veSSy7pLz0AALaGAhgAoAkYNWrUCUmbefbs2bFs2TLhAQCJsGzZsnjllVcSN/cJJ5xwovQAANgaCmAAgF3sn//5nzt37NjxiCTN3NjYGA888IDwAIBEGT9+fDQ0NCRq5k6dOn1h9OjRHaQHAMCnpQAGANjFfvSjH30tk8kk6rps2rRpsWrVKuEBAImyatWqeOGFFxI1cyaTKfzpT386SnoAAHxaCmAAgF1o0KBBpX369Plqkmaur6+PCRMmCA8ASKQJEyZEXV1dombu27fvV/r27VssPQAAPg0FMADALnTZZZcdXlRUVJGkmadOnRpr164VHgCQSOvXr48pU6YkauaioqLK3/zmN0dIDwCAT0MBDACwi2Sz2cy+++57UpJmrqurc/cvAJB4jz76aOLuAt5///1PymazGekBAPBJFMAAALvI1VdfPbSsrKx3kmaeMmVKbNiwQXgAQKJt2LAhnn/++UTNXFZW1ueqq67aS3oAAHwSBTAAwC7y5S9/+bgkzVtfXx8TJ04UHACQCo8//nji7gL+0pe+dLzkAAD4JApgAIBdYPTo0R3atm07IkkzT5s2LdatWyc8ACAVPvzww5g+fXqiZm7fvv2I0aNHd5AeAABbogAGANgFfvrTn47KZDKFSZm3vr4+HnnkEcEBAKnyyCOPRH19fWLmzWQyhT/96U+/JjkAALZEAQwAsJN16tQp26dPn6OTNLO7fwGANFq3bl1MmzYtUTP36dPnmE6dOmWlBwDAx1EAAwDsZFddddUB2Wy2dVLmbWxsjEmTJgmOVOvYsWN06OCJmgD5aNKkSdHY2JiYebPZbOurrrrqAMkBAPBxFMAAADvZiBEjvp6keV988cVYtWqV4Ei1Ll26xIUXXhinnXZadO3a1UIA8siqVavipZdecj0JAEBqKIABAHaiM844o3tlZeXeSZk3l8vFxIkTBUdeyGQyMXjw4PjVr34VY8aMcUcwQB55/PHHI5fLJWbeysrKvc8444zukgMA4KMogAEAdqJTTjnlqxGRScq8CxYsiPfee09w5JVMJhN77713XHjhhTFmzJho3769pQCk3HvvvRcLFy5M1B9X/3NdCQAA/4cCGABgJ+nVq1ezXr16fTlJM3v3L/nsr0XwBRdcECeffHK0bdvWUgBSLGnXPb169fpyr169mkkOAIB/pAAGANhJrrjiioOLiopaJmXeBN4JAztEYWFhDB8+PC688MIYPXp0VFZWWgpACi1YsCCWLVuWmHmLiopaXnnllYdIDgCAf6QABgDYSYYPH/6VJM2btHfhwY5WVFQUI0aMiEsuuSRGjx4dLVu2tBSAFMnlcvH4448naub99tvvK5IDAOAfKYABAHaC0aNHd6isrByalHnXrl0bL7/8suDgI/y1CL744ovjhBNOiBYtWlgKQEq89NJLsW7dusTMW1lZudfo0aM7SA4AgL+lAAYA2AlOP/30o5J07fXMM89EQ0OD4GALiouL47DDDouxY8fGqFGjoqyszFIAEq6hoSGeeeaZJI1c8D/XmQAA8P8vEq0AAGDHymazmX79+n05KfPW1tbGlClTBAefUnFxcYwcOTIuvfTSGDVqVJSWlloKQII9//zzUVtbm5h5+/Xr9+VsNpuRHAAAf6UABgDYwX7zm9/sWVJS0jkp886YMSOqq6sFB1uppKQkRo4cGZdcckkcffTRUVJSYikACVRdXR0zZ85M0p8/na+44orBkgMA4K8UwAAAO9gXvvCFLyVl1lwuF08//bTQ4DNo3rx5HHXUUXHJJZfEyJEjI5vNWgpAwjz11FORy+USM++RRx75ZakBAPBXCmAAgB1oyJAhpZ07dz4iKfO+/vrrsWLFCsHBdlBeXh6jRo2KSy+9VBEMkDArVqyI119/PTHzdunS5fD+/ft79AQAABGhAAYA2KHGjh17aGFhYWJeCOruX9j+KioqYtSoUXHxxRfH4YcfHkVFRZYC4LpouyosLGz+H//xHwdLDQCACAUwAMAOteeeex6ZlFnXrl0b8+bNExrsIK1atYrjjz8+LrroohgxYkQUFPh2DKApmzdvXqxZsyYx8+61115HSg0AgAgFMADADnPMMce0bt269b5Jmfe5556LxsZGwcEO1qZNmxg9enRcfPHFimCAJqyxsTGee+65JP35MvyYY45pLTkAAPykAQBgBznzzDMPz2Qyibjeqq+vj6lTpwoNdqK2bdvG6NGj47zzzovhw4crggGaoBdeeCHq6+sTMWsmkyk844wzDpUaAAB+wgAAsIP079//C0mZdc6cObFhwwahwS7QqVOnOPnkk+Pf/u3fYu+9945MJmMpAE3Ehg0bYvbs2YmZd8CAAR4DDQCAAhgAYEf43ve+16mysnKPpMybpMcbQlp17tw5xowZE7/61a8UwQBNyPPPP5+YWSsrKwd/73vf6yQ1AID8pgAGANgBTj755CMiIhHtzcqVK+P1118XGjQRXbt2jTFjxsQ555wTgwcPthCAXez111+PlStXJmXczMknn3y41AAA8psCGABgB+jXr19iHv88ZcqUyOVyQoMmpnfv3nHaaafFOeecE/3797cQgF0kl8vFlClTknQd6jHQAAB5TgEMALCdnX766d0qKip2S8Ks9fX1MW3aNKFBE9anT58466yz4pxzzonddtvNQgB2gWnTpkV9fX0iZq2oqNjt9NNP7yY1AID8pQAGANjORo8efURSZp03b15s3LhRaJAAffr0ibPPPjvOPPPM6Nmzp4UA7EQbN26MefPmuR4FACARFMAAANtZr169EvPetSQ9zhD4bwMGDIhf/vKXceaZZ0b37t0tBGAnmTp1apKuRw+TGABA/lIAAwBsR2eccUb38vLyvkmYdf369fHaa68JDRJqwIAB8S//8i9x2mmnRbdunvQJsKPNnz8/Pvzww0TMWl5e3u9HP/pRF6kBAOQnBTAAwHZ03HHHHZSUWWfMmBGNjY1CgwTLZDIxePDg+Nd//dcYM2ZMdOjQwVIAdpDGxsaYMWNGYub9xje+cYjUAADykwIYAGA76tOnz8FJmDOXyyXqMYbAlmUymdh7773jwgsvjDFjxkT79u0tBWAHeOGFF5J0XXqIxAAA8pMCGABgOznppJPat2zZcvckzLpkyZJYuXKl0CBl/loEX3DBBXHyySdH27ZtLQVgO1qxYkW8/fbbiZi1srJy0PHHH+8PAgCAPKQABgDYTr773e8eGBGZJMyapMcXAluvsLAwhg8fHhdeeGGMHj06KisrLQVgO5k+fXpSRi34/ve/f6DEAADyjwIYAGA72X333Q9Nwpz19fUxc+ZMgUEeKCoqihEjRsQll1wSo0ePjpYtW1oKwGc0c+bMqK+vT8SsAwcOPFRiAAD5RwEMALAdHHTQQRUtW7bcKwmzLly4MKqrq4UGeeSvRfDFF18cJ5xwQrRo0cJSALZRVVVVvP7664mYtVWrVkOHDx9eLjUAgPyiAAYA2A7OPvvsz2cymaIkzOrxz5C/iouL47DDDouxY8fGqFGjoqyszFIAtkFSnqaSyWSy55577uclBgCQXxTAAADbwe67735AEuasra2NOXPmCAzyXHFxcYwcOTIuvfRSRTDANpg9e3bU1dUlYtY99tjjAIkBAOQXBTAAwGfUqlWrwnbt2u2fhFnnzZsXtbW1QgMiIqKkpCRGjhwZY8eOjaOPPjpKSkosBeBT2LRpU8ybNy8Rs7Zv337/iooKPwMEAMgjLv4AAD6jCy+8cPeioqKKJMz64osvCgz4P5o3bx5HHXVUXHLJJTFy5MjIZrOWAvAJZs2alYg5i4qKWlx88cWDJAYAkD8UwAAAn9GBBx6YiMfqVVdXJ+ZOFWDXKC8vj1GjRsWll16qCAb4BPPmzYuamppEzHrQQQd5DDQAQB5RAAMAfEZdu3YdnoQ5582bF/X19QIDPlFFRUWMGjUqLr744jj88MOjqKjIUgD+QV1dXbz66quJmLVLly77SwwAIH8ogAEAPoNTTjmlY3l5+W5JmPXll18WGLBVWrVqFccff3xcdNFFMWLEiCgo8C0kwN966aWXEjFnRUXFbieddFJ7iQEA5AffvQMAfAYnnnji55MwZ21tbcyfP19gwDZp06ZNjB49OsaOHasIBvgb8+fPj9ra2iSMmvnud7/7eYkBAOQH37UDAHwGn/vc5/ZLwpwLFy6Muro6gQGfyV+L4PPOOy+GDx+uCAby3ubNm2PhwoWJmLVfv37DJQYAkB98tw4AsI1atWpV2Lp1672TMKvHPwPbU6dOneLkk0+Oc889NwYNGmQhQF6bPXt2IuZs06bN3hUVFX4WCACQB1z0AQBso/PPP39gYWFheVOfs76+PubMmSMwYLvr2bNn/OQnP4nzzjsv9t5778hkMpYC5J3Zs2dHfX19k5+zqKio4vzzzx8oMQCA9FMAAwBso/3333/fJMz5+uuvR01NjcCAHaZLly4xZsyYOOecc2Lw4MEWAuSV6urqeOONNxIx64EHHriPxAAA0k8BDACwjbp27ZqIxz/PnTtXWMBO0bt37zjttNPinHPOif79+1sIkDeScr3VvXv3vaUFAJB+CmAAgG0wZMiQ0srKyj2a+py5XM7jn4Gdrk+fPnHWWWfFOeecE7vttpuFAKk3e/bsyOVyTX7Oli1b7jlo0KBSiQEApJsCGABgG5x55pl7ZjKZbFOfc9myZbFu3TqBAbtEnz594uyzz44zzzwzevbsaSFAaq1bty6WL1/e5OfMZDLZs846a4jEAADSrcgKAAC23tChQ4clYc558+YJC9jlBgwYEAMGDIgFCxbE+PHjY+nSpZYCpM68efOiS5cuTX7OffbZZ5+ImC4xAID0cgcwAMA26Nix4z5JmHP+/PnCApqMAQMGxC9/+cs47bTTolu3bhYCpEpSrrs6deq0j7QAANJNAQwAsJWOOOKIlhUVFf2a+pxVVVWxaNEigQFNSiaTicGDB8e//uu/xpgxY6JDhw6WAqTCW2+9FVVVVU1+zoqKis8deuihLSQGAJBeCmAAgK108sknD46ITFOfc/78+dHY2CgwoEnKZDKx9957x4UXXhhjxoyJ9u3bWwqQaI2NjbFgwYJE/Cv4u9/97h4SAwBILwUwAMBW2n333fdMwpze/wskwV+L4AsuuCBOPvnkaNu2raUAiZWU66/BgwfvKS0AgPQqsgIAgK3Trl27wU19xlwul5Q7UAAiIqKwsDCGDx8e++yzT0ybNi0mTJgQ69evtxggURYsWBC5XC4ymab9sJgOHToMlhYAQHq5AxgAYCsMGjSotGXLlgOa+pzvvfdebNy4UWBA4hQVFcWIESPikksuidGjR0fLli0tBUiMDz/8MJYtW9bk52zZsuXA/v37l0gMACCdFMAAAFvhxz/+8aBMJtPkn6Li7l8g6f5aBI8dOzZOOOGEaNGihaUAibBw4cImP2Mmk8n+5Cc/GSAtAIB0UgADAGyFvffee88kzJmEHzwCfBrNmjWLww47LMaOHRujRo2KsrIySwGatKT8Il5SrmsBANh63gEMALAVunbtOqSpz1hfXx9vvvmmsIBUKS4ujpEjR8bBBx8czz77bDz++ONRXV1tMUCT8+abb0Z9fX0UFTXtH7t16dJlT2kBAKSTO4ABAD6lioqKgoqKikFNfc4lS5bE5s2bBQakUklJSYwcOTLGjh0bRx99dJSUeIUl0LTU1tbG0qVLm/ycLVu2HFRaWupngwAAKeQiDwDgUzr77LP7FhYWNvlnj7722mvCAlKvefPmcdRRR8Ull1wSI0eOjGbNmlkK4HpsKxQWFpafffbZvaQFAJA+CmAAgE9p//3375+EOV9//XVhAXmjvLw8Ro0aFf/+7/8eI0eOjGw2aymA67FP6fOf//xAaQEApI8CGADgU+rRo8fuTX3G2traePvtt4UF5J2KiooYNWpUXHzxxXH44Yc3+XdvAum2ePHiRLySo1evXoOkBQCQPgpgAIBPqXXr1k3+DoklS5ZEQ0ODsIC81apVqzj++OPj4osvjhEjRkRBgW97gZ2voaEhlixZ0uTnbNOmjQIYACCFfCcMAPApDBkypLR58+a9m/qcb775prAAIqJ169YxevToGDt2rCIYcF32MZo3b95n0KBBpdICAEgX3wEDAHwKp556av9MJtPkr53eeustYQH8jTZt2sTo0aPjvPPOi+HDhyuCAddlfyOTyRT84Ac/+Jy0AADSxXe+AACfwuDBg5v84/Hq6+tj0aJFwgL4CJ06dYqTTz45/u3f/i323nvvyGQylgLsUIsXL07Eqzn23HPPgdICAEgXBTAAwKfQpUuXAU19xnfeeSfq6uqEBbAFnTt3jjFjxiiCgR2utrY23n333SRc53oPMABAyiiAAQA+hZYtW/Zv6jN6/DPAp9elS5cYM2ZMnHvuuTF48GALAfL2+iwJ17kAAGwdBTAAwCcYPnx4eUlJSeemPqfHPwNsvV69esVpp50W55xzTvTvrwMB8u/6rLS0tPPw4cPLpQUAkB4KYACAT/Ctb31rt4ho8s8IXbx4sbAAtlGfPn3irLPOinPOOSd22203CwG2i4T8gl7m29/+dj9pAQCkhwIYAOAT7L777k2+CVi7dm1s2LBBWACfUZ8+feLss8+OM888M3r27GkhwGfy4Ycfxrp165r8nAMHDlQAAwCkSJEVAABsWadOnZr8D8TefvttQQFsRwMGDIgBAwbEggULYvz48bF06VJLAbb5Oq1Vq1audwEA2GkUwAAAn6CyslIBDJCnBgwYEP3794958+bFQw89FO+++66lAFtlyZIlsddeezX1613PvgcASBEFMADAFnTq1CnbvHnzXk19ziVLlggLYAfJZDIxePDg2GOPPeLll1+OBx98MFauXGkxQGqu05o3b967Xbt2RatXr66XGABA8nkHMADAFowZM6ZnJpPJNuUZGxsbPZoUYCfIZDKx9957x4UXXhhjxoyJ9u3bWwrwiZYuXRqNjY1NesaCgoLsqaee2kNaAADp4A5gAIAt2Hvvvfs29RlXrlwZtbW1wgLYSf5aBO+5554xa9asmDBhQqxevdpigI9UW1sb77//fnTu3LlJzzls2LC+EbFIYgAAyecOYACALejRo0eTL4DfeecdQQHsAoWFhTF8+PC48MILY/To0VFZWWkpQGKv15Jw3QsAwKejAAYA2ILWrVs3+ff/vvvuu4IC2IUKCwtjxIgRcckll8To0aOjZcuWlgIk7notCde9AAB8Oh4BDQCwBc2bN+/Z1GdUAAM0kW+wi4pixIgRsd9++8WUKVPiscceiw0bNlgMEO+9914SrnsVwAAAKeEOYACAj9G/f/+SkpKSjk19TgUwQNPSrFmzOOyww2Ls2LExatSoKCsrsxTIc0m4XistLe3Ut2/fYmkBACSfAhgA4GOccMIJ3Zr69dK6deuiqqpKWABNUHFxcYwcOTJ+/etfK4Ihz1VVVcX69eub+pgF3/zmN7tLCwAg+RTAAAAfY8iQIT2b+oxJeJwgQL77axE8duzYOProo6OkpMRSIA8l4botCde/AAB8MgUwAMDH6N69e8+mPqPHPwMkR/PmzeOoo46KSy65JEaOHBnNmjWzFMgjSbhuS8L1LwAAn0wBDADwMVq1atWjqc+4bNkyQQEkTHl5eYwaNSr+/d//PUaOHBnZbNZSIA8k4botCde/AAB8MgUwAMDHqKio6NXUZ1y+fLmgAJL750yMGjUqLr744jj88MOjqKjIUiDFknDd1rJly16SAgBIPgUwAMBHyGazmbKysq5NecbGxsZYtWqVsAASrlWrVnH88cfHxRdfHCNGjIiCAt+qQxqtWrUqGhsbm/SMJSUlXbPZbEZaAADJ5rtKAICPcNxxx7UrKCgobsozrl69Ourr64UFkBKtW7eO0aNHx9ixYxXBkEJ1dXXxwQcfNOkZCwoKio877rh20gIASDbfTQIAfITPf/7zXZr6jO+//76gAFKoTZs2MXr06Dj//PNj+PDhimBIkRUrVrgOBgBgh/NdJP+PvTuPr7I888d/nSwEkhD2HUQEUVRAoIiouCtq64Jabd1arVorbqO2tlXbaavTOu38Rqffdmpbu9rWpYogsqgFRXCttAIKArJDgAAJBLKQ5JzfH8WO4+DOcp6T9/v18jWvTv657ut6hNvnk/t+AICd2G+//bL+xVcSXiAC8PF17do1Lr300rj99ttj2LBhkUq5lRWSLgn7tyTsgwEAeH8FWgAA8H917txZAAxAVujevXtceeWVsXr16njiiSdi9uzZkclkNAYSKAn7tyTsgwEAeH8CYACAnWjXrp0roAHIKj169Igrr7wyli5dGpMmTYo5c+ZoCiRMEvZvSdgHAwDw/gTAAAA7UVxc3D3baxQAAzRPffr0ibFjx8aSJUti/PjxsWDBAk2BhEjC/i0J+2AAAN6fbwADAOxESUlJz2yur7q6Ourq6gwKoBnbb7/94l/+5V/ia1/7WhxwwAEaAglQV1cX1dXV9sEAAOxWAmAAgHc5/PDDSwsKCtpmc40VFRUGBUBERPTt2zduvPHGuOGGG2LffffVEMhy2b6PKygoaDt8+PASkwIASC4BMADAu5x44oldsr3GDRs2GBQA/8uAAQPiG9/4Rtxwww3Ru3dvDQH7uE+yH+5qUgAAyeUbwAAA79KvX7+sD4DXr19vUADs1IABA+LAAw+MuXPnxoQJE2LlypWaAlkkCTe5HHDAAV0i4i3TAgBIJgEwAMC7dO/evXO21+gEMADvJ5VKxaBBg2LgwIExe/bsGD9+fKxbt05jwD4uZ/bDAAC8NwEwAMC7tG/fvlO21ygABuDDSKVSMWzYsBg6dGjMnj07HnvsMbdIwF6WhBPASdgPAwDw3gTAAADv0rp166w/8ZCEF4cAZI+3g+BDDz00XnnllZg4caK/S8A+LtH7YQAA3psAGADgXUpKSrL6xENjY2Ns3rzZoAD4yPLz8+Pwww+P4cOHx/PPPx8TJ06MqqoqjYE9aPPmzdHY2BgFBdn7Wi7b98MAALw/ATAAwLu0bNmySzbXV1lZGZlMxqAA+Njy8/Nj1KhRMXLkyHjhhRcEwbAHZTKZqKqqio4dO9oPAwCwWwiAAQDepaioKKuvvKusrDQkAHaJgoKCGDVqVIwYMSJmzpwZkydPji1btmgM7IH9XDYHwNm+HwYA4P3laQEAwP8YPnx4SX5+fkk21ygABmBXa9GiRRx//PFxxx13xNlnnx0lJSWaAs14P5efn18yfPhwfxAAACSUABgA4B2OOOKIDtleo+//ArC7FBUVxejRo+P73/9+nH322VFcXKwpsBsk4cr1JOyLAQDYOQEwAMA79O3bt1221+gEMAC729tB8B133BGnn356tGrVSlOgme3n9ttvv7YmBQCQTAJgAIB36NSpkwAYAHYoKSmJz3zmM3HnnXfG6NGjo0WLFpoCzWQ/l4R9MQAAOycABgB4hw4dOrTN9hqTcGUgALmlpKQkzj777PjOd74To0aNivz8fE2BHN/PJWFfDADAzgmAAQDeoaysrG221ygABmBvad++fVx00UVx5513xgknnBCFhYWaAjm6nysrK3MCGAAgoQTAAADvUFJS0j6b68tkMlFdXW1QAOxV7dq1i/POOy+++93vxqhRoyIvz+sF+CiSsJ8rLS0VAAMAJJT/QgMAeIfi4uK22VxfXV1dNDY2GhQAWeHtE8F33HGHIBg+gsbGxqirq7MvBgBgt/BfZgAA79CqVausPung9C8A2ahDhw5x0UUXxbe//e04/PDDBcGQA/u6oqIiJ4ABABLKf5EBALxDQUGBABgAPqauXbvGpZdeGt/61rdi2LBhkUqlNAUSuq9r0aJFW1MCAEimAi0AAPgfhYWFZdlc39atWw0JgKzXrVu3uPLKK2P16tXxxBNPxOzZsyOTyWgMJGhfl+37YgAA3psAGADgnZujgoLW2VyfE8AAJEmPHj3iyiuvjKVLl8akSZNizpw5mgIJ2ddl+74YAID35gpoAIAdWrdunZefn98ym2sUAAOQRH369ImxY8fGLbfcEgMGDNAQSMC+Lj8/v1WrVq28OwQASCCbOACAHQYNGlQSEVn9scJt27YZFACJtd9++8UNN9wQX/va1+KAAw7QEJq1BOzr8gYPHlxsUgAAySMABgDY4YADDijJ9hpramoMCoDE69u3b9x4441xww03xL777qshNEu1tbVZX2P//v1LTQoAIHl8AxgAYIeePXtm/QuuJLwoBIAPa8CAATFgwICYP39+jBs3LpYvX64pNBtJ2Nf16NGjxKQAAJJHAAwAsEOnTp0EwACwFwwYMCAOPPDAmDt3bkyYMCFWrlypKeS8JOzrunbtKgAGAEggATAAwA5lZWVZ/4Krrq7OoADISalUKgYNGhQDBw6M2bNnx4QJE2Lt2rUaQ85KQgDcpk0bV0ADACSQABgAYIeysjIngAFgL0ulUjFs2LAYOnRozJ49O8aPHx/r1q3TGHKOABgAgN1FAAwAsENJSUlxttfoBDAAzcXbQfCQIUPi5ZdfjokTJ0ZFRYXGkDOSEAAnYX8MAMD/JQAGANihqKioKNtrrKmpMSgAmpW8vLw4/PDDY/jw4fH888/HE088EZWVlRpD4iUhAG7RokWRSQEAJI8AGABgh8LCwhbZXF86nY7t27cbFADNUn5+fowaNSpGjhwZL7zwQkycODGqqqo0hsTavn17ZDKZSKVSWVtjixYtWpgUAEDyCIABAHbI9gC4oaHBkABo9goKCmLUqFExYsSImDlzZkyePDm2bNmiMSROJpOJhoaGyOaMtbCw0AlgAIAk/neTFgAA7NgYFRRk9QuuxsZGQwKAHVq0aBHHH398HHnkkfHMM8/E1KlTY9u2bRpDomR7AJzt+2MAAN5jH6cFAAA7NkZZ/oLL9c8A8H8VFRXF6NGj49hjj41nnnkmpkyZEjU1NRpDImT7DS8FBQWugAYASCABMADA2xujLH/B5QpoAHhvbwfBRx11VEyfPj2efvrpqK2t1RiymgAYAIDdIU8LAAD+QQAMAMlXUlISn/nMZ+LOO++M0aNHZ/X1uiAABgBgdxAAAwDskO1XQAuAAeDDKykpibPPPjv+7d/+LUaPHh2FhYWagv3dR5Sfn9/SlAAAkkcADADw9sYoL88JYADIMa1bt46zzz47vve978UJJ5wgCMb+7iPIz8/3LwwAQAIJgAEAdkilUlm9N2psbDQkAPiY2rVrF+edd15897vfjRNOOCEKCgo0Bfu7D94f55sSAEDyCIABAHbI9gA4nU4bEgB8Qu3bt/9nEDxq1KjIy/NqBPu799kfp0wJACB5/FcOAMAOXnABQPPRoUOHuOiii+J73/ueIJi9JpPJZHuJ/sUAAEggmzgAgP+R1QFwAl4QAkDidOzYMS666KL41re+FYcffnj4fTDs796xOc7yG3IAANg5mzgAgITsjQTAALD7dOvWLS699NL41re+FcOGDRMEs0dk+xXQeXl5/kUAAEigAi0AAPiHbH/BJQAGgN2ve/fuceWVV8ayZcviiSeeiDlz5mgKzXl/5/AIAEACCYABAHbIZDJOAAMAERGx7777xtixY2PJkiUxYcKEmD9/vqZgfwwAQCIIgAEA/ocr7gCA/2W//faLG264Id56660YP358vPnmm5rCLpPtV0Cn3IUOAJBIAmAAgB2y/QVXtr8gBIBc1rdv37jxxhvjrbfeinHjxsWiRYs0hU/MFdAAANjEAQDsXln9Bs4BDADY+/r27Rs333xz3HDDDdG7d28NIdf3d75BAgCQQE4AAwDskO0nMATAAJA9BgwYEAMGDIj58+fHI488EitXrtQUcnF/5woaAIAEcgIYAGCHVCqVzvL6DAkAssyAAQPi1ltvjbFjx0bPnj01hJza32UScEc1AAD/lxPAAAD/QwAMAHysv6MHDRoUBx98cDz//PMxadKk2LRpk8aQ+P1dtv+CJAAAO+cEMADADul0dr/fEgADQHarr6+PioqK2LZtm2aQE/u7dDrtBDAAQAI5AQwA8D+cAAYAPrK6urp4+umnY9q0acJfcm1/5wQwAEACCYABAP6HEw4AwIfW0NAQ06ZNiyeffDK2bt2qIXxkCfgGsAAYACCBBMAAADtkMpmsDoDz8ny9AwCywdvB71NPPRXV1dUaQs7u7wTAAADJJAAGANgh219wCYABYO9qbGyMGTNmxJNPPhmVlZUawieWn5+f9VtkUwIASB4BMADADplMpiGb6yssLDQkANgL0ul0zJo1KyZPnhwbN27UEHaZgoLsfjXX1NTUaEoAAAncZ2oBAMA/NDY2bs/m+gTAALBnpdPpePnll2Py5Mmxdu1aDWGXa9GiRbb/O1BvSgAAySMABgDYoampSQAMAEQmk4nZs2fH448/HuXl5RpCs93fNTY2CoABABJIAAwAsENDQ0NWv+ASAAPA7vV28PvEE0/E6tWrNYTdLtuvgM72G3IAAHiPfaYWAAD8gyugAaD5mjNnTkyaNCmWLl2qGewx2X4FtAAYACCZBMAAADs0NTU5AQwAzcyCBQtiwoQJ8dZbb2kG9nfv0tDQIAAGAEggATAAwA7Z/oJLAAwAu87ChQtj/PjxsXjxYs1gr8n2K6Cz/RckAQB4j32mFgAA/EO2B8AFBQWRl5cX6XTasADgY1q+fHmMGzcu5s+frxnsVXl5eVkfAG/fvt0JYACABBIAAwDs0NDQkPUnHFq1ahXbtm0zLAD4iFauXBmPPPKI4Jes2tclYH8sAAYASCABMADADrW1tXXZXqMAGAA+mnXr1sX48eNj9uzZkclkNISs2tdlu7q6ulqTAgBIHgEwAMAOW7du3ZrtNSbhRSEAZIP169fHY489JvjFvu4TqK6u3mpSAADJIwAGANihqqpKAAwACbdhw4Z4/PHH45VXXommpiYNwb7uE6isrHT1DABAAgmAAQB22LRpU9a/4GrZsqVBAcBOVFVVxcSJE+OFF16IxsZGDSHrJSEA3rRpkxPAAAAJJAAGANhh3bp1WR8AOwEMAP/bli1bYsKECYJfEicJ+7ry8nIBMABAAgmAAQB2WLZsmSugASAhqqurY/LkyTFz5syor6/XEBInCfu6pUuXCoABABJIAAwAsMP8+fOz/gRwcXGxQQHQrNXU1MSUKVPimWeeEfySaEnY173++uu+AQwAkEACYACAHRYsWFCXyWQaUqlUYbbW2Lp1a4MCoFmqq6uLp59+OqZNmxbbtsmkSL5s39el0+mGpUuXbjcpAIDkEQADALxDU1PTtoKCgrbZWp8AGIDmZvv27TF9+vR48sknY+tWt9GSO7J9X9fU1ORfOACAhBIAAwC8Q0NDw9ZsDoBLS0sNCYDm8ndyTJs2LZ566qmorq7WEHJOtu/rGhsb/YsHAJBQAmAAgHeor6+vbNWqVc9src8JYAByXWNjY8yYMSOefPLJqKys1BByVrbv6+rr66tMCQAgmQTAAADv0NDQkNVvmgXAAOSqdDods2bNismTJ8fGjRs1hJyX7fu6bN8XAwDw3gTAAADvUFdXV5XN9ZWWlkYqlYpMJmNYAOSETCYTr732Wjz++OOxatUqDaFZSKVSUVJSktU11tbWVpkUAEAyCYABAN5h27Ztm7K5vvz8/GjVqlXU1NQYFgCJlslkYvbs2fH4449HeXm5htCstGrVKvLz87O6xq1btzoBDACQUAJgAIB3qK6u3pztNZaVlQmAAUist4PfiRMnxpo1azSEZqmsrCzra9y2bVuVSQEAJJMAGADgHaqqqjZle43t2rWLtWvXGhYAiTNnzpyYNGlSLF26VDNo1tq1a5f1NW7atMkJYACALNbQWBgFjQ0REZFKRSavMJre/pkAGADgHSoqKqqyvcYkvDAEgHdasGBBTJgwId566y3NgITs5zZs2CAABgDIYoUFDf9MejMRqab0/+S+AmAAgHdYtWpV1r/oatu2rUEBkAgLFy6M8ePHx+LFizUD3iEJAfDq1aurTAoAIJkEwAAA77BgwYKsD4CdAAYg2y1fvjzGjRsX8+fP1wzYiST8Ql8S9sUAAOycABgA4B2eeOKJjZlMpimVSuVna41OAAOQrVauXBmPPPKI4Bc+QLb/Ql8mk2l64oknNpoUAEAyCYABAN6huro6vX379g1FRUVdsrVGJ4AByDZr166NCRMmxOzZsyOTyWgIJHw/t3379g3V1dVpkwIASCYBMADAu9TV1a0XAAPAB1u/fn089thjgl/Isf1cXV3delMCAEguATAAwLvU1dVVtGnTJmvrKykpiRYtWsT27dsNC4C9oqKiIiZOnBivvPJKNDU1aQh8BEVFRVFcXJz1+2GTAgBILgEwAMC7bN26dV2XLll7ADhSqVR07Ngx1qxZY1gA7FFVVVUxceLEeP755wW/8DF17NgxUqlU1u+HTQoAILkEwAAA71JVVZX1Jx46deokAAZgj9m8eXM8/vjj8cILL0RjY6OGwCfcx9kPAwCwOwmAAQDeZf369Vn/zbMkvDgEIPm2bNkSU6ZMiZkzZ0Z9fb2GwC7QsWNH+2EAAHYrATAAwLusXr066088JOHFIQDJVVNTE1OmTIlnnnlG8Au7WBJ+kW/VqlUCYACABBMAAwC8y9///ves/+aZABiA3aG2tjYmT54czz77bNTV1WkINNN93KuvvioABgBIMAEwAMC7PPzww+t//OMfN6RSqcJsrbFz584GBcAus3379pg+fXpMnTo1tm3bpiGwG2X7CeB0Ot3w8MMPC4ABABJMAAwA8C7V1dXpurq68latWu2TrTV26NAh8vLyIp1OGxgAH1tDQ0NMmzYtnnrqqaiurtYQ2M3y8vKiQ4cOWV1jfX39mtraWptMAIAEEwADAOxEbW3tmmwOgAsKCqJdu3axceNGwwLgI2tsbIwZM2bEk08+GZWVlRoCe0j79u2joCC7X8fV1NSUmxQAQLIJgAEAdmLz5s2r2rdvn9U1duvWTQAMwEeSTqdj1qxZMXnyZH+HwF7av2W7LVu2rDQpAIBkEwADAOzEpk2bVvfp0yera+zWrVvMmzfPsAD4QG8Hv1OmTIkNGzZoCOzF/Vu227BhwxqTAgBINgEwAMBOrFixYvWwYcOyusYkvEAEYO/KZDLx0ksvxZQpU6K83K2usLd17do162tctWrVKpMCAEg2ATAAwE7Mnz9/9ZgxY7K6xiS8QARg78hkMjF79uyYOHFirFnjMB9kiyT8At+8efP8oQEAkHACYACAnRg3btyab37zm5mISGVrjU4AA7Azc+bMiSeeeCKWLVumGZBlEvALfJlx48atNikAgGQTAAMA7MTrr79e29DQsKmwsLBDttZYXFwcZWVlsWXLFgMDIBYsWBDjx4+PJUuWaAZkobKysiguLs7qGhsaGjYuWLCgzrQAAJJNAAwA8B62bt26vF27dh2yucauXbsKgAGauYULF8b48eNj8eLFmgFZLAm3t2zbtm25SQEAJJ8AGADgPVRVVS1t167d0GyusWfPnrFw4ULDAmiGli1bFo899ljMnz9fMyABevbsmfU1VlZWLjUpAIDkEwADALyHdevWLevTp09W15iEF4kA7ForVqyIRx99VPALCZOEfdvatWuXmRQAQPIJgAEA3sPChQuXHX744VldY69evQwKoJlYtWpVjB8/PubOnRuZTEZDIGGSsG9buHDhMpMCAEg+ATAAwHuYNm3a0ksuuSSra+zevXvk5+dHU1OTgQHkqHXr1sX48eNj9uzZgl9IqIKCgkR8A/jpp59eZloAADmw/9QCAICde+ihhzbcd999W/Pz80uzdjNXUBBdunSJNWvWGBhAjqmoqIiJEyfGyy+/HOl0WkMgwbp27RoFBdn9Gq6xsbH6kUce2WBaAADJJwAGAHgf27ZtW15WVnZwNtfYq1cvATBADqmqqoqJEyfG888/74YHyBFJ+P7vtm3blpsUAEBuEAADALyPLVu2LMv2ALhnz57x0ksvGRZAwm3evDkef/zxeOGFF6KxsVFDIIck4fu/W7ZsWWpSAAC5QQAMAPA+1q9fvyzbT2z06NHDoAASbMuWLTFlypSYOXNm1NfXawjkoCTs19avX7/MpAAAcoMAGADgfSxYsGDh0KFDs7rGfffdN1KpVGQyGQMDSJCampqYMmVKPPPMM4JfyGGpVCr23XffrK9z/vz5C00LACA3CIABAN7Ho48++uYFF1yQ1TWWlJRE586dY926dQYGkAC1tbUxefLkePbZZ6Ourk5DIMd17do1WrVqlfV1/vnPf15kWgAAuUEADADwPiZNmlRVX1+/oaioqGM217nvvvsKgAGy3Pbt22P69OkxderU2LZtm4ZAM9GnT5+sr7G+vr7iySefrDItAIDcIAAGAPgAW7duXZTtAXCfPn3ipZdeMiyALNTQ0BDTpk2Lp556KqqrqzUEmpkkXP+8detWp38BAHKIABgA4ANUVFQs7NChw8hsrjEJLxYBmpvGxsaYMWNGPPnkk1FZWakh0EwlYZ9WUVHh+78AADlEAAwA8AGWLl266MADD8zqGnv16hUFBQXR2NhoYAB7WTqdjlmzZsWkSZNi06ZNGgLNWGFhYfTs2TMR+13TAgDIHQJgAIAPMHPmzEWnnnpqdm/qCgqiZ8+esWzZMgMD2EveDn4nT54cGzdu1BAg9tlnn8jPz0/CfnexaQEA5I48LQAAeH+//OUvV6bT6bpsr7NPnz6GBbAXZDKZePHFF+O73/1u3H///cJf4J+ScP1zOp2u++Uvf7nStAAAcocTwAAAH6C6ujpdXV29uE2bNodkc539+vWL6dOnGxjAHpLJZGL27NkxceLEWLNmjYYAO92fJWCvu7i6ujptWgAAuUMADADwIWzYsGFetgfA/fv3NyiAPeTVV1+NSZMmxapVqzQD2KlUKpWI/dmGDRvmmhYAQG4RAAMAfAiLFy9+o2/fvlldY1lZWXTu3DnWr19vYAC7yYIFC2L8+PGxZMkSzQDeV5cuXaK0tDQJ+9z5pgUAkFsEwAAAH8JTTz31+ujRo7O+zv33318ADLAbLFy4MMaPHx+LFy/WDOBD78uSYMqUKa+bFgBAbsnTAgCAD/aLX/xiTWNjY1W215mUF40ASbFs2bK4++674z/+4z+Ev8BHkoTv/zY0NFTee++9q00LACC3OAEMAPAhNDQ0ZDZv3jy/Q4cOI7O5TgEwwK6xYsWKePTRR2P+fDejArm7L9uyZYs/5AAAcpAAGADgQ1q3bl3WB8AdO3aMNm3axObNmw0M4GNYtWpVjB8/PubOnRuZTEZDgI+lbdu20aFDh0Tsb00LACD3CIABAD6kefPmzTvooIOyvs4DDzwwXnrpJQMD+AjWrVsX48ePj9mzZwt+gV2yH0uCuXPnzjMtAIDcIwAGAPiQ/vznP88/77zzsr7OAw44QAAM8CFVVFTEuHHjBL/ALt+PJcHDDz/sBDAAQA4SAAMAfEgTJ06srK2tXdGqVat9srnOgw8+2LAAPkBVVVVMnDgxnn/++WhqatIQYJdKwq0xNTU1yydNmlRlWgAAuUcADADwEWzYsOHvvXr1yuoAuG3bttG1a9dYu3atgQG8y+bNm+Pxxx+PF154IRobGzUE2OW6desWbdu2TcS+1rQAAHKTABgA4CNYuHDha7169Toj2+scMGCAABjgHbZs2RJTpkyJ5557LrZv364hwG6TlO//Lly48O+mBQCQmwTAAAAfwcSJE/9+wgknZH2dBx54YEyfPt3AgGavpqYmpkyZEs8880zU19drCLDbDRgwIBF1jh8//u+mBQCQmwTAAAAfwb333rv6Bz/4wfqioqLO2VznAQccEHl5eZFOpw0NaJZqa2tj8uTJ8eyzz0ZdXZ2GAHtEXl5e9O/fP+vrrK+vX3ffffeVmxgAQG4SAAMAfESVlZVzu3btmtXHgFu1ahX77LNPLFu2zMCAZqWuri6efvrpmDZtWmzbtk1DgD1qn332iVatWmV9nZs2bZpjWgAAuUsADADwES1dunR2tgfAERGDBg0SAAPNRkNDQ0ybNi2eeuqpqK6u1hBgr+2/kuCtt976m2kBAOQuATAAwEc0ffr0v48cOTLr6xw4cGBMmDDBwICc1tDQEM8991w8+eSTUVlZqSHAXt9/JcG0adP+bloAALlLAAwA8BH9x3/8x9JbbrmlOj8/v3U219mrV68oKyuLLVu2GBqQc9LpdMyaNSsmTZoUmzZt0hBgrysrK4tevXplfZ2NjY1b7rnnnmUmBgCQuwTAAAAfUW1tbXrDhg1/7dKly3HZXGcqlYqBAwfGrFmzDA3IGW8Hv5MnT46NGzdqCJA1Bg4cGKlUKuvr3Lhx4yu1tbVpEwMAyF0CYACAj+Gtt956JdsD4IgQAAM5I51Ox8svvxxTpkyJ8vJyDQGyct+VBIsWLXrFtAAAcpsAGADgYxg/fvwrRxxxRNbXedBBB0VBQUE0NjYaGpBImUwmZs+eHRMnTow1a9ZoCJCVCgoK4qCDDkpErY888ogAGAAgx+VpAQDAR/fjH/94ZX19/fpsr7OoqCj69etnYEAivfrqq3HHHXfEz3/+c+EvkNX69esXRUVFWV9nXV1d+b333rvaxAAAcpsTwAAAH9OGDRte6dGjx6ezvc5BgwbFggULDAxIjCVLlsSECRNi/vz5mgEkwuDBgxNR5/r1653+BQBoBgTAAAAf07x5815OQgA8bNiwePjhhyOTyRgakNXefPPNmDBhQixevFgzgMRIpVIxdOjQRNQ6d+7cl0wMACD3CYABAD6m++677+XRo0dnIiKVzXW2bds2evfuHcuWLTM0ICstW7YsHnvsMSd+gUTq06dPtG3bNgmlpu+9996/mhgAQO4TAAMAfEwTJ06s3Lp165LS0tK+2V7rkCFDBMBA1lmxYkU8+uijgl8g0YYMGZKIOqurqxc+/fTTm00MACD3CYABAD6B8vLyl/fff/+sD4AHDx4c48aNMzAgK6xcuTImTJgQc+fOdT09kHhJ+f7vmjVrfP8XAKCZEAADAHwCM2fOfG7//ff/fLbX2a1bt+jWrVuUl5cbGrDXrFu3LsaPHx+zZ88W/AI5oWfPntGlS5dE1DpjxoznTAwAoHkQAAMAfAK33Xbba5dcckl1fn5+62yvdciQIQJgYK9Yv359PPbYY4JfIOck5frnxsbGzbfddts8EwMAaB4EwAAAn0BlZWXThg0b/tqlS5fjsr3WQw89NCZNmmRowJ78MzKeeOKJeP7556OpqUlDgJxz6KGHJqLOioqKV6qrq9MmBgDQPAiAAQA+oXnz5s1MQgDcu3dv10ADe0RVVVVMnDgxXnjhhWhsbNQQICd17949evbsmZT9quufAQCakTwtAAD4ZP77v/97VkQk4kTFpz71KQMDdpstW7bEQw89FLfffns899xzwl8gpw0fPjwRdWYymfTdd9/9gokBADQfTgADAHxCkyZNqtqyZcuCsrKyg7K91uHDh8fjjz9uaMAuVVNTE1OmTIlnnnkm6uvrNQTIealUKg477LBE1Lply5bXp0+fvsXUAACaDwEwAMAusHz58lkDBw7M+gC4S5cu0atXr1i5cqWhAZ9YbW1tTJ48OZ599tmoq6vTEKDZ6N27d3Ts2DEx+1QTAwBoXgTAAAC7wLPPPvvCwIEDr0hCrcOGDRMAA59IXV1dPP300zFt2rTYtm2bhgDNzrBhwxJT61/+8pcXTQwAoHnxDWAAgF3g1ltvnV9fX782CbUefvjhkUqlDA34yBoaGmLq1Klx6623xuOPPy78BZqlJF3/XFdXt/rWW29dYGoAAM2LE8AAALtAQ0NDZs2aNc/16dPns9lea7t27aJPnz6xZMkSgwM+7J9xMW3atHjqqaeiurpaQ4Bmbb/99ou2bdsmotbVq1fPNDEAgOZHAAwAsIs8++yz05IQAEdEHHHEEQJg4AOl0+mYNWtWTJo0KTZt2qQhABFx5JFHJqbW6dOnTzMxAIDmxxXQAAC7yC233PJaQ0NDZRJqHT58eLRo0cLQgJ1Kp9Px3HPPxW233Rb333+/8Bdgh6KiovjUpz6ViFobGho23HLLLXNNDQCg+XECGABgF6murk6Xl5c/t88++5yR7bW2bNkyDj300Hj55ZcNDvindDodL7/8ckyZMiXKy8s1BOBdhgwZEkVFRYmodc2aNc/V1tamTQ0AoPkRAAMA7EIvvvjiM0kIgCMiRo4cKQAGIiIik8nE7NmzY+LEibFmzRoNAXif/VNSzJo161kTAwBongTAAAC70O233/7KOeecszU/P78022sdMGBAtG/f3tWu0My9+uqrMWnSpFi1apVmALyPjh07xgEHHJCIWhsbG6u/8Y1v/NXUAACaJwEwAMAutHLlyob169fP6tat2+hsrzWVSsXhhx8ekyZNMjhohubMmROTJ0+OJUuWaAbAh3D44YdHKpVKRK3r16+fVVFR0WhqAADNU54WAADsWq+++mpirts77LDDDAyamTfffDP+/d//PX7yk58IfwE+pFQqFSNGjEhMva+88sozpgYA0Hw5AQwAsIvddNNNz5166qnV+fn5rbO91m7dukX//v1j4cKFBgc5btmyZfHYY4/F/PnzNQPgIzrggAOic+fOiai1sbFxy4033jjL1AAAmi8BMADALrZy5cqG8vLyGT179vx0Euo9+uijBcCQw5YvXx7jxo0T/AJ8wv1SUpSXlz9TXl7eYGoAAM2XABgAYDeYMWPGUxdccEEiAuAhQ4ZE69ato7q62uAgh6xcuTImTJgQc+fOjUwmoyEAH1ObNm3i0EMPTUy9zz777FOmBgDQvPkGMADAbvDVr371lYaGhk1JqLWgoCCOOOIIQ4McsW7duvj5z38ed955Z8yZM0f4C/AJjRw5MvLz8xNRa0NDw8abbrrpVVMDAGjenAAGANgNKisrm1atWjW9T58+5ySh3qOPPjqefPJJQREk2Pr16+Oxxx6L2bNn+3cZYBdJpVIxatSoxNS7cuXKadXV1WmTAwBo3pwABgDYTaZNm5aY6/c6duwYAwYMMDRIoA0bNsSvf/3r+Nd//dd49dVXhb8Au9CAAQOiY8eOian36aefftLUAAAQAAMA7CZf+9rX5tTX11ckpd6jjjrK0CBBqqqq4v77749vf/vb8eKLL0ZTU5OmAOxiRx55ZGJqra+vX/eNb3zjdVMDAMAV0AAAu0ltbW16xYoVT++///6fT0K9hx56aLRt2zaqqqoMD7LYli1bYsqUKfHcc8/F9u3bNQRgN2nbtm0MGTIkMfUuX778qdraWtc/AwDgBDAAwO70xz/+cUJSas3Pz4/jjjvO0CBL1dTUxKOPPhq33XZb/OUvfxH+Auxmxx57bOTn5yel3Myvf/3rCaYGAECEABgAYLe66667llZXV89PSr1HH310tGjRwuAgi7wd/H7jG9+IqVOnRn19vaYA7GYtWrSIo48+OjH1btmy5Y177rlnhckBABDhCmgAgN3u9ddfn3T44YcPSEKtxcXFcdhhh8XMmTMNDvayurq6ePrpp2PatGmxbds2DQHYgw477LAoKSlJTL3z5s17wtQAAHibE8AAALvZ9773vanpdLohKfWecMIJkUqlDA72koaGhpg6dWrceuut8fjjjwt/AfawVCoVJ5xwQmLqTafT27/73e8+ZXIAALzNCWAAgN1s+vTpWyoqKmZ26dIlER/Y7d69e/Tv3z/efPNNw4M9qKGhIaZNmxZPPfVUVFdXawjAXnLAAQdE9+7dE1NvRUXFczNmzPAXBwAA/+QEMADAHjBr1qxEXcuXpFMvkHTpdDqee+65uP322+PRRx8V/gLsZccff3yi6p0xY8YkUwMA4J2cAAYA2AO++tWvvnT66adXFRYWtk1CvQMHDoyOHTvGhg0bDA92k3Q6HbNmzYrJkyfHxo0bNQQgC3Ts2DEGDhyYmHobGhoqb7755pdMDgCAd3ICGABgDygvL29YsWLF1MRsEvPy4sQTTzQ42A3S6XS8+OKL8Z3vfCfuv/9+4S9AFjnppJMiLy85r8tWrFgxpaKiotHkAAB4JwEwAMAe8qtf/erRiMgkpd6jjjoqysrKDA52kUwmE6+++mp873vfi1//+texdu1aTQHIImVlZXHUUUcl6q+W//7v//6zyQEA8G4CYACAPeQ///M/l1dWVv4tKfUWFhbGMcccY3CwC7wd/P785z+PNWvWaAhAFjruuOOioCA5X0urqqqa/dOf/nS1yQEA8G4CYACAPeill14al6R6jzvuuCgqKjI4+JjmzJkTd911V/z85z+P1au9owfIVkVFRYn7xbcXXnhhnMkBALAzBVoAALDnjB079pkFCxZUFhYWtktCvSUlJXHEEUfE9OnTDQ8+gjfffDPGjx8fb731lmYAJMCRRx4ZJSUliam3oaFh0zXXXPOsyQEAsDMCYACAPai8vLxh6dKlE/v3739xUmo+8cQT49lnn410Om2A8AEWLVoUjz32WCxevFgzABIiLy8vTjzxxETVvGTJkifKy8sbTA8AgJ3ucbUAAGDP+u1vfzsxIjJJqbdjx44xdOhQg4P3sXz58rj77rvjRz/6kfAXIGGGDRsWHTp0SFLJmd/85jePmxwAAO9FAAwAsIf953/+5/JNmza9kqSaTz/99EilUoYH77Jy5cr4yU9+Et///vdj/vz5GgKQMHl5eXHGGWckquZNmza9fM8996wwPQAA3osroAEA9oKXXnpp/KmnnnpYUurt2rVrDBkyJGbPnm14EBHr1q2L8ePHx+zZsyOTyWgIQEINHTo0OnfunKiaX3jhhQkmBwDA+xEAAwDsBZdffvkzS5YsWVdUVNQlKTWfccYZ8be//U3YRbO2fv36eOyxxwS/ADkglUrF6aefnqia6+rq1lx22WXTTQ8AgPcjAAYA2AsqKyub5s+f/8ihhx56dVJq7tatm1PANFsbNmyIxx9/PF555ZVoamrSEIAc8KlPfSq6du2aqJrfeOONcdXV1WnTAwDg/fgGMADAXvL1r399XDqdrktSzb4FTHNTVVUV999/f3z729+OF198UfgLkCNSqVR8+tOfTlTN6XS69pvf/OZjpgcAwAdxAhgAYC+ZMWNG9Zo1a/7Ss2fPxLx97N69ewwcODDmzJljgOS0LVu2xIQJE+KFF16IxsZGDQHIMYceemh069YtUTWvXr36qRkzZlSbHgAAH8QJYACAvejXv/71HyMiUR8SPeuss5wCJmdt27YtHn300bjtttviueeeE/4C5KC8vLwYM2ZM0srO/OpXv/qT6QEA8KH2vFoAALD3fP/733+rqqoqUR/V7dGjR3zqU58yPHJKfX19TJ06Nb71rW/F1KlTo76+XlMActSIESOiS5cuiap506ZNf73rrruWmh4AAB+GABgAYC975plnHkpazWeccUbk5dlKkjvmzZsXjz76aGzdulUzAHJYQUFBnH766Ymre9q0aQ+aHgAAH5a3dgAAe9nYsWNn1tfXr01SzZ07d47DDjvM8ACARBk5cmR06NAhUTXX1dWtHjt27POmBwDAhyUABgDYyyorK5tee+21Pyat7jPPPDMKCgoMEABIhBYtWiTy9O/s2bP/UF1dnTZBAAA+LAEwAEAWuOqqqyY0NjZWJanm9u3bx9FHH214AEAiHHfccdGmTZtE1dzQ0LDxiiuumGh6AAB8FAJgAIAssGDBgrqFCxc+lrS6R48eHYWFhQYIAGS1li1bxsknn5y4uhcuXDhu6dKl200QAICPQgAMAJAlvv71r/8pnU7XJqnmtm3bximnnGJ4AEBWO+2006K0tDRRNTc1NdV+7Wtfe8j0AAD4qATAAABZ4umnn968fPnyxF3xN3r06GjXrp0BAgBZqUOHDnH88ccnru5ly5ZNmD59+hYTBADgoxIAAwBkkbvvvvtPmUymKUk1FxYWxumnn254AEBWOvPMMxP3yYpMJtN41113/dH0AAD4OATAAABZ5Be/+MWatWvXTkta3UcccUT06tXLAAGArNK7d+847LDDEld3eXn5X+6///51JggAwMchAAYAyDIPP/zwn5JWcyqVijPPPNPwAICsMmbMmEilUomr+8EHH/yT6QEA8HEJgAEAsszXv/71NzZs2DAraXUPHDgwDj74YAMEALLCoEGDYsCAAYmru6KiYuatt966wAQBAPi4BMAAAFlo3Lhxv01i3WPGjIm8PFtMAGDvysvLizFjxiSy9j//+c+/NUEAAD7RflgLAACyz/XXXz+nqqrqr0mru1evXnHUUUcZIACwVx1zzDHRvXv3xNW9adOmV2666aa5JggAwCchAAYAyFJ/+tOf7k1i3WPGjInS0lIDBAD2ijZt2sRZZ52VyNofeOCBe00QAIBPSgAMAJClbrrpprlJPAVcXFwcZ555pgECAHvFWWedFS1btkxc3Zs2bXrl5ptvnmeCAAB8UgJgAIAsNm7cuF8lse5Ro0ZF7969DRAA2KP69OkTI0eOTGTtjz322K9MEACAXUEADACQxcaOHTu7qqrqb0mrO5VKxfnnnx+pVMoQAYA9tv/4/Oc/n8j9R2Vl5d+uueaav5kiAAC7ggAYACDLTZ069bdJrLtv374xZMgQAwQA9ojDDjsssTeQTJ48+TcmCADAriIABgDIcpdeeumLVVVVryax9s9//vNRXFxsiADAblVaWhrnn39+Imuvqqr66+WXX/6SKQIAsKsIgAEAEuChhx76WRLrLisri9NPP90AAYDd6qyzzoqSkpIklp753e9+91MTBABgVxIAAwAkwA033DB3w4YNs5JY+3HHHRd9+vQxRABgt+jbt28cddRRiay9oqJi1te//vU3TBEAgF1JAAwAkBA///nPfxoR6aTVnUql4vOf/3zk5dl6AgC7Vn5+flx00UWRSqWSWH76F7/4xX+bIgAAu5q3cAAACXHHHXe8tW7duulJrL13795xzDHHGCIAsEudcMIJ0b1790TWXl5e/pc77rjjLVMEAGBXEwADACTI3XfffW8mk2lKYu1nnXVWtG3b1hABgF2iQ4cOcfrppyey9kwm03T33Xf/3BQBANgdBMAAAAlyzz33rCgvL386ibW3bNkyzj33XEMEAHaJc889N1q0aJHI2tesWTP1xz/+8UpTBABgdxAAAwAkzA9/+MOfZzKZhiTWPnz48Bg0aJAhAgCfyKGHHhpDhw5NZO3pdLrhBz/4wS9MEQCA3UUADACQMPfee+/qRYsWPZDU+i+++OIoKSkxSADgY2ndunVcfPHFia1/4cKFf7jvvvvKTRIAgN1FAAwAkECXXXbZrxsaGjYlsfaysjJXQQMAH9u5554bpaWliay9oaFh4+WXX/47UwQAYHcSAAMAJNDs2bNrXn311V8ntf4jjjgiDj74YIMEAD6SwYMHx+GHH57Y+l955ZX7Zs+eXWOSAADsTgJgAICEOueccx6tqalZmtT6L7roomjZsqVBAgAfSsuWLeNzn/tcYuuvqalZMmbMmMdMEgCA3U0ADACQUJWVlU3Tpk37RVLrb9++fZx++ukGCQB8KGeccUa0b98+sfU/+eST91ZXV6dNEgCA3U0ADACQYOedd960qqqqV5Ja/wknnOAqaADgAx188MFx/PHHJ7b+TZs2vXzBBRc8a5IAAOwJAmAAgIT74x//eG9EZJJYeyqVigsuuMBV0ADAe2rZsmVccMEFkUqlkrqEzP333/8zkwQAYE8RAAMAJNzNN988b9WqVU8ktf6OHTsm+nt+AMDudcEFF0THjh0TW/+KFSse//rXv/6GSQIAsKcIgAEAcsCNN974k6ampq1JrX/kyJExdOhQgwQA/pdPfepTMWLEiMTW39TUVH3zzTf/t0kCALAnCYABAHLAxIkTK//+97//KslruPDCC6OsrMwwAYCIiGjTpk18/vOfT/QaZs+efd/EiRMrTRMAgD1JAAwAkCPOPvvsh2pqapYntf7S0tK46KKLDBIAiFQqFV/84hejtLQ0sWuoqal566yzznrYNAEA2NMEwAAAOaKioqJx0qRJP07yGgYPHhwjR440TABo5o444og46KCDEr2GJ5544qeVlZVNpgkAwJ4mAAYAyCGXXHLJzIqKihlJXsMFF1wQ3bp1M0wAaKZ69uyZ+KufKyoqZnzhC1+YZZoAAOwNAmAAgBzzb//2b/ek0+ntSa2/RYsWceWVV0ZhYaFhAkAzU1hYGF/60pcSvQ9Ip9Pb/+3f/u0e0wQAYG8RAAMA5Jh777139aJFix5M8hq6d+8eZ555pmECQDNzxhlnRPfu3RO9hsWLFz947733rjZNAAD2FgEwAEAO+uxnP/vL2traRL94PPHEE2Pw4MGGCQDNxKBBg+Kkk05K9Bpqa2tXn3vuub80TQAA9iYBMABADlq8eHH9uHHj/j3Ja0ilUnHJJZdE27ZtDRQAclybNm3ikksuiVQqleh1jBs37t8XL15cb6IAAOxNAmAAgBx1+eWXv1RRUTEjyWsoLS2NL3zhC4l/GQwAvLe3f+mrdevWiV5HRUXFM5dffvlLJgoAwN4mAAYAyGE33HDDXU1NTVuTvIaDDjrI94ABIId95jOfiUMOOSTRa2hqaqq+4YYbfmiaAABkAwEwAEAOGzdu3MbZs2cn/jt0p5xyiu8BA0AOOuSQQ+LTn/504tfx17/+9efjxo3baKIAAGQDATAAQI77zGc+81B1dfXCJK8hlUrFF7/4xejQoYOBAkCO6NixY3zpS19K/KceNm/ePO+00057xEQBAMgWAmAAgBxXXV2dfuCBB34UEekkr6O4uDguvfTSyMuzhQWApMvPz4/LLrssiouLk76U9P333/+ftbW1aVMFACBbeHsGANAMXH/99XMWLVr0YNLXsf/++8e5555roACQcOedd1707ds38etYuHDhH7/61a++bqIAAGQTATAAQDNxySWX/Lyurq486es4/vjjfQ8YABJs2LBhccwxxyR+HXV1dWsuvPDC+0wUAIBsIwAGAGgmXnvttdoHHnjguxGRSfI6UqlUfOlLX4oePXoYKgAkTO/evePSSy9N/Hd/IyLzwAMPfO/111+vNVUAALKNABgAoBm5+uqr/7Z06dJHk76OoqKiGDt2bJSWlhoqACRE69at46qrrorCwsLEr2X58uXjrr766r+ZKgAA2UgADADQzJx33nn/r66ubnXS19GhQ4e4/PLLIy/PlhYAsl1eXl5cfvnl0b59+8Svpb6+ft0ll1zyE1MFACBr999aAADQvLz++uu1Dz744Pcj4VdBR0QMGDAgzjrrLEMFgCw3ZsyYOPDAA3NiLY899tgPXnnllW2mCgBAthIAAwA0Q1/5ylf+umbNmqm5sJaTTz45Dj30UEMFgCw1ZMiQOOmkk3JiLWvXrv3LpZde+oKpAgCQzQTAAADN1GWXXfYf9fX1FUlfRyqViksvvTS6d+9uqACQZXr06BFf/OIXI5VKJX4tDQ0Nm6655pofmioAANlOAAwA0EzNmDGj+oEHHvhO5MBV0C1btozrr78+2rZta7AAkCXatWsX1113XbRs2TIXlpN56KGH/nXSpElVJgsAQLYTAAMANGNf+cpX/rpkyZI/58Ja2rZtG1dffXW0aNHCYAFgL2vRokVcffXVOfPLWUuXLn30iiuueNlkAQBIAgEwAEAzd+655/6ktrZ2eS6spXfv3jlzzSQAJNXbn2fYZ599cmI9tbW1y88555wfmywAAEkhAAYAaOYWLFhQ97Of/ezbmUymMRfWM2zYsDjllFMMFgD2kk9/+tMxdOjQnFhLJpNp/NnPfvbtBQsW1JksAABJIQAGACBuvfXWBfPnz78/V9Zz5plnxuDBgw0WAPaw4cOHx2c+85mcWc/8+fN/d+utty4wWQAAkkQADABARESMGTPmvpqamrdyYS2pVCouu+yy6Nmzp8ECwB7Su3fvuPjii3PmUwxbt25ddPrpp//aZAEASBoBMAAAERGxcuXKhh/+8Ie3pdPpnLjisGXLlvEv//Iv0aVLF8MFgN2sS5cucf3110dRUVFOrKepqanmu9/97jfKy8sbTBcAgKQRAAMA8E933XXX0ueff/6eXFlPaWlpXHvttVFWVma4ALCblJWVxXXXXRclJSU5s6aZM2fe/f/+3/9bZboAACSRABgAgP/l5JNPHldeXv50rqynU6dOMXbs2Jw5kQQA2aSoqCiuueaa6NixY86sqby8/MlTTz11gukCAJBUAmAAAP6PSy655K66urq1ubKefffdN6644orIy7P9BYBdJS8vL6688sro3bt3zqyprq6u/JJLLvmh6QIAkOi9uhYAAPBus2bNqn7ooYfujIh0rqxp4MCBcd555xkuAOwi559/fhxyyCG5tKT0gw8+eOesWbOqTRcAgCTLb3tQ9NzpjndbRG15oQ4BADRTEydOXDNmzJi8Tp06Dc2VNfXp0yfy8/PjzTffNGAA+ATOOuusOOmkk3JqTa+//vp9Z5555kTTBQAgCYq7N0Ze6c5/5gQwAADv6dRTT/31li1bXs+lNZ122mlx9NFHGy4AfEzHHntsnHrqqTm1pi1btrxx2mmn/cZ0AQDIBQJgAADeU0VFReONN974jcbGxqpcWtcFF1wQRx55pAEDwEd05JFHxuc+97mcWlNjY2PVzTff/I2KiopGEwYAIBcIgAEAeF9//OMf1z/yyCPfiRz6HnAqlYqLLroohgwZYsAA8CENHTo0LrrookilUrm0rPQjjzzynfvvv3+dCQMAkCsEwAAAfKBLL730hQULFvwupzbCeXnxpS99Kfbff38DBoAPcNBBB8WXvvSlyMvLrVdJCxYs+N2ll176ggkDAJBLBMAAAHwoo0eP/mVVVdXcXFpTYWFhfOUrX4kePXoYMAC8h169esUVV1wRBQUFObWuqqqqOaNHj/6lCQMAkGsEwAAAfCgVFRWNV1111S0NDQ0bcmldJSUlcfPNN8c+++xjyADwLr17946bbropiouLc2pdDQ0NG6666qqv++4vAAC5SAAMAMCHNmHChE3333//tzKZTDqX1lVcXBzXXXdddO/e3ZABYIfu3bvHtddeG61atcqpdWUymfT999//rQkTJmwyZQAAcpEAGACAj2Ts2LGz58+f/9tcW1fr1q3juuuuiw4dOhgyAM1ehw4d4rrrrovWrVvn3Nrmz5//m7Fjx842ZQAAcpUAGACAj+y44477xaZNm17MtXW1a9cubrzxxmjXrp0hA9BstW3bNmf/Pty4ceOLxx13nO/+AgCQ0wTAAAB8ZNXV1emLL774W3V1datzbW0dO3aMG2+8Mdq0aWPQADQ7ZWVlceONN0bHjh1zbm21tbWrL7zwwturq6vTJg0AQC7Lb3tQ9NzZD9LbImrLC3UIAICdWrZsWf327dtfOvbYY0/Ny8trkUtrKykpiaFDh8Zrr70WNTU1hg1As9ChQ4f42te+Fp06dcq5tTU1NW39zne+M/bBBx9cb9IAAOSC4u6NkVe6858JgAEA+NhefPHFzYcccsiyAQMGnBgRqZzaRBcXx5AhQ4TAADQLHTt2jJtuuik6dOiQi8tLjx8//ravfvWrc0waAIBc8X4BsCugAQD4RC688MIZb7zxxm9ycW3t27ePm266KSdPQgHA2zp16pTL4W+88cYbv77wwgufM2kAAJoLATAAAJ/YqFGjfrFhw4aZubi2t0Pgzp07GzQAOadz585x0003Rfv27XNyfRs2bJg5atSo+0waAIDmRAAMAMAnVltbm77sssu+V1dXtzoX19euXbu44YYbomPHjoYNQM7o0KFDXH/99dGuXbtc3Z+s/sIXvvDd2tratGkDANCc+AYwAAC7xJIlS+oj4pVRo0admpeX1yLX1ldcXBxDhw6NuXPnxrZt2wwcgETr0qVL3HjjjTl77XNTU1P1nXfeec0f/vCHdaYNAEAuer9vAAuAAQDYZWbNmlXVo0ePuYceeujoVCqVn2vra9WqVYwYMSIWLVoUlZWVBg5AIu23335x0003RVlZWU6uL51ON/z617++4fbbb3/TtAEAyFUCYAAA9phJkyatPeqoozbsu+++R+fi+goLC2P48OGxbNmy2LBhg4EDkCgDBgyIa6+9Nlq1apWza5w2bdq/XXLJJc+ZNgAAuez9AmDfAAYAYJc77bTTHn/rrbcezNX1FRUVxTXXXBNDhgwxbAASY8iQIXHNNddEUVFRzq5xwYIFvzv99NOfMG0AAJozATAAALvFEUcccc+GDRtm5ur6CgoK4sorr4wjjjjCsAFIwt/LceWVV0ZBQUHOrrG8vPypESNG/LdpAwDQ3AmAAQDYLaqrq9MXXXTRd2pra1fk7GY6Ly8uvvjiOPLIIw0cgKw1atSouPjiiyMvL3dfA23dunXxZz/72e83NDRkTBwAgObON4ABANhtli9fvr2mpuaFY4899uT8/PyWubjGVCoVgwYNikwmE4sWLTJ0ALLK6aefHueee26kUqmcXWN9fX3FDTfccM3UqVOrTBwAgObi/b4BLAAGAGC3evnll7cUFBS8cMQRR4zOy8trkYtrTKVSccABB0SnTp1i7ty5kck4fATA3lVYWBhXXHFFHHPMMTm9zsbGxuo777zzKz/72c9WmzoAAM2JABgAgL1qxowZlb169Xp98ODBJ6dSqfxcXWfPnj2jb9++8fe//z0aGxsNHoC9olWrVnH11VfHwIEDc3qd6XS64be//e2Nt9122wJTBwCguREAAwCw1z3xxBPlw4cPX9OvX79jIyJn76Hs2LFjDBw4MObMmRN1dXUGD8Ae1a5du7jxxhujT58+ub7U9JQpU779xS9+8XlTBwCgOXq/ADhPewAA2FPGjBkz9Y033vh1rq+zZ8+eceONN0bHjh0NHYA9pkuXLnHTTTdF9+7dc36tc+fO/eU555zzF1MHAID/SwAMAMAe9alPfernS5cufTjX19mlS5e49dZb48ADDzR0AHa7gQMHxje/+c3o1KlTzq/1rbfeemjEiBG/MnUAANg5ATAAAHvcsccee8/GjRtfyPV1FhcXx7XXXhsjRowwdAB2m8MPPzyuuuqqaNmyZc6vdePGjc8fffTR95g6AAC8NwEwAAB7XEVFReNxxx339crKyr/l+loLCgrisssui/PPPz9SqZThA7DLpFKpOP/88+PSSy+NgoKCnF/vpk2bXj7ssMNuqaysbDJ9AAB4bwJgAAD2isWLF9efddZZN1dXV7/ZHNZ7/PHHx5e//OUoKioyfAA+sRYtWsSXv/zlOP7445vFequrq98cM2bMN8rLyxtMHwAA3l9+24Oi585+kN4WUVteqEMAAOw2a9asaVi1atWs0aNHH1dQUNA619fbrVu3OOCAA2LevHlRX1/vAQDgYykrK4trrrkmDjrooGax3rq6uvKxY8de89RTT202fQAA+Ifi7o2RV7rznwmAAQDYq+bNm1ezevXqZ04++eTjCwoKSnN9ve3atYuRI0fG8uXLY+PGjR4AAD6S/v37x0033RRdu3ZtFuutr69fd9111335T3/6U4XpAwDA/xAAAwCQ1ebMmbMtlUq9fOSRR56Ul5eX83ckt2jRIkaMGBG1tbWxdOlSDwAAH8rxxx8fX/rSl5rN5wQaGxu33HXXXdf99Kc/XWn6AADwvwmAAQDIejNnzqzs2bPn64MHDz4plUrl5/p6U6lUHHLIIdGqVatYsGBBZDIZDwEAO5WXlxef/exn4/TTT49UKtUs1pxOp7f//ve//+o3vvGN1z0BAADwfwmAAQBIhEmTJpXvs88+8wYOHHhCKpUqaA5r3m+//WLAgAExd+5c3wUG4P8oKyuL6667LoYNG9Zs1pxOp7f/8Y9/vOmqq676qycAAAB2TgAMAEBiTJw4cc3BBx+85MADDzwulUrlNYc1t2/fPoYOHRqLFi2KLVu2eAgAiIiIffbZJ66//vro2bNns1lzJpNpnDBhwm1f/OIXn/cEAADAexMAAwCQKI8++ujy/fff/42DDjrohOZwHXRERHFxcRx11FHR2NgYb731locAoJkbPXp0XHHFFVFSUtJs1pxOpxsefvjhr15yySWzPAEAAPD+BMAAACTO+PHjVw0cOHDpAQcccGxzOQmcSqViwIAB0aVLl3jjjTeiqanJgwDQzBQVFcWll14aJ554YrP53m/EP07+Pv7447dffPHFMz0FAADwwQTAAAAk0iOPPLLs0EMPXbb//vs3mxA4IqJHjx4xZMiQePPNN2Pr1q0eBIBmonv37vEv//IvccABBzSrdWcymaYnnnji9s997nPPeAoAAODDEQADAJBYDz/88NJjjjlmY+/evY+KiGZzFKq0tDSGDx8eq1evjvXr13sQAHLcwIED45prrol27do1t6VnZsyY8YOzzjprqqcAAAA+PAEwAACJdv/99795zDHHVO6zzz5HRDMKgVu0aBGHHXZYtGzZMhYuXBjpdNrDAJBjCgoK4pxzzonzzz8/WrRo0dyWn37uuefuOuWUUyZ4EgAA4KMRAAMAkHi///3v5w8bNmxF3759j2lO10GnUqno27dvDB06NBYvXhxbtmzxMADkiJ49e8YNN9wQgwcPblbf+434x7XPU6ZM+fbpp58+2ZMAAAAfnQAYAICc8OCDDy4ZNmzYin79+jWrEDgionXr1nHEEUdEfX19LF261MMAkGCpVCpOOOGEuOKKK6JNmzbNbv07wt9vnXPOOX/xNAAAwMcjAAYAIGc89NBDS4YNG7a8X79+xza3EDg/Pz8OPvjg6NWrV8yfPz8aGho8EAAJU1JSEpdffnmccMIJkZ+f3+zWn8lkGp944olvffazn53maQAAgI9PAAwAQE556KGHlo4cOXJdnz59RqWa252ZEdG1a9cYNmxYLFu2LCorKz0QAAnRt2/fuO6662K//fZrluvPZDLpp59++rvnnHPO054GAAD4ZATAAADknD/96U+LDj300KX7779/s7sOOiKiuLg4jjzyyCgpKYk333wz0um0hwIgSxUUFMRnP/vZuPDCC6OkpKRZ9iCdTjc88sgjt5x//vnTPREAAPDJCYABAMhJDz/88NId3wQelUqlmt09mqlUKvr06RMHH3xwLFy4MLZt2+ahAMgynTt3jrFjx8bQoUOjGV5aERH/CH+feOKJ2y+88MLnPBEAALBrCIABAMhZDz300JIePXq8NmjQoGPz8vJaNMcetG3bNkaNGhVNTU2xZMkSDwVAFkilUjF69Oi48soro0OHDs22D01NTdt++9vf/stll132oqcCAAB2HQEwAAA5bdKkSeXdu3efM3jw4GYbAufn58eAAQOiV69esWDBgti+fbsHA2Avad26dVx66aVx/PHHR35+frPtQ2NjY/WvfvWrf7nuuute81QAAMCuJQAGACDnTZ48eW1jY+OMI4444uiCgoKS5tqHrl27xqhRo2Lbtm2xcuVKDwbAHpRKpWLUqFExduzY6NWrV7PuRX19/fo77rjjK9/61rcWejIAAGDXEwADANAsPP/881UbNmx45rjjjjuqsLCwrLn2obCwMAYNGhT77bdfLF68OGpraz0cALtZ+/bt44orrogTTzwxCgub9/uU2tralTfffPPVP/nJT1Z7MgAAYPcQAAMA0Gz87W9/27p27doZJ5xwwsjCwsK2zbkXnTp1ipEjR0Z1dbXTwAC70ciRI+Pqq6+OHj16NPte1NTULL/hhhuu/e1vf7vOkwEAALuPABgAgGbltdde2zpv3rynTznllKFFRUWdmnMvCgsL49BDD4399tsvFi1a5DQwwC709qnfk08+udmf+o2I2Lx587yLL774unHjxm30dAAAwO71fgFwat9zYsTOftC4LmLjq610DwCAxOrVq1fhs88++69du3Y9QTciGhoaYurUqTF58uRobGzUEICPqaCgIE499dQYPXq04HeH8vLyp4499tjvrly5skE3AABg9+swrDYKuuz8ZwJgAAByWuvWrfNeeumlm/fdd9+zdeMfVq9eHffff38sWbJEMwA+ov322y8uuugi1z2/w8KFC38/fPjwnzY0NGR0AwAA9gwBMAAAzd7zzz9/8aGHHnp1RKR0IyKTycTMmTPjz3/+c9TV1WkIwAcoKSmJ8847L0aMGBGplL9Kdki//PLL9xx77LEPagUAAOxZ7xcA+wYwAADNwn333Tfn+OOP39yrV6/DQwgcqVQqevfuHcOHD49169ZFRUWFhwTgPRxyyCExduzY6N+/v/B3h0wm0/jMM8/828knnzxONwAAYM97v28AC4ABAGg2fve7370xePDgJf369Ts6lUrl60hEcXFxjBgxInr06BFLly6N2tpaTQHYoUOHDvGFL3whzjzzzCguLtaQHZqammoeeOCBWz73uc9N1w0AANg7BMAAALDDww8/vKygoOC54cOHH1FQUFCqI//QrVu3OO6446K0tDQWL14cTU1NmgI0Wy1btoxzzjknLr300ujevbuGvENtbe2K22677arbbrvtDd0AAIC9RwAMAADv8Oyzz25avHjx0yeddNKQoqKiTjryD3l5edGnT58YOXJkbN26NVatWqUpQLNz+OGHx1e+8pUYMGBA5OXlacg7VFVV/e3CCy+8/oEHHvDdAAAA2MsEwAAA8C7z58+vefbZZ58+44wz+hcXF/fSkf/RsmXLGDJkSOyzzz6xdOnSqKmp0RQg53Xs2DG++MUvximnnBItW7bUkHdZt27dMyeffPI3Xn755W26AQAAe9/7BcCpfc+JETv7QeO6iI2vttI9AAByWmFhYer555//0sEHH3y5bvxfTU1N8fzzz8f48eOjurpaQ4Cc07p16zjzzDPjyCOPdOJ35zJ///vff3rMMcfc39DQkNEOAADIDh2G1UZBl53/TAAMAAARMWnSpM8cc8wxt6RSKdfg7ERNTU1MmTIlpk2bFg0NDRoCJF5hYWGccsopcdJJJ0VRUZGG7EQ6na6fOnXqd88555y/6AYAAGSX9wuAXQENAAAR8Yc//GHhfvvt98aAAQOOysvLkwS8S2FhYQwYMCCGDh0amzZtinXr1mkKkFiDBw+Oq666KoYOHRoFBQUashONjY1Vv//972/5whe+MEs3AAAg+/gGMAAAfAgTJkxYXV1dPf3II4/8VGFhYTsd+b9KS0vjsMMOi/79+8eaNWti8+bNmgIkRu/evePyyy+PU045JUpLSzXkPWzdunXxLbfccs33vve9hboBAADZyTeAAQDgI+jTp0+LJ5988us9evQ4TTfe3/z58+ORRx6JlStXagaQtXr16hXnnHNODBgwQDM+wKpVq5444YQTfrBy5Ur3/QMAQBbzDWAAAPgYnnnmmfOHDx9+fSqVytON95bJZGL27Nkxbty4qKio0BAga3Tu3DnOOuusGDp0aKRSKQ15/z/Lm2bNmvXDk08++THdAACA7OcbwAAA8DH85je/eX3//fd//cADDzzSd4HfWyqViu7du8cxxxwT7dq1i2XLlkV9fb3GAHtN27Zt49xzz42LL744evToIfz9AI2NjdUPPvjgLZ/97Gf/ohsAAJAMvgEMAAAf0/jx41dFxPOHHXbYiMLCwjIdeW95eXnRu3fvOOqoo6KgoCBWrlwZjY2NGgPsMcXFxXHKKafEl770pejbt2/k5bnA4YPU1tau+MEPfnD9LbfcMk83AAAgQf/94xvAAADwyQwePLjVo48++s1u3bqdpBsfTn19fTzzzDMxderU2LZtm4YAu01ZWVmceuqpceSRR0ZRkQsbPqyVK1c+/ulPf/pHixcvdm0DAAAkjG8AAwDALvLkk0+edeSRR96USqVcl/MhCYKB3eXtE7/HHnus4PcjyGQyDbNmzfoP3/sFAIDk8g1gAADYRX7/+98v6NGjx2uHHHLIyPz8fL8x+SEUFBREv3794qijjoq8vLxYtWqVq6GBT6Rly5ZxwgknxBVXXBEHHXRQFBQUaMqH1NDQsOG3v/3t1z7/+c8/oxsAAJBcroAGAIBd7Lzzzut4991339m2bdvBuvHR1NTUxLPPPhvTpk2LLVu2aAjwoZWVlcXxxx8fxxxzTBQXF2vIR1RVVfW3a6+99vZHHnlkg24AAECyuQIaAAB2g06dOhVMmzZtbN++fT8XESkd+WgaGhri+eefjyeffDI2bJBFAO/7522cdNJJccQRR0RhodvKPobMokWL/nTsscf+pLKyskk7AAAg+QTAAACwG/3hD38Ydfrpp99WUFDQRjc+unQ6Ha+++mpMnTo1Vq5cqSHAP/Xq1StOOeWUGDp0aOTl5WnIx9DY2Fg1YcKEOy666KKZugEAALlDAAwAALvZaaed1vbee+/9docOHUbqxse3fPnymDZtWrz88suRTqc1BJqhvLy8OOyww+L444+P3r17a8gnsHHjxue//OUvf3fSpElVugEAALlFAAwAAHtAYWFh6qmnnjpv+PDh16RSKXeUfgIbNmyIGTNmxHPPPRc1NTUaAs1AcXFxjBo1Ko4++ujo2LGjhnwCmUym4ZVXXvl/J5100kMNDQ0ZHQEAgNzzfgFwftuDoufOfpDeFlFb7p0VAAB8WOl0On7zm9+8Xlpa+uLgwYM/VVhYWKYrH09xcXEMGDAgjj322GjTpk2sXbs2amtrNQZyUIcOHeKMM86ISy+9NAYOHBjFxcWa8gnU1tau+slPfnLjxRdf/IybFAAAIHcVd2+MvNKd/8wJYAAA2A1OPPHENvfdd9+tnTp1Olo3PrnGxsb429/+Fs8++2wsWrRIQyAH9OvXL44++ugYNmxYFBQUaMguUFFR8cwXv/jFf5s+ffoW3QAAgNzmCmgAANhLHn744RNGjx799YKCgta6sWusX78+Zs6cGc8//3xUV1drCCRIaWlpHHnkkXHUUUdF586dNWQXaWxs3DJ16tS7PvvZz/5FNwAAoHkQAAMAwF50ySWXdP3+97//rXbt2g3VjV2nsbExXnvttXjuuedi/vz5GgJZbMCAATFq1KgYPHiw0767WFVV1atf//rXv/e73/1urW4AAEDzIQAGAIC9rF27dvlTp0699OCDD740lUrl68iutXz58nj++efj5ZdfjpqaGg2BLFBSUhLDhw+PI444Inr37q0hu1gmk2mcN2/efSeeeOJvq6urfewXAACaGQEwAABkia9//ev73Xjjjf9aWlraXzd2vXQ6HW+++WY899xz8dprr0VjY6OmwB5UUFAQgwcPjlGjRsUBBxwQeXl5mrIbVFdXL/zP//zPf/3BD36wRDcAAKB5EgADAEAWOfjgg1v9+c9/vrZ3795jIiKlI7tHZWVlvPjii/HCCy/EunXrNAR2o65du8bIkSPj8MMPj7Zt22rI7pNZunTpn88888z/t3jx4nrtAACA5ksADAAAWejuu+8eePHFF9/WqlUrd6PuZuXl5fHqq6/GSy+9FOvXr9cQ2AU6d+4cI0aMiGHDhkW3bt00ZDerqalZ9tvf/vbOm266aa5uAAAAAmAAAMhS/fr1K3r44Ycv79+//4WpVMpdqXvA8uXL46WXXoqXX345qqurNQQ+grKyshg+fHiMGDHCd333kEwmk164cOEfzj777F8sXbp0u44AAAARAmAAAMh6P/3pT4d97nOf+2bLli176Mae0dDQEHPnzo2//vWvMXfu3Ni+Xa4CO9OyZcsYNGhQDBs2LA455JAoKCjQlD2ktrZ21R//+Mc7rr322r/rBgAA8E4CYAAASIA+ffq0ePTRR69wGnjPS6fTsXTp0nj11VedDIaIaNu2bQwbNiyGDRsWffr0ibw8fyTtSZlMpuG11177+ZlnnvmnioqKRh0BAADeTQAMAAAJ8uMf//jQCy644JutWrXaRzf2vLdPBs+ePTvmzp0bdXV1mkKzUFZWFoMHD45hw4ZF//79Iz8/X1P2gpqammX333//nTfccINv/QIAAO9JAAwAAAnTrl27/HHjxp37qU996qq8vDwb870kk8nEihUrYu7cuTFnzpxYsWJFZDIZjSEnpFKp6Nu3bwwbNiwGDRoUHTt21JS9qKmpqfbVV1/92ZgxY/5cWVnZpCMAAMD7EQADAEBCffnLX+5x++23f7V9+/aH68bet2XLlnjjjTdizpw5MW/evKivr9cUEqVly5Zx8MEHx6BBg+KQQw6J0tJSTckCGzdufPG73/3uv//iF79YoxsAAMCHIQAGAIAEKywsTE2cOPGMkSNHXlNQUNBaR7JDXV1dvPnmm/HGG2/EG2+8EevXr9cUslKXLl3ioIMOioMOOigOOOCAKCoq0pQs0djYuGXmzJk/PvPMMyc2NDS4XgAAAPjQBMAAAJADjjzyyNY/+9nPrujbt++5EZGnI9mluro6Fi5cGPPnz4958+ZFZWWlprBXtGvXLg455JAYMGBA9O/fP1q39nsjWSj91ltv/fmqq676xaxZs6q1AwAA+KgEwAAAkEN++ctfjhgzZsyNrVq16q0b2SmdTsfKlStj0aJFsXDhwli8eHFs27ZNY9gtSkpKol+/ftG/f//Yf//9o1evXpGX53dEslVNTc3yRx999EdXXnnlK7oBAAB8XAJgAADIMd26dSt8+OGHPzd48ODL8vPzbdyzXCaTiTVr1sTChQtj0aJFsWjRotiyZYvG8LGUlZVF//79/xn6du/ePVKplMZkuaampprXXnvtV2PGjHmgoqKiUUcAAIBPQgAMAAA56rjjjiv7r//6r8tdC508mzdvjuXLl8eKFSti+fLlsXjx4qipqdEY/pfi4uLo169f9O7dO/bZZ5/Yd999o6ysTGMSJJPJpJcsWfLn66677pfTp0/3mx8AAMAuIQAGAIAc99Of/nTIueeee3NpaWlf3UimxsbGWLlyZSxdujSWLVsWy5cvj3Xr1kUmk9GcZiKVSkWXLl1in332iT59+kSfPn2iV69eUVBQoDkJtXXr1sUPPvjgj6699tq/6wYAALArCYABAKAZaNeuXf64cePOGTp06BUFBQWtdST56uvrY+XKlf88KbxixYpYu3ZtpNNpzUm4vLy86Nq1a+yzzz7//KdXr17RsmVLzckBjY2NW/7617/+4pxzznm0srKySUcAAIBdTQAMAADNyIknntjmnnvuuXzfffcdk0qlHB3MMdu3b481a9bEmjVrYu3atbF27dooLy+PDRs2CIazUF5eXnTs2DG6desWXbt2jW7dukW3bt2iR48eUVhYqEE5JpPJNC5ZsuRR1z0DAAC7mwAYAACaoa9+9av7Xnfdddd16NDhCN3IfY2Njf8MhNetWxfr1q2LioqKWLduXWzbtk2DdrPS0tLo3LnzP//p0qVLdO3aNbp27eoK52Ziw4YNM//rv/7rxz/60Y+W6wYAALC7CYABAKAZ++UvfznirLPOuq64uNj3gZupmpqaWL9+/T//qaioiMrKyqisrIxNmzZFY2OjJn2AgoKCaN++fbRr1y7at28fHTt2jC5dukSnTp2ic+fOUVxcrEnN1NatW98aP378PVdcccXLugEAAOwpAmAAAGjm2rVrl//ggw+eOWLEiCsLCwvb6gjvtHnz5n+GwZs2bYrKysqorq6OLVu2xJYtW6K6ujqqq6sjk8nk3NpTqVS0bt06WrduHWVlZdGmTZsoLS39X2Fvu3btok2bNh4U/peGhobKl1566efnnHPO+OrqavevAwAAe5QAGAAAiIiIoUOHFt97770XHHjggRfk5+c7ssiHlk6n/xkEV1dXR01Nzfv+k8lkora2NtLpdNTX10dTU1PU1dXt0u8U5+XlRcuWLSM/Pz+KiooiLy8vWrVqFalUKoqLi3f6T0lJSbRq1eqfgW9paWnk5eUZMB9aU1NTzYIFC/745S9/+Y+zZ8+u0REAAGBvEAADAAD/y2mnndb2rrvuurRPnz5n5+XlFeoIe9LbgfDbtm/f/r7XUBcUFESLFi3++b/fDnxhT8pkMg1LliwZd8stt/xq0qRJVToCAADsTQJgAABgp0477bS2d95554X777//5wTBAP9XJpNpWLhw4QO33nrrHwS/AABAtni/ADi/7UHRc2c/SG+LqC33/gcAAHLZokWL6u69995X0un0swcddFCnkpKS3roC8A8VFRUz/7//7/+77aKLLpq6aNGiOh0BAACyRXH3xsgr3fnPBMAAAEDMnDmz8u67736qqalpWr9+/Ypbt27dN5VKpXQGaG4ymUx6zZo1U+65555/Peeccx6cOXNmpa4AAADZRgAMAAB8KDNnzqz88Y9//Gw6nZ4uCAaak7eD37vvvvtfzz///McEvwAAQDYTAAMAAB+JIBhoLgS/AABAEgmAAQCAj+XtILisrOyFvn37diwuLu4VEYJgIBdkKioqnrv33nu/PWbMmEcEvwAAQJK8XwCc2vecGLGzHzSui9j4aivdAwAA/unqq6/u8ZWvfOX8Pn36nJWXl9dCR4CkSafT9UuXLh3/X//1Xw/84he/WKMjAABAEnUYVhsFXXb+MwEwAADwkZ1xxhntb7/99rMPPPDA8/Pz81vrCJDtmpqaqhcsWPDgd77znUcmTpzotC8AAJBoAmAAAGC3GD58eMkPf/jDzwwePPjioqKijjoCZJv6+voNr7322u9vvPHGx2fPnl2jIwAAQC4QAAMAALvV0KFDi++5556zDjnkkPOKioq66giwt9XV1a19/fXXH7z++uvHC34BAIBcIwAGAAD2iFatWuXdc889w0455ZTzO3bseJSOAHtYZsOGDbOmTJny4PXXX/9qbW1tWksAAIBcJAAGAAD2uH/913/tf/7555/dq1ev0/Ly8lroCLC7pNPp+pUrV05+4IEHHvnOd76zSEcAAIBcJwAGAAD2mjPOOKP97bfffvYBBxzw2YKCgjY6AuwqjY2NVW+++eafv/e97z06YcKETToCAAA0FwJgAABgrxs+fHjJ97///dGDBg0aU1paur+OAB9XdXX1wtdee+3Rr371q1Nfe+21Wh0BAACaGwEwAACQVb761a/ue8EFF3y6b9++ZxUUFLTWEeCDNDY2bnnrrbfG/+EPf5j4ox/9aLmOAAAAzZkAGAAAyEpDhw4t/sEPfnDy4MGDz27dunV/HQHerbq6+s2XX375weuuu+7ppUuXbtcRAAAAATAAAJDlCgsLU3ffffeQ0aNHn9G1a9fj8vLyinQFmq90Ol1XXl4+bcqUKROuvfbav+sIAADA/yYABgAAEqNPnz4t/v3f/33UyJEjz2rfvv2nIiKlK9AsZDZt2vTXF1544bGvfe1rzzntCwAA8N4EwAAAQCJddNFFXa6++uqTDzzwwLNbtmzZTUcg99TV1a1ZsGDBuJ/+9KdP3n///et0BAAA4IMJgAEAgETr1q1b4d13333k4YcffmqHDh2OyMvLK9QVSK50Ot2wcePGWbNmzZp8/fXXz6qoqGjUFQAAgA9PAAwAAOSMo48+uvWtt956/CGHHHJKu3btBkdEnq5AIqQrKytfmzdv3uQ777xz+owZM6q1BAAA4OMRAAMAADnpuOOOK/vGN75x/CGHHHJa27ZtB4bvBUO2yVRVVc2dN2/epO9///vTpk+fvkVLAAAAPjkBMAAAkPNuu+22vmedddZJffr0Oa5Vq1a9dQT2ntra2uXLly+f/uijjz51xx13vKUjAAAAu5YAGAAAaFa+9KUvdbv44ouP7t+//wlOBsMekamqqpq7cOHCv/z+97+fcd9995VrCQAAwO4jAAYAAJqtSy65pOtll112jDAYdrl0VVXVvIULF/7lV7/61bO/+93v1moJAADAniEABgAAiIirr766x/nnnz9q//33P7JNmzZDUqlUga7Ah5fJZBoqKyv/vnjx4uf+9Kc/zbr33ntX6woAAMCeJwAGAAB4l379+hV97WtfGzRy5MhRPXv2PLaoqKizrsD/VV9fv37VqlXPvPDCC8/9+7//+5zFixfX6woAAMDeJQAGAAB4H61bt8678847Bx599NFHde/efURpaen+4apomq/M1q1bF69Zs+bF5557btY3v/nNOdXV1WltAQAAyB4CYAAAgI9g8ODBrcaOHXvI8OHDD+vevfvw1q1bHxACYXJXprq6+s01a9a88sorr7z8k5/8ZN5rr71Wqy0AAADZSwAMAADwCVx//fX7nHHGGYf169dvePv27Yfm5+e31hWSrLGxsXrjxo2vvvXWWy+PHz/+lR//+McrdQUAACA5BMAAAAC70Je//OUe55xzzvA+ffoM7tix45CioqKuukI2q6+vX7t27doXFy9ePGfixImv3Xvvvat1BQAAILkEwAAAALvRl7/85R6f+cxnBvfr129Qly5dDm/ZsqVAmL2qrq5u7bp16wS+AAAAOUoADAAAsIe0atUq75prrtnn2GOPPXi//fY7uH379oeUlpb2TaVS+brDbpKuqalZtnHjxnlvvfXW3GeffXbef/3Xfy2vra1Naw0AAEBuEgADAADsRQceeGDLq6+++oAhQ4Yc3LNnz4Pbtm17sGuj+biampqqq6qqXi8vL583Z86ceb/85S/nvfjii1t1BgAAoPkQAAMAAGSZoUOHFn/xi1/cf9CgQQf26NHjwHbt2h3YqlWr3qlUKk932CFdU1OzvLKycsHq1asXzJkzZ8Gf//znJTNmzKjWGgAAgOZNAAwAAJAAxx13XNkFF1xw4MEHH3xA165dDywtLd23pKRkn1QqVag7uS2TyTRs27ZtRXV19dJ169YtfOONNxZOmDBh4YQJEzbpDgAAAO8mAAYAAEiw8847r+OJJ57Yp3///vt16dKlT5s2bfZr3bp1v/z8/GLdSZampqaa6urqxZs3b16ybt26pQsXLlzy9NNPL33ooYc26A4AAAAflgAYAAAgx7Rr1y7/kksu6TFkyJCe++67b89OnTr1Kisr61VcXNyzZcuW3VKpVL4u7R2ZTKaprq6uvKamZtWWLVtWVlRUrFy6dOnK2bNnr7r//vvXVFZWNukSAAAAn4QAGAAAoBnp1KlTwec+97luQ4cO7bnPPvv0aNeuXafWrVt3Li4u7tqyZcvORUVFnfLy8lro1MeTTqe319fXr6+rq6uoqalZW11dvb6ysnL9ihUrVr/66qurHnzwwbUVFRWNOgUAAMDuIgAGAADgfznjjDPaH3bYYZ369OnTuUuXLp3Kysral5SUtC0uLu5YVFTUrqioqG2LFi065OfnlzaXnjQ1NW3dvn37xvr6+qr6+vrKmpqaDdu2bavasmXLpnXr1lUsXbp0/Ysvvrh+4sSJlZ4gAAAA9iYBMAAAAB9Lr169CkeNGtXuoIMOatexY8ey9u3bl7Zp06Z1SUlJWXFxcetWrVq1btGiRVlRUVHrwsLC1hGRX1hYWBoR+QUFBSV5eXkFeXl5u/0/LtPpdG06nW5sbGzcFhFNDQ0NW3f83+r6+vrq7du3b6mtra2uqamp3rZtW/XmzZurN23aVL1hw4YtCxYsqJo1a1bl0qVLt5s4AAAASSAABgAAYK/q169fUffu3Vvss88+xSUlJQVv//8LCwtT3bp1+8BTxuXl5VsbGhoyb//vbdu2Na5YsaJmzZo12xcvXlyvwwAAADQn7xcAF2gPAAAAu9vixYvrdwS11boBAAAAu0+eFgAAAAAAAADkBgEwAAAAAAAAQI4QAAMAAAAAAADkCAEwAAAAAAAAQI4QAAMAAAAAAADkCAEwAAAAAAAAQI4QAAMAAAAAAADkCAEwAAAAAAAAQI4QAAMAAAAAAADkCAEwAAAAAAAAQI4QAAMAAAAAAADkCAEwAAAAAAAAQI4QAAMAAAAAAADkCAEwAAAAAAAAQI4o0AIAAAAAAACA5GhoLIyCxoaIiEilIpNXGE1v/0wADAAAAAAAAJAghQUN/0x6MxGppvT/5L6ugAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAAYAAAAAAADIEQJgAAAAAAAAgBwhAIb/v5272ZHiusM4/FZ1NUkz9sQwOF4EyZJtpJCwysa5jSy4n1xPEqRIuQFvvfGSgIwBOzGRQAQERnx0d1UW0cgWGvKxsMGvnmfVdc7/1OJsf+oCAAAAAACAEgIwAAAAAAAAQAkBGAAAAAAAAKCEAAwAAAAAAABQQgAGAAAAAAAAKCEAAwAAAAAAAJQQgAEAAAAAAABKCMAAAAAAAAAAJQRgAAAAAAAAgBICMAAAAAAAAEAJARgAAAAAAACghAAMAAAAAAAAUEIABgAAAAAAACghAAMAAAAAAACUEIABAAAAAAAASgjAAAAAAAAAACUEYAAAAAAAAIASAjAAAAAAAABACQEYAAAAAAAAoIQADAAAAAAAAFBCAAYAAAAAAAAoIQADAAAAAAAAlBCAAQAAAAAAAEoIwAAAAAAAAAAlBGAAAAAAAACAEgIwAAAAAAAAQAkBGAAAAAAAAKCEAAwAAAAAAABQQgAGAAAAAAAAKCEAAwAAAAAAAJQQgAEAAAAAAABKCMAAAAAAAAAAJQRgAAAAAAAAgBICMAAAAAAAAEAJARgAAAAAAACghAAMAAAAAAAAUEIABgAAAAAAACghAAMAAAAAAACUEIABAAAAAAAASgjAAAAAAAAAACUEYAAAAAAAAIASAjAAAAAAAABACQEYAAAAAAAAoIQADAAAAAAAAFBCAAYAAAAAAAAoIQADAAAAAAAAlBCAAQAAAAAAAEoIwAAAAAAAAAAlBGAAAAAAAACAEgIwAAAAAAAAQAkBGAAAAAAAAKCEAAwAAAAAAABQQgAGAAAAAAAAKCEAAwAAAAAAAJQQgAEAAAAAAABKCMAAAAAAAAAAJQRgAAAAAAAAgBICMAAAAAAAAEAJARgAAAAAAACghAAMAAAAAAAAUEIABgAAAAAAACghAAMAAAAAAACUEIABAAAAAAAASgjAAAAAAAAAACUEYAAAAAAAAIASAjAAAAAAAABACQEYAAAAAAAAoIQADAAAAAAAAFBCAAYAAAAAAAAoIQADAAAAAAAAlBCAAQAAAAAAAEoIwAAAAAAAAAAlBGAAAAAAAACAEgIwAAAAAAAAQAkBGAAAAAAAAKCEAAwAAAAAAABQQgAGAAAAAAAAKCEAAwAAAAAAAJQQgAEAAAAAAABKCMAAAAAAAAAAJQRgAAAAAAAAgBICMAAAAAAAAEAJARgAAAAAAACghAAMAAAAAAAAUEIABgAAAAAAACghAAMAAAAAAACUEIABAAAAAAAASgjAAAAAAAAAACUEYAAAAAAAAIASAjAAAAAAAABACQEYAAAAAAAAoIQADAAAAAAAAFBCAAYAAAAAAAAoIQADAAAAAAAAlBCAAQAAAAAAAEoIwAAAAAAAAAAlBGAAAAAAAACAEgIwAAAAAAAAQAkBGAAAAAAAAKCEAAwAAAAAAABQQgAGAAAAAAAAKCEAAwAAAAAAAJQQgAEAAAAAAABKCMAAAAAAAAAAJQRgAAAAAAAAgBICMAAAAAAAAEAJARgAAAAAAACghAAMAAAAAAAAUEIABgAAAAAAACghAAMAAAAAAACUEIABAAAAAAAASgjAAAAAAAAAACUEYAAAAAAAAIASAjAAAAAAAABACQEYAAAAAAAAoIQADAAAAAAAAFBCAAYAAAAAAAAoIQADAAAAAAAAlBCAAQAAAAAAAEoIwAAAAAAAAAAlBGAAAAAAAACAEgIwAAAAAAAAQAkBGAAAAAAAAKCEAAwAAAAAAABQQgAGAAAAAAAAKCEAAwAAAAAAAJQQgAEAAAAAAABKCMAAAAAAAAAAJQRgAAAAAAAAgBICMAAAAAAAAEAJARgAAAAAAACghAAMAAAAAAAAUEIABgAAAAAAACghAAMAAAAAAACUEIABAAAAAAAASgjAAAAAAAAAACUEYAAAAAAAAIASAjAAAAAAAABACQEYAAAAAAAAoIQADAAAAAAAAFBCAAYAAAAAAAAoIQADAAAAAAAAlBCAAQAAAAAAAEoIwAAAAAAAAAAlBGAAAAAAAACAEgIwAAAAAAAAQAkBGAAAAAAAAKCEAAwAAAAAAABQQgAGAAAAAAAAKCEAAwAAAAAAAJQQgAEAAAAAAABKCMAAAAAAAAAAJQRgAAAAAAAAgBICMAAAAAAAAEAJARgAAAAAAACghAAMAAAAAAAAUEIABgAAAAAAACghAAMAAAAAAACUEIABAAAAAAAASgjAAAAAAAAAACUEYAAAAAAAAIASAjAAAAAAAABACQEYAAAAAAAAoIQADAAAAAAAAFBCAAYAAAAAAAAoIQADAAAAAAAAlBCAAQAAAAAAAEoIwAAAAAAAAAAlBGAAAAAAAACAEgIwAAAAAAAAQAkBGAAAAAAAAKCEAAwAAAAAAABQQgAGAAAAAAAAKCEAAwAAAAAAAJQQgAEAAAAAAABKCMAAAAAAAAAAJQRgAAAAAAAAgBICMAAAAAAAAEAJARgAAAAAAACghAAMAAAAAAAAUEIABgAAAAAAACghAAMAAAAAAACUEIABAAAAAAAASgjAAAAAAAAAACUEYAAAAAAAAIASAjAAAAAAAABACQEYAAAAAAAAoIQADAAAAAAAAFBCAAYAAAAAAAAoIQADAAAAAAAAlBCAAQAAAAAAAEoIwAAAAAAAAAAlBGAAAAAAAACAEgIwAAAAAAAAQAkBGAAAAAAAAKCEAAwAAAAAAABQQgAGAAAAAAAAKCEAAwAAAAAAAJQQgAEAAAAAAABKCMAAAAAAAAAAJQRgAAAAAAAAgBICMAAAAAAAAEAJARgAAAAAAACghAAMAAAAAAAAUEIABgAAAAAAACghAAMAAAAAAACUEIABAAAAAAAASgjAAAAAAAAAACUEYAAAAAAAAIASAjAAAAAAAABACQEYAAAAAAAAoIQADAAAAAAAAFBCAAYAAAAAAAAoMY3JP//9K8My551lzpAk293a7QAAAAAAAAD8iIw3r+SL7TpPxuSt4/ibJJuz20QDBgAAAAAAAHhzrJPp6NvHYcyyjLl7dJTPbl/Jp6sPLufSsM+5ec7q5YOrF0OeP/SVaAAAAAAAAIA3weH7u6zfm79dWDIMSw6225w785vsx3XyzasOby5ssz69c4sAAAAAAAAAr9n69C6bC9sT93a7rKdnORin5Otxynzi1JQcfiwCAwAAAAAAALxO69O7HH68TaaT98cp85R8vbp3Nfszv8q0LHn7xMF1sjk/ZzUPmZ/MmWefhAYAAAAAAAD4oayPdjn7223Gn7x6ZrXPnetX8mBKkpv3cufDd/Pufn5FL56SzcVtNheT3dNt8tQlAwAAAAAAAHyv1sm0ySv/9XtsNWZ3I/lHkgzHi7/4XY7WYz5yiwAAAAAAAAA/Ivtcv/3nPEyS1fHa42t5+vNLyX7JoRsCAAAAAAAAePPt1/nbV3/KvePn1Xc371/NYxEYAAAAAAAA4M0yTHk2rvNo2WdzvHZqzN9v/SF3vju3evng/at5fPDLPDu1yuGyZHSVAAAAAAAAAK/XOGe4ueSvZ4e8M8xZbVe5ceuPufvy3Oqkw4+v5emDX+fuuTlLhhwsEYIBAAAAAAAAXpclGR8OuXP0TR4cPM/9z/+SRyfNDf/1TZezOp/87KdjzizJZkhO7edMy/w/nAUAAAAAAADg/zaMWcZkP8/ZLsmLacr2/MV8+cnvs/tP5/4FmLjAq1ifcioAAAAASUVORK5CYII=";function H0($,q,Q){if(typeof $==="string"&&!isNaN(Number($)))$=Number($);if(typeof $==="number"&&$<100)return v0($);if(typeof $==="number"&&$>=100)return $;if(typeof $==="string"&&$.includes("%")){if(q&&q==="X")return Math.round(parseFloat($)/100*Q.width);if(q&&q==="Y")return Math.round(parseFloat($)/100*Q.height);return Math.round(parseFloat($)/100*Q.width)}return 0}function Y5($){return $.replace(/[xy]/g,function(q){let Q=Math.random()*16|0;return(q==="x"?Q:Q&3|8).toString(16)})}function k0($){if(typeof $>"u"||$==null)return"";return $.toString().replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function v0($){if(typeof $==="number"&&$>100)return $;if(typeof $==="string")$=Number($.replace(/in*/gi,""));return Math.round(L0*$)}function Y0($){let q=Number($)||0;return isNaN(q)?0:Math.round(q*w8)}function S1($){return $=$||0,Math.round(($>360?$-360:$)*60000)}function j7($){let q=$.toString(16);return q.length===1?"0"+q:q}function g7($,q,Q){return(j7($)+j7(q)+j7(Q)).toUpperCase()}function R0($,q){let Q=($||"").replace("#","");if(!C7.test(Q)&&Q!==G2.background1&&Q!==G2.background2&&Q!==G2.text1&&Q!==G2.text2&&Q!==G2.accent1&&Q!==G2.accent2&&Q!==G2.accent3&&Q!==G2.accent4&&Q!==G2.accent5&&Q!==G2.accent6)console.warn(`"${Q}" is not a valid scheme color or hex RGB! "${Q2}" used instead. Only provide 6-digit RGB or 'pptx.SchemeColor' values!`),Q=Q2;let K=C7.test(Q)?"srgbClr":"schemeClr",J='val="'+(C7.test(Q)?Q.toUpperCase():Q)+'"';return q?`${q}`:``}function fB($,q){let Q="",K=Object.assign(Object.assign({},q),$),J=Math.round(K.size*w8),Z=K.color,G=Math.round(K.opacity*1e5);return Q+=``,Q+=R0(Z,``),Q+="",Q}function B2($){let q="solid",Q="",K="",J="";if($){if(typeof $==="string")Q=$;else{if($.type)q=$.type;if($.color)Q=$.color;if($.alpha)K+=``;if($.transparency)K+=``}switch(q){case"solid":J+=`${R0(Q,K)}`;break;default:J+="";break}}return J}function a2($){return $._rels.length+$._relsChart.length+$._relsMedia.length+1}function c7($){if(!$||typeof $!=="object")return;if($.type!=="outer"&&$.type!=="inner"&&$.type!=="none")console.warn("Warning: shadow.type options are `outer`, `inner` or `none`."),$.type="outer";if($.angle){if(isNaN(Number($.angle))||$.angle<0||$.angle>359)console.warn("Warning: shadow.angle can only be 0-359"),$.angle=270;$.angle=Math.round(Number($.angle))}if($.opacity){if(isNaN(Number($.opacity))||$.opacity<0||$.opacity>1)console.warn("Warning: shadow.opacity can only be 0-1"),$.opacity=0.75;$.opacity=Number($.opacity)}if($.color){if($.color.startsWith("#"))console.warn('Warning: shadow.color should not include hash (#) character, , e.g. "FF0000"'),$.color=$.color.replace("#","")}return $}function RB($,q,Q){var K,J;let Z=2.3+(((K=$.options)===null||K===void 0?void 0:K.autoPageCharWeight)?$.options.autoPageCharWeight:0),G=Math.floor(q/w8*L0)/((((J=$.options)===null||J===void 0?void 0:J.fontSize)?$.options.fontSize:k2)/Z),W=[],B=[],V=[],U=[];if($.text&&$.text.toString().trim().length===0)B.push({_type:D0.tablecell,text:" "});else if(typeof $.text==="number"||typeof $.text==="string")B.push({_type:D0.tablecell,text:($.text||"").toString().trim()});else if(Array.isArray($.text))B=$.text;let w=[];return B.forEach((F)=>{var M;if(typeof F.text==="string"){if(F.text.split(` -`).length>1)F.text.split(` -`).forEach((k)=>{w.push({_type:D0.tablecell,text:k,options:Object.assign(Object.assign({},F.options),{breakLine:!0})})});else w.push({_type:D0.tablecell,text:F.text.trim(),options:F.options});if((M=F.options)===null||M===void 0?void 0:M.breakLine)V.push(w),w=[]}if(w.length>0)V.push(w),w=[]}),V.forEach((F)=>{F.forEach((M)=>{let k=[],L=String(M.text).split(" ");L.forEach((D,z)=>{let N=Object.assign({},M.options);if(N===null||N===void 0?void 0:N.breakLine)N.breakLine=z+1===L.length;k.push({_type:D0.tablecell,text:D+(z+1{let M=[],k="";if(F.forEach((f)=>{if(k.length+f.text.length>G)W.push(M),M=[],k="";M.push(f),k+=f.text.toString()}),M.length>0)W.push(M)}),W}function GJ($=[],q={},Q,K){let J=M8,Z=L0*1,G=L0*1,W=0,B=0,V=[],U=H0(q.x,"X",Q),w=H0(q.y,"Y",Q),F=H0(q.w,"X",Q),M=H0(q.h,"Y",Q),k=F;function f(){let D=0;if(V.length===0)D=w||v0(J[0]);if(V.length>0)D=v0(q.autoPageSlideStartY||q.newSlideStartY||J[0]);if(G=(M||Q.height)-D-v0(J[2]),V.length>1){if(typeof q.autoPageSlideStartY==="number")G=(M||Q.height)-v0(q.autoPageSlideStartY+J[2]);else if(typeof q.newSlideStartY==="number")G=(M||Q.height)-v0(q.newSlideStartY+J[2]);else if(w){if(G=(M||Q.height)-v0((w/L0{if(!z)z={_type:D0.tablecell};let N=z.options||null;B+=Number((N===null||N===void 0?void 0:N.colspan)?N.colspan:1)}),q.verbose)console.log(`| numCols ......................................... = ${B}`);if(!F&&q.colW){if(k=Array.isArray(q.colW)?q.colW.reduce((D,z)=>D+z)*L0:q.colW*B||0,q.verbose)console.log(`| tableCalcW ...................................... = ${k/L0}`)}if(Z=k||v0((U?U/L0:J[1])+J[3]),q.verbose)console.log(`| emuSlideTabW .................................... = ${(Z/L0).toFixed(1)}`);if(!q.colW||!Array.isArray(q.colW))if(q.colW&&!isNaN(Number(q.colW))){let D=[];($[0]||[]).forEach(()=>D.push(q.colW)),q.colW=[],D.forEach((N)=>{if(Array.isArray(q.colW))q.colW.push(N)})}else{q.colW=[];for(let D=0;D{let N=[],H=0,v=0,j=[];if(D.forEach((X)=>{var P,g,c,h;if(j.push({_type:D0.tablecell,text:[],options:X.options}),X.options.margin&&X.options.margin[0]>=1){if(((P=X.options)===null||P===void 0?void 0:P.margin)&&X.options.margin[0]&&Y0(X.options.margin[0])>H)H=Y0(X.options.margin[0]);else if((q===null||q===void 0?void 0:q.margin)&&q.margin[0]&&Y0(q.margin[0])>H)H=Y0(q.margin[0]);if(((g=X.options)===null||g===void 0?void 0:g.margin)&&X.options.margin[2]&&Y0(X.options.margin[2])>v)v=Y0(X.options.margin[2]);else if((q===null||q===void 0?void 0:q.margin)&&q.margin[2]&&Y0(q.margin[2])>v)v=Y0(q.margin[2])}else{if(((c=X.options)===null||c===void 0?void 0:c.margin)&&X.options.margin[0]&&v0(X.options.margin[0])>H)H=v0(X.options.margin[0]);else if((q===null||q===void 0?void 0:q.margin)&&q.margin[0]&&v0(q.margin[0])>H)H=v0(q.margin[0]);if(((h=X.options)===null||h===void 0?void 0:h.margin)&&X.options.margin[2]&&v0(X.options.margin[2])>v)v=v0(X.options.margin[2]);else if((q===null||q===void 0?void 0:q.margin)&&q.margin[2]&&v0(q.margin[2])>v)v=v0(q.margin[2])}}),f(),W+=H+v,q.verbose&&z===0)console.log(`| SLIDE [${V.length}]: emuSlideTabH ...... = ${(G/L0).toFixed(1)} `);if(D.forEach((X,P)=>{var g;let c={_type:D0.tablecell,_lines:null,_lineHeight:v0((((g=X.options)===null||g===void 0?void 0:g.fontSize)?X.options.fontSize:q.fontSize?q.fontSize:k2)*(YB+(q.autoPageLineWeight?q.autoPageLineWeight:0))/100),text:[],options:X.options};if(c.options.rowspan)c._lineHeight=0;c.options.autoPageCharWeight=q.autoPageCharWeight?q.autoPageCharWeight:null;let h=q.colW[P];if(X.options.colspan&&Array.isArray(q.colW))h=q.colW.filter((x,l)=>l>=P&&lx+l);c._lines=RB(X,h),N.push(c)}),q.verbose)console.log(` -| SLIDE [${V.length}]: ROW [${z}]: START...`);let n=0,d=0,_=!1;while(!_){let X=N[n],P=j[n];if(N.forEach((h)=>{if(h._lineHeight>=d)d=h._lineHeight}),W+d>G){if(q.verbose)console.log(` -|-----------------------------------------------------------------------|`),console.log(`|-- NEW SLIDE CREATED (currTabH+currLineH > maxH) => ${(W/L0).toFixed(2)} + ${(X._lineHeight/L0).toFixed(2)} > ${G/L0}`),console.log(`|-----------------------------------------------------------------------| - -`);if(j.length>0&&j.map((x)=>x.text.length).reduce((x,l)=>x+l)>0)L.rows.push(j);if(V.push(L),L={rows:[]},j=[],D.forEach((x)=>j.push({_type:D0.tablecell,text:[],options:x.options})),f(),W+=H+v,q.verbose)console.log(`| SLIDE [${V.length}]: emuSlideTabH ...... = ${(G/L0).toFixed(1)} `);if(W=0,(q.addHeaderToEach||q.autoPageRepeatHeader)&&q._arrObjTabHeadRows)q._arrObjTabHeadRows.forEach((x)=>{let l=[],$0=0;x.forEach((Z0)=>{if(l.push(Z0),Z0._lineHeight>$0)$0=Z0._lineHeight}),L.rows.push(l),W+=$0});P=j[n]}let g=X._lines.shift();if(Array.isArray(P.text)){if(g)P.text=P.text.concat(g);else if(P.text.length===0)P.text=P.text.concat({_type:D0.tablecell,text:""})}if(n===N.length-1)W+=d;if(n=nh._lines.length).reduce((h,x)=>h+x)===0)_=!0}if(j.length>0)L.rows.push(j);if(q.verbose)console.log(`- SLIDE [${V.length}]: ROW [${z}]: ...COMPLETE ...... emuTabCurrH = ${(W/L0).toFixed(2)} ( emuSlideTabH = ${(G/L0).toFixed(2)} )`)}),V.push(L),q.verbose)console.log(` -|================================================|`),console.log(`| FINAL: tableRowSlides.length = ${V.length}`),V.forEach((D)=>console.log(D)),console.log(`|================================================| - -`);return V}function IB($,q,Q={},K){let J=Q||{};J.slideMargin=J.slideMargin||J.slideMargin===0?J.slideMargin:0.5;let Z=J.w||$.presLayout.width,G=[],W=[],B=[],V=[],U=[],w=[0.5,0.5,0.5,0.5],F=0;if(!document.getElementById(q))throw Error('tableToSlides: Table ID "'+q+'" does not exist!');if(K===null||K===void 0?void 0:K._margin){if(Array.isArray(K._margin))w=K._margin;else if(!isNaN(K._margin))w=[K._margin,K._margin,K._margin,K._margin];J.slideMargin=w}else if(J===null||J===void 0?void 0:J.slideMargin){if(Array.isArray(J.slideMargin))w=J.slideMargin;else if(!isNaN(J.slideMargin))w=[J.slideMargin,J.slideMargin,J.slideMargin,J.slideMargin]}if(Z=(J.w?v0(J.w):$.presLayout.width)-v0(w[1]+w[3]),J.verbose)console.log("[[VERBOSE MODE]]"),console.log("|-- `tableToSlides` ----------------------------------------------------|"),console.log(`| tableProps.h .................................... = ${J.h}`),console.log(`| tableProps.w .................................... = ${J.w}`),console.log(`| pptx.presLayout.width ........................... = ${($.presLayout.width/L0).toFixed(1)}`),console.log(`| pptx.presLayout.height .......................... = ${($.presLayout.height/L0).toFixed(1)}`),console.log(`| emuSlideTabW .................................... = ${(Z/L0).toFixed(1)}`);let M=document.querySelectorAll(`#${q} tr:first-child th`);if(M.length===0)M=document.querySelectorAll(`#${q} tr:first-child td`);if(M.forEach((f)=>{let L=f;if(L.getAttribute("colspan"))for(let D=0;D{F+=f}),U.forEach((f,L)=>{let D=Number((Number(Z)*(f/F*100)/100/L0).toFixed(2)),z=0,N=document.querySelector(`#${q} thead tr:first-child th:nth-child(${L+1})`);if(N)z=Number(N.getAttribute("data-pptx-min-width"));let H=document.querySelector(`#${q} thead tr:first-child th:nth-child(${L+1})`);if(H)z=Number(H.getAttribute("data-pptx-width"));V.push(z>D?z:D)}),J.verbose)console.log(`| arrColW ......................................... = [${V.join(", ")}]`);["thead","tbody","tfoot"].forEach((f)=>{document.querySelectorAll(`#${q} ${f} tr`).forEach((L)=>{let D=L,z=[];switch(Array.from(D.cells).forEach((N)=>{let H=window.getComputedStyle(N).getPropertyValue("color").replace(/\s+/gi,"").replace("rgba(","").replace("rgb(","").replace(")","").split(","),v=window.getComputedStyle(N).getPropertyValue("background-color").replace(/\s+/gi,"").replace("rgba(","").replace("rgb(","").replace(")","").split(",");if(window.getComputedStyle(N).getPropertyValue("background-color")==="rgba(0, 0, 0, 0)"||window.getComputedStyle(N).getPropertyValue("transparent"))v=["255","255","255"];let j={align:null,bold:window.getComputedStyle(N).getPropertyValue("font-weight")==="bold"||Number(window.getComputedStyle(N).getPropertyValue("font-weight"))>=500,border:null,color:g7(Number(H[0]),Number(H[1]),Number(H[2])),fill:{color:g7(Number(v[0]),Number(v[1]),Number(v[2]))},fontFace:(window.getComputedStyle(N).getPropertyValue("font-family")||"").split(",")[0].replace(/"/g,"").replace("inherit","").replace("initial","")||null,fontSize:Number(window.getComputedStyle(N).getPropertyValue("font-size").replace(/[a-z]/gi,"")),margin:null,colspan:Number(N.getAttribute("colspan"))||null,rowspan:Number(N.getAttribute("rowspan"))||null,valign:null};if(["left","center","right","start","end"].includes(window.getComputedStyle(N).getPropertyValue("text-align"))){let n=window.getComputedStyle(N).getPropertyValue("text-align").replace("start","left").replace("end","right");j.align=n==="center"?"center":n==="left"?"left":n==="right"?"right":null}if(["top","middle","bottom"].includes(window.getComputedStyle(N).getPropertyValue("vertical-align"))){let n=window.getComputedStyle(N).getPropertyValue("vertical-align");j.valign=n==="top"?"top":n==="middle"?"middle":n==="bottom"?"bottom":null}if(window.getComputedStyle(N).getPropertyValue("padding-left"))j.margin=[0,0,0,0],["padding-top","padding-right","padding-bottom","padding-left"].forEach((d,_)=>{j.margin[_]=Math.round(Number(window.getComputedStyle(N).getPropertyValue(d).replace(/\D/gi,"")))});if(window.getComputedStyle(N).getPropertyValue("border-top-width")||window.getComputedStyle(N).getPropertyValue("border-right-width")||window.getComputedStyle(N).getPropertyValue("border-bottom-width")||window.getComputedStyle(N).getPropertyValue("border-left-width"))j.border=[null,null,null,null],["top","right","bottom","left"].forEach((d,_)=>{let X=Math.round(Number(window.getComputedStyle(N).getPropertyValue("border-"+d+"-width").replace("px",""))),P=[];P=window.getComputedStyle(N).getPropertyValue("border-"+d+"-color").replace(/\s+/gi,"").replace("rgba(","").replace("rgb(","").replace(")","").split(",");let g=g7(Number(P[0]),Number(P[1]),Number(P[2]));j.border[_]={pt:X,color:g}});z.push({_type:D0.tablecell,text:N.innerText,options:j})}),f){case"thead":G.push(z);break;case"tbody":W.push(z);break;case"tfoot":B.push(z);break;default:console.log(`table parsing: unexpected table part: ${f}`);break}})}),J._arrObjTabHeadRows=G||null,J.colW=V,GJ([...G,...W,...B],J,$.presLayout,K).forEach((f,L)=>{let D=$.addSlide({masterName:J.masterSlideName||null});if(L===0)J.y=J.y||w[0];if(L>0)J.y=J.autoPageSlideStartY||J.newSlideStartY||w[0];if(J.verbose)console.log(`| opts.autoPageSlideStartY: ${J.autoPageSlideStartY} / arrInchMargins[0]: ${w[0]} => opts.y = ${J.y}`);if(D.addTable(f.rows,{x:J.x||w[3],y:J.y,w:Number(Z)/L0,colW:V,autoPage:!1}),J.addImage)if(J.addImage.options=J.addImage.options||{},!J.addImage.image||!J.addImage.image.path&&!J.addImage.image.data)console.warn("Warning: tableToSlides.addImage requires either `path` or `data`");else D.addImage({path:J.addImage.image.path,data:J.addImage.image.data,x:J.addImage.options.x,y:J.addImage.options.y,w:J.addImage.options.w,h:J.addImage.options.h});if(J.addShape)D.addShape(J.addShape.shapeName,J.addShape.options||{});if(J.addTable)D.addTable(J.addTable.rows,J.addTable.options||{});if(J.addText)D.addText(J.addText.text,J.addText.options||{})})}var CB=0;function jB($,q){if($.bkgd)q.bkgd=$.bkgd;if($.objects&&Array.isArray($.objects)&&$.objects.length>0)$.objects.forEach((Q,K)=>{let J=Object.keys(Q)[0],Z=q;if(W1[J]&&J==="chart")WJ(Z,Q[J].type,Q[J].data,Q[J].opts);else if(W1[J]&&J==="image")BJ(Z,Q[J]);else if(W1[J]&&J==="line")E7(Z,B1.LINE,Q[J]);else if(W1[J]&&J==="rect")E7(Z,B1.RECTANGLE,Q[J]);else if(W1[J]&&J==="text")L5(Z,[{text:Q[J].text}],Q[J].options,!1);else if(W1[J]&&J==="placeholder")Q[J].options.placeholder=Q[J].options.name,delete Q[J].options.name,Q[J].options._placeholderType=Q[J].options.type,delete Q[J].options.type,Q[J].options._placeholderIdx=100+K,L5(Z,[{text:Q[J].text}],Q[J].options,!0)});if($.slideNumber&&typeof $.slideNumber==="object")q._slideNumberProps=$.slideNumber}function WJ($,q,Q,K){var J;function Z(w){if(!w||w.style==="none")return;if(w.size!==void 0&&(isNaN(Number(w.size))||w.size<=0))console.warn("Warning: chart.gridLine.size must be greater than 0."),delete w.size;if(w.style&&!["solid","dash","dot"].includes(w.style))console.warn("Warning: chart.gridLine.style options: `solid`, `dash`, `dot`."),delete w.style;if(w.cap&&!["flat","square","round"].includes(w.cap))console.warn("Warning: chart.gridLine.cap options: `flat`, `square`, `round`."),delete w.cap}let G=++CB,W={_type:null,text:null,options:null,chartRid:null},B=null,V=[];if(Array.isArray(q))q.forEach((w)=>{V=V.concat(w.data)}),B=Q||K;else V=Q,B=K;V.forEach((w,F)=>{if(w._dataIndex=F,w.labels!==void 0&&!Array.isArray(w.labels[0]))w.labels=[w.labels]});let U=B&&typeof B==="object"?B:{};if(U._type=q,U.x=typeof U.x<"u"&&U.x!=null&&!isNaN(Number(U.x))?U.x:1,U.y=typeof U.y<"u"&&U.y!=null&&!isNaN(Number(U.y))?U.y:1,U.w=U.w||"50%",U.h=U.h||"50%",U.objectName=U.objectName?k0(U.objectName):`Chart ${$._slideObjects.filter((w)=>w._type===D0.chart).length}`,!["bar","col"].includes(U.barDir||""))U.barDir="col";if(U._type===q0.AREA){if(!["stacked","standard","percentStacked"].includes(U.barGrouping||""))U.barGrouping="standard"}if(U._type===q0.BAR){if(!["clustered","stacked","percentStacked"].includes(U.barGrouping||""))U.barGrouping="clustered"}if(U._type===q0.BAR3D){if(!["clustered","stacked","standard","percentStacked"].includes(U.barGrouping||""))U.barGrouping="standard"}if((J=U.barGrouping)===null||J===void 0?void 0:J.includes("tacked")){if(!U.barGapWidthPct)U.barGapWidthPct=50}if(U.dataLabelPosition){if(U._type===q0.AREA||U._type===q0.BAR3D||U._type===q0.DOUGHNUT||U._type===q0.RADAR)delete U.dataLabelPosition;if(U._type===q0.PIE){if(!["bestFit","ctr","inEnd","outEnd"].includes(U.dataLabelPosition))delete U.dataLabelPosition}if(U._type===q0.BUBBLE||U._type===q0.BUBBLE3D||U._type===q0.LINE||U._type===q0.SCATTER){if(!["b","ctr","l","r","t"].includes(U.dataLabelPosition))delete U.dataLabelPosition}if(U._type===q0.BAR){if(!["stacked","percentStacked"].includes(U.barGrouping||"")){if(!["ctr","inBase","inEnd"].includes(U.dataLabelPosition))delete U.dataLabelPosition}if(!["clustered"].includes(U.barGrouping||"")){if(!["ctr","inBase","inEnd","outEnd"].includes(U.dataLabelPosition))delete U.dataLabelPosition}}}if(U.dataLabelBkgrdColors=U.dataLabelBkgrdColors||!U.dataLabelBkgrdColors?U.dataLabelBkgrdColors:!1,!["b","l","r","t","tr"].includes(U.legendPos||""))U.legendPos="r";if(!["cone","coneToMax","box","cylinder","pyramid","pyramidToMax"].includes(U.bar3DShape||""))U.bar3DShape="box";if(!["circle","dash","diamond","dot","none","square","triangle"].includes(U.lineDataSymbol||""))U.lineDataSymbol="circle";if(!["gap","span"].includes(U.displayBlanksAs||""))U.displayBlanksAs="span";if(!["standard","marker","filled"].includes(U.radarStyle||""))U.radarStyle="standard";if(U.lineDataSymbolSize=U.lineDataSymbolSize&&!isNaN(U.lineDataSymbolSize)?U.lineDataSymbolSize:6,U.lineDataSymbolLineSize=U.lineDataSymbolLineSize&&!isNaN(U.lineDataSymbolLineSize)?Y0(U.lineDataSymbolLineSize):Y0(0.75),U.layout)["x","y","w","h"].forEach((w)=>{let F=U.layout[w];if(isNaN(Number(F))||F<0||F>1)console.warn("Warning: chart.layout."+w+" can only be 0-1"),delete U.layout[w]});if(U.catGridLine=U.catGridLine||(U._type===q0.SCATTER?{color:"D9D9D9",size:1}:{style:"none"}),U.valGridLine=U.valGridLine||(U._type===q0.SCATTER?{color:"D9D9D9",size:1}:{}),U.serGridLine=U.serGridLine||(U._type===q0.SCATTER?{color:"D9D9D9",size:1}:{style:"none"}),Z(U.catGridLine),Z(U.valGridLine),Z(U.serGridLine),c7(U.shadow),U.showDataTable=U.showDataTable||!U.showDataTable?U.showDataTable:!1,U.showDataTableHorzBorder=U.showDataTableHorzBorder||!U.showDataTableHorzBorder?U.showDataTableHorzBorder:!0,U.showDataTableVertBorder=U.showDataTableVertBorder||!U.showDataTableVertBorder?U.showDataTableVertBorder:!0,U.showDataTableOutline=U.showDataTableOutline||!U.showDataTableOutline?U.showDataTableOutline:!0,U.showDataTableKeys=U.showDataTableKeys||!U.showDataTableKeys?U.showDataTableKeys:!0,U.showLabel=U.showLabel||!U.showLabel?U.showLabel:!1,U.showLegend=U.showLegend||!U.showLegend?U.showLegend:!1,U.showPercent=U.showPercent||!U.showPercent?U.showPercent:!0,U.showTitle=U.showTitle||!U.showTitle?U.showTitle:!1,U.showValue=U.showValue||!U.showValue?U.showValue:!1,U.showLeaderLines=U.showLeaderLines||!U.showLeaderLines?U.showLeaderLines:!1,U.catAxisLineShow=typeof U.catAxisLineShow<"u"?U.catAxisLineShow:!0,U.valAxisLineShow=typeof U.valAxisLineShow<"u"?U.valAxisLineShow:!0,U.serAxisLineShow=typeof U.serAxisLineShow<"u"?U.serAxisLineShow:!0,U.v3DRotX=!isNaN(U.v3DRotX)&&U.v3DRotX>=-90&&U.v3DRotX<=90?U.v3DRotX:30,U.v3DRotY=!isNaN(U.v3DRotY)&&U.v3DRotY>=0&&U.v3DRotY<=360?U.v3DRotY:30,U.v3DRAngAx=U.v3DRAngAx||!U.v3DRAngAx?U.v3DRAngAx:!0,U.v3DPerspective=!isNaN(U.v3DPerspective)&&U.v3DPerspective>=0&&U.v3DPerspective<=240?U.v3DPerspective:30,U.barGapWidthPct=!isNaN(U.barGapWidthPct)&&U.barGapWidthPct>=0&&U.barGapWidthPct<=1000?U.barGapWidthPct:150,U.barGapDepthPct=!isNaN(U.barGapDepthPct)&&U.barGapDepthPct>=0&&U.barGapDepthPct<=1000?U.barGapDepthPct:150,U.chartColors=Array.isArray(U.chartColors)?U.chartColors:U._type===q0.PIE||U._type===q0.DOUGHNUT?HB:z8,U.chartColorsOpacity=U.chartColorsOpacity&&!isNaN(U.chartColorsOpacity)?U.chartColorsOpacity:null,U.border=U.border&&typeof U.border==="object"?U.border:null,U.border&&(!U.border.pt||isNaN(U.border.pt)))U.border.pt=v6.pt;if(U.border&&(!U.border.color||typeof U.border.color!=="string"))U.border.color=v6.color;if(U.plotArea=U.plotArea||{},U.plotArea.border=U.plotArea.border&&typeof U.plotArea.border==="object"?U.plotArea.border:null,U.plotArea.border&&(!U.plotArea.border.pt||isNaN(U.plotArea.border.pt)))U.plotArea.border.pt=v6.pt;if(U.plotArea.border&&(!U.plotArea.border.color||typeof U.plotArea.border.color!=="string"))U.plotArea.border.color=v6.color;if(U.border)U.plotArea.border=U.border;if(U.plotArea.fill=U.plotArea.fill||{color:null,transparency:null},U.fill)U.plotArea.fill.color=U.fill;if(U.chartArea=U.chartArea||{},U.chartArea.border=U.chartArea.border&&typeof U.chartArea.border==="object"?U.chartArea.border:null,U.chartArea.border)U.chartArea.border={color:U.chartArea.border.color||v6.color,pt:U.chartArea.border.pt||v6.pt};if(U.chartArea.roundedCorners=typeof U.chartArea.roundedCorners==="boolean"?U.chartArea.roundedCorners:!0,U.dataBorder=U.dataBorder&&typeof U.dataBorder==="object"?U.dataBorder:null,U.dataBorder&&(!U.dataBorder.pt||isNaN(U.dataBorder.pt)))U.dataBorder.pt=0.75;if(U.dataBorder&&U.dataBorder.color){let w=typeof U.dataBorder.color==="string"&&U.dataBorder.color.length===6&&/^[0-9A-Fa-f]{6}$/.test(U.dataBorder.color),F=Object.values(D5).includes(U.dataBorder.color);if(!w&&!F)U.dataBorder.color="F9F9F9"}if(!U.dataLabelFormatCode&&U._type===q0.SCATTER)U.dataLabelFormatCode="General";if(!U.dataLabelFormatCode&&(U._type===q0.PIE||U._type===q0.DOUGHNUT))U.dataLabelFormatCode=U.showPercent?"0%":"General";if(U.dataLabelFormatCode=U.dataLabelFormatCode&&typeof U.dataLabelFormatCode==="string"?U.dataLabelFormatCode:"#,##0",!U.dataLabelFormatScatter&&U._type===q0.SCATTER)U.dataLabelFormatScatter="custom";if(U.lineSize=typeof U.lineSize==="number"?U.lineSize:2,U.valAxisMajorUnit=typeof U.valAxisMajorUnit==="number"?U.valAxisMajorUnit:null,U._type===q0.AREA||U._type===q0.BAR||U._type===q0.BAR3D||U._type===q0.LINE)U.catAxisMultiLevelLabels=!!U.catAxisMultiLevelLabels;else delete U.catAxisMultiLevelLabels;return W._type="chart",W.options=U,W.chartRid=a2($),$._relsChart.push({rId:a2($),data:V,opts:U,type:U._type,globalId:G,fileName:`chart${G}.xml`,Target:`/ppt/charts/chart${G}.xml`}),$._slideObjects.push(W),W}function BJ($,q){let Q={_type:null,text:null,options:null,image:null,imageRid:null,hyperlink:null},K=q.x||0,J=q.y||0,Z=q.w||0,G=q.h||0,W=q.sizing||null,B=q.hyperlink||"",V=q.data||"",U=q.path||"",w=a2($),F=q.objectName?k0(q.objectName):`Image ${$._slideObjects.filter((k)=>k._type===D0.image).length}`;if(!U&&!V)return console.error("ERROR: addImage() requires either 'data' or 'path' parameter!"),null;else if(U&&typeof U!=="string")return console.error(`ERROR: addImage() 'path' should be a string, ex: {path:'/img/sample.png'} - you sent ${String(U)}`),null;else if(V&&typeof V!=="string")return console.error(`ERROR: addImage() 'data' should be a string, ex: {data:'image/png;base64,NMP[...]'} - you sent ${String(V)}`),null;else if(V&&typeof V==="string"&&!V.toLowerCase().includes("base64,"))return console.error("ERROR: Image `data` value lacks a base64 header! Ex: 'image/png;base64,NMP[...]')"),null;let M=(U.substring(U.lastIndexOf("/")+1).split("?")[0].split(".").pop().split("#")[0]||"png").toLowerCase();if(V&&/image\/(\w+);/.exec(V)&&/image\/(\w+);/.exec(V).length>0)M=/image\/(\w+);/.exec(V)[1];else if(V===null||V===void 0?void 0:V.toLowerCase().includes("image/svg+xml"))M="svg";if(Q._type=D0.image,Q.image=U||"preencoded.png",Q.options={x:K||0,y:J||0,w:Z||1,h:G||1,altText:q.altText||"",rounding:typeof q.rounding==="boolean"?q.rounding:!1,sizing:W,placeholder:q.placeholder,rotate:q.rotate||0,flipV:q.flipV||!1,flipH:q.flipH||!1,transparency:q.transparency||0,objectName:F,shadow:c7(q.shadow)},M==="svg")$._relsMedia.push({path:U||V+"png",type:"image/png",extn:"png",data:V||"",rId:w,Target:`../media/image-${$._slideNum}-${$._relsMedia.length+1}.png`,isSvgPng:!0,svgSize:{w:H0(Q.options.w,"X",$._presLayout),h:H0(Q.options.h,"Y",$._presLayout)}}),Q.imageRid=w,$._relsMedia.push({path:U||V,type:"image/svg+xml",extn:M,data:V||"",rId:w+1,Target:`../media/image-${$._slideNum}-${$._relsMedia.length+1}.${M}`}),Q.imageRid=w+1;else{let k=$._relsMedia.filter((f)=>f.path&&f.path===U&&f.type==="image/"+M&&!f.isDuplicate)[0];$._relsMedia.push({path:U||"preencoded."+M,type:"image/"+M,extn:M,data:V||"",rId:w,isDuplicate:!!(k===null||k===void 0?void 0:k.Target),Target:(k===null||k===void 0?void 0:k.Target)?k.Target:`../media/image-${$._slideNum}-${$._relsMedia.length+1}.${M}`}),Q.imageRid=w}if(typeof B==="object")if(!B.url&&!B.slide)throw Error("ERROR: `hyperlink` option requires either: `url` or `slide`");else w++,$._rels.push({type:D0.hyperlink,data:B.slide?"slide":"dummy",rId:w,Target:B.url||B.slide.toString()}),B._rId=w,Q.hyperlink=B;$._slideObjects.push(Q)}function gB($,q){let Q=q.x||0,K=q.y||0,J=q.w||2,Z=q.h||2,G=q.data||"",W=q.link||"",B=q.path||"",V=q.type||"audio",U="",w=q.cover||vB,F=q.objectName?k0(q.objectName):`Media ${$._slideObjects.filter((k)=>k._type===D0.media).length}`,M={_type:D0.media};if(!B&&!G&&V!=="online")throw Error("addMedia() error: either `data` or `path` are required!");else if(G&&!G.toLowerCase().includes("base64,"))throw Error("addMedia() error: `data` value lacks a base64 header! Ex: 'video/mpeg;base64,NMP[...]')");else if(!w.toLowerCase().includes("base64,"))throw Error("addMedia() error: `cover` value lacks a base64 header! Ex: 'data:image/png;base64,iV[...]')");if(V==="online"&&!W)throw Error("addMedia() error: online videos require `link` value");if(U=q.extn||(G?G.split(";")[0].split("/")[1]:B.split(".").pop())||"mp3",M.mtype=V,M.media=B||"preencoded.mov",M.options={},M.options.x=Q,M.options.y=K,M.options.w=J,M.options.h=Z,M.options.objectName=F,V==="online"){let k=a2($);$._relsMedia.push({path:B||"preencoded"+U,data:"dummy",type:"online",extn:U,rId:k,Target:W}),M.mediaRid=k,$._relsMedia.push({path:"preencoded.png",data:w,type:"image/png",extn:"png",rId:a2($),Target:`../media/image-${$._slideNum}-${$._relsMedia.length+1}.png`})}else{let k=$._relsMedia.filter((L)=>L.path&&L.path===B&&L.type===V+"/"+U&&!L.isDuplicate)[0],f=a2($);$._relsMedia.push({path:B||"preencoded"+U,type:V+"/"+U,extn:U,data:G||"",rId:f,isDuplicate:!!(k===null||k===void 0?void 0:k.Target),Target:(k===null||k===void 0?void 0:k.Target)?k.Target:`../media/media-${$._slideNum}-${$._relsMedia.length+1}.${U}`}),M.mediaRid=f,$._relsMedia.push({path:B||"preencoded"+U,type:V+"/"+U,extn:U,data:G||"",rId:a2($),isDuplicate:!!(k===null||k===void 0?void 0:k.Target),Target:(k===null||k===void 0?void 0:k.Target)?k.Target:`../media/media-${$._slideNum}-${$._relsMedia.length+0}.${U}`}),$._relsMedia.push({path:"preencoded.png",type:"image/png",extn:"png",data:w,rId:a2($),Target:`../media/image-${$._slideNum}-${$._relsMedia.length+1}.png`})}$._slideObjects.push(M)}function AB($,q){$._slideObjects.push({_type:D0.notes,text:[{text:q}]})}function E7($,q,Q){let K=typeof Q==="object"?Q:{};K.line=K.line||{type:"none"};let J={_type:D0.text,shape:q||B1.RECTANGLE,options:K,text:null};if(!q)throw Error("Missing/Invalid shape parameter! Example: `addShape(pptxgen.shapes.LINE, {x:1, y:1, w:1, h:1});`");let Z={type:K.line.type||"solid",color:K.line.color||VJ,transparency:K.line.transparency||0,width:K.line.width||1,dashType:K.line.dashType||"solid",beginArrowType:K.line.beginArrowType||null,endArrowType:K.line.endArrowType||null};if(typeof K.line==="object"&&K.line.type!=="none")K.line=Z;if(K.x=K.x||(K.x===0?0:1),K.y=K.y||(K.y===0?0:1),K.w=K.w||(K.w===0?0:1),K.h=K.h||(K.h===0?0:1),K.objectName=K.objectName?k0(K.objectName):`Shape ${$._slideObjects.filter((G)=>G._type===D0.text).length}`,typeof K.line==="string"){let G=Z;G.color=String(K.line),K.line=G}if(typeof K.lineSize==="number")K.line.width=K.lineSize;if(typeof K.lineDash==="string")K.line.dashType=K.lineDash;if(typeof K.lineHead==="string")K.line.beginArrowType=K.lineHead;if(typeof K.lineTail==="string")K.line.endArrowType=K.lineTail;g6($,J),$._slideObjects.push(J)}function XB($,q,Q,K,J,Z,G){let W=[$],B=Q&&typeof Q==="object"?Q:{};B.objectName=B.objectName?k0(B.objectName):`Table ${$._slideObjects.filter((F)=>F._type===D0.table).length}`;{if(q===null||q.length===0||!Array.isArray(q))throw Error("addTable: Array expected! EX: 'slide.addTable( [rows], {options} );' (https://gitbrent.github.io/PptxGenJS/docs/api-tables.html)");if(!q[0]||!Array.isArray(q[0]))throw Error("addTable: 'rows' should be an array of cells! EX: 'slide.addTable( [ ['A'], ['B'], {text:'C',options:{align:'center'}} ] );' (https://gitbrent.github.io/PptxGenJS/docs/api-tables.html)")}let V=[];if(q.forEach((F)=>{let M=[];if(Array.isArray(F))F.forEach((k)=>{let f={_type:D0.tablecell,text:"",options:typeof k==="object"&&k.options?k.options:{}};if(typeof k==="string"||typeof k==="number")f.text=k.toString();else if(k.text){if(typeof k.text==="string"||typeof k.text==="number")f.text=k.text.toString();else if(k.text)f.text=k.text;if(k.options&&typeof k.options==="object")f.options=k.options}f.options.border=f.options.border||B.border||[{type:"none"},{type:"none"},{type:"none"},{type:"none"}];let L=f.options.border;if(!Array.isArray(L)&&typeof L==="object")f.options.border=[L,L,L,L];if(!f.options.border[0])f.options.border[0]={type:"none"};if(!f.options.border[1])f.options.border[1]={type:"none"};if(!f.options.border[2])f.options.border[2]={type:"none"};if(!f.options.border[3])f.options.border[3]={type:"none"};[0,1,2,3].forEach((z)=>{f.options.border[z]={type:f.options.border[z].type||H6.type,color:f.options.border[z].color||H6.color,pt:typeof f.options.border[z].pt==="number"?f.options.border[z].pt:H6.pt}}),M.push(f)});else console.log("addTable: tableRows has a bad row. A row should be an array of cells. You provided:"),console.log(F);V.push(M)}),B.x=H0(B.x||(B.x===0?0:L0/2),"X",J),B.y=H0(B.y||(B.y===0?0:L0/2),"Y",J),B.h)B.h=H0(B.h,"Y",J);if(B.fontSize=B.fontSize||k2,B.margin=B.margin===0||B.margin?B.margin:JJ,typeof B.margin==="number")B.margin=[Number(B.margin),Number(B.margin),Number(B.margin),Number(B.margin)];if(JSON.stringify({arrRows:V}).indexOf("hyperlink")===-1){if(!B.color)B.color=B.color||Q2}if(typeof B.border==="string")console.warn("addTable `border` option must be an object. Ex: `{border: {type:'none'}}`"),B.border=null;else if(Array.isArray(B.border))[0,1,2,3].forEach((F)=>{B.border[F]=B.border[F]?{type:B.border[F].type||H6.type,color:B.border[F].color||H6.color,pt:B.border[F].pt||H6.pt}:{type:"none"}});if(B.autoPage=typeof B.autoPage==="boolean"?B.autoPage:!1,B.autoPageRepeatHeader=typeof B.autoPageRepeatHeader==="boolean"?B.autoPageRepeatHeader:!1,B.autoPageHeaderRows=typeof B.autoPageHeaderRows<"u"&&!isNaN(Number(B.autoPageHeaderRows))?Number(B.autoPageHeaderRows):1,B.autoPageLineWeight=typeof B.autoPageLineWeight<"u"&&!isNaN(Number(B.autoPageLineWeight))?Number(B.autoPageLineWeight):0,B.autoPageLineWeight){if(B.autoPageLineWeight>1)B.autoPageLineWeight=1;else if(B.autoPageLineWeight<-1)B.autoPageLineWeight=-1}let U=M8;if(K&&typeof K._margin<"u"){if(Array.isArray(K._margin))U=K._margin;else if(!isNaN(Number(K._margin)))U=[Number(K._margin),Number(K._margin),Number(K._margin),Number(K._margin)]}if(B.colW){let F=V[0].reduce((M,k)=>{var f;if(((f=k===null||k===void 0?void 0:k.options)===null||f===void 0?void 0:f.colspan)&&typeof k.options.colspan==="number")M+=k.options.colspan;else M+=1;return M},0);if(typeof B.colW==="string"||typeof B.colW==="number")B.w=Math.floor(Number(B.colW)*F),B.colW=null;else if(B.colW&&Array.isArray(B.colW)&&B.colW.length===1&&F>1)B.w=Math.floor(Number(B.colW)*F),B.colW=null;else if(B.colW&&Array.isArray(B.colW)&&B.colW.length!==F)console.warn("addTable: mismatch: (colW.length != data.length) Therefore, defaulting to evenly distributed col widths."),B.colW=null}else if(B.w)B.w=H0(B.w,"X",J);else B.w=Math.floor(J._sizeW/L0-U[1]-U[3]);if(B.x&&B.x<20)B.x=v0(B.x);if(B.y&&B.y<20)B.y=v0(B.y);if(B.w&&typeof B.w==="number"&&B.w<20)B.w=v0(B.w);if(B.h&&typeof B.h==="number"&&B.h<20)B.h=v0(B.h);V.forEach((F)=>{F.forEach((M,k)=>{if(typeof M==="number"||typeof M==="string")F[k]={_type:D0.tablecell,text:String(F[k]),options:B};else if(typeof M==="object"){if(typeof M.text==="number")F[k].text=F[k].text.toString();else if(typeof M.text>"u"||M.text===null)F[k].text="";F[k].options=M.options||{},F[k]._type=D0.tablecell}})});let w=[];if(B&&!B.autoPage)g6($,V),$._slideObjects.push({_type:D0.table,arrTabRows:V,options:Object.assign({},B)});else{if(B.autoPageRepeatHeader)B._arrObjTabHeadRows=V.filter((F,M)=>M{if(!G($._slideNum+M))W.push(Z({masterName:(K===null||K===void 0?void 0:K._name)||null}));if(M>0)B.y=v0(B.autoPageSlideStartY||B.newSlideStartY||U[0]);{let k=G($._slideNum+M);if(B.autoPage=!1,g6(k,F.rows),k.addTable(F.rows,Object.assign({},B)),M>0)w.push(k)}})}return w}function L5($,q,Q,K){let J={_type:K?D0.placeholder:D0.text,shape:(Q===null||Q===void 0?void 0:Q.shape)||B1.RECTANGLE,text:!q||q.length===0?[{text:"",options:null}]:q,options:Q||{}};function Z(G){{if(!G.placeholder)G.color=G.color||J.options.color||$.color||Q2;if(G.placeholder||K)G.bullet=G.bullet||!1;if(G.placeholder&&$._slideLayout&&$._slideLayout._slideObjects){let W=$._slideLayout._slideObjects.filter((B)=>B._type==="placeholder"&&B.options&&B.options.placeholder&&B.options.placeholder===G.placeholder)[0];if(W===null||W===void 0?void 0:W.options)G=Object.assign(Object.assign({},G),W.options)}if(G.objectName=G.objectName?k0(G.objectName):`Text ${$._slideObjects.filter((W)=>W._type===D0.text).length}`,G.shape===B1.LINE){let W={type:G.line.type||"solid",color:G.line.color||VJ,transparency:G.line.transparency||0,width:G.line.width||1,dashType:G.line.dashType||"solid",beginArrowType:G.line.beginArrowType||null,endArrowType:G.line.endArrowType||null};if(typeof G.line==="object")G.line=W;if(typeof G.line==="string"){let B=W;if(typeof G.line==="string")B.color=G.line;G.line=B}if(typeof G.lineSize==="number")G.line.width=G.lineSize;if(typeof G.lineDash==="string")G.line.dashType=G.lineDash;if(typeof G.lineHead==="string")G.line.beginArrowType=G.lineHead;if(typeof G.lineTail==="string")G.line.endArrowType=G.lineTail}if(G.line=G.line||{},G.lineSpacing=G.lineSpacing&&!isNaN(G.lineSpacing)?G.lineSpacing:null,G.lineSpacingMultiple=G.lineSpacingMultiple&&!isNaN(G.lineSpacingMultiple)?G.lineSpacingMultiple:null,G._bodyProp=G._bodyProp||{},G._bodyProp.autoFit=G.autoFit||!1,G._bodyProp.anchor=!G.placeholder?I6.ctr:null,G._bodyProp.vert=G.vert||null,G._bodyProp.wrap=typeof G.wrap==="boolean"?G.wrap:!0,G.inset&&!isNaN(Number(G.inset))||G.inset===0)G._bodyProp.lIns=v0(G.inset),G._bodyProp.rIns=v0(G.inset),G._bodyProp.tIns=v0(G.inset),G._bodyProp.bIns=v0(G.inset);if(typeof G.underline==="boolean"&&G.underline===!0)G.underline={style:"sng"}}{if((G.align||"").toLowerCase().indexOf("c")===0)G._bodyProp.align=R6.center;else if((G.align||"").toLowerCase().indexOf("l")===0)G._bodyProp.align=R6.left;else if((G.align||"").toLowerCase().indexOf("r")===0)G._bodyProp.align=R6.right;else if((G.align||"").toLowerCase().indexOf("j")===0)G._bodyProp.align=R6.justify;if((G.valign||"").toLowerCase().indexOf("b")===0)G._bodyProp.anchor=I6.b;else if((G.valign||"").toLowerCase().indexOf("m")===0)G._bodyProp.anchor=I6.ctr;else if((G.valign||"").toLowerCase().indexOf("t")===0)G._bodyProp.anchor=I6.t}return c7(G.shadow),G}J.options=Z(J.options),J.text.forEach((G)=>G.options=Z(G.options||{})),g6($,J.text||""),$._slideObjects.push(J)}function yB($){($._slideLayout._slideObjects||[]).forEach((q)=>{if(q._type===D0.placeholder){if($._slideObjects.filter((Q)=>Q.options&&Q.options.placeholder===q.options.placeholder).length===0)L5($,[{text:""}],q.options,!1)}})}function zJ($,q){var Q;if(q.bkgd){if(!q.background)q.background={};if(typeof q.bkgd==="string")q.background.color=q.bkgd;else{if(q.bkgd.data)q.background.data=q.bkgd.data;if(q.bkgd.path)q.background.path=q.bkgd.path;if(q.bkgd.src)q.background.path=q.bkgd.src}}if((Q=q.background)===null||Q===void 0?void 0:Q.fill)q.background.color=q.background.fill;if($&&($.path||$.data)){$.path=$.path||"preencoded.png";let K=($.path.split(".").pop()||"png").split("?")[0];if(K==="jpg")K="jpeg";q._relsMedia=q._relsMedia||[];let J=q._relsMedia.length+1;q._relsMedia.push({path:$.path,type:D0.image,extn:K,data:$.data||null,rId:J,Target:`../media/${(q._name||"").replace(/\s+/gi,"-")}-image-${q._relsMedia.length+1}.${K}`}),q._bkgdImgRid=J}}function g6($,q,Q){let K=[];if(typeof q==="string"||typeof q==="number")return;else if(Array.isArray(q))K=q;else if(typeof q==="object")K=[q];K.forEach((J,Z)=>{if(Q&&Q[Z]&&Q[Z].hyperlink)J.options=Object.assign(Object.assign({},J.options),Q[Z]);if(Array.isArray(J)){let G=[];J.forEach((W)=>{if(W.options&&!W.text.options)G.push(W.options)}),g6($,J,G)}else if(Array.isArray(J.text))g6($,J.text,Q&&Q[Z]?[Q[Z]]:void 0);else if(J&&typeof J==="object"&&J.options&&J.options.hyperlink&&!J.options.hyperlink._rId)if(typeof J.options.hyperlink!=="object")console.log("ERROR: text `hyperlink` option should be an object. Ex: `hyperlink: {url:'https://github.com'}` ");else if(!J.options.hyperlink.url&&!J.options.hyperlink.slide)console.log("ERROR: 'hyperlink requires either: `url` or `slide`'");else{let G=a2($);$._rels.push({type:D0.hyperlink,data:J.options.hyperlink.slide?"slide":"dummy",rId:G,Target:k0(J.options.hyperlink.url)||J.options.hyperlink.slide.toString()}),J.options.hyperlink._rId=G}else if(J&&typeof J==="object"&&J.options&&J.options.hyperlink&&J.options.hyperlink._rId){if($._rels.filter((G)=>G.rId===J.options.hyperlink._rId).length===0)$._rels.push({type:D0.hyperlink,data:J.options.hyperlink.slide?"slide":"dummy",rId:J.options.hyperlink._rId,Target:k0(J.options.hyperlink.url)||J.options.hyperlink.slide.toString()})}})}class FJ{constructor($){var q;this.addSlide=$.addSlide,this.getSlide=$.getSlide,this._name=`Slide ${$.slideNumber}`,this._presLayout=$.presLayout,this._rId=$.slideRId,this._rels=[],this._relsChart=[],this._relsMedia=[],this._setSlideNum=$.setSlideNum,this._slideId=$.slideId,this._slideLayout=$.slideLayout||null,this._slideNum=$.slideNumber,this._slideObjects=[],this._slideNumberProps=((q=this._slideLayout)===null||q===void 0?void 0:q._slideNumberProps)?this._slideLayout._slideNumberProps:null}set bkgd($){if(this._bkgd=$,!this._background||!this._background.color){if(!this._background)this._background={};if(typeof $==="string")this._background.color=$}}get bkgd(){return this._bkgd}set background($){if(this._background=$,$)zJ($,this)}get background(){return this._background}set color($){this._color=$}get color(){return this._color}set hidden($){this._hidden=$}get hidden(){return this._hidden}set slideNumber($){this._slideNumberProps=$,this._setSlideNum($)}get slideNumber(){return this._slideNumberProps}get newAutoPagedSlides(){return this._newAutoPagedSlides}addChart($,q,Q){let K=Q||{};return K._type=$,WJ(this,$,q,Q),this}addImage($){return BJ(this,$),this}addMedia($){return gB(this,$),this}addNotes($){return AB(this,$),this}addShape($,q){return E7(this,$,q),this}addTable($,q){return this._newAutoPagedSlides=XB(this,$,q,this._slideLayout,this._presLayout,this.addSlide,this.getSlide),this}addText($,q){return L5(this,typeof $==="string"||typeof $==="number"?[{text:$,options:q}]:$,q,!1),this}}function hB($,q){return W2(this,void 0,void 0,function*(){let Q=$.data;return yield new Promise((K,J)=>{var Z,G;let W=new _7.default,B=(Q.length-1)*2+1,V=((G=(Z=Q[0])===null||Z===void 0?void 0:Z.labels)===null||G===void 0?void 0:G.length)>1;W.folder("_rels"),W.folder("docProps"),W.folder("xl/_rels"),W.folder("xl/tables"),W.folder("xl/theme"),W.folder("xl/worksheets"),W.folder("xl/worksheets/_rels"),W.file("[Content_Types].xml",' \n'),W.file("_rels/.rels",` -`),W.file("docProps/app.xml",`Microsoft Macintosh Excel0falseWorksheets1Sheet1falsefalsefalse16.0300 -`),W.file("docProps/core.xml",'PptxGenJSPptxGenJS'+new Date().toISOString()+''+new Date().toISOString()+""),W.file("xl/_rels/workbook.xml.rels",''),W.file("xl/styles.xml",'\n'),W.file("xl/theme/theme1.xml",''),W.file("xl/workbook.xml",` -`),W.file("xl/worksheets/_rels/sheet1.xml.rels",` -`);{let U='';if($.opts._type===q0.BUBBLE||$.opts._type===q0.BUBBLE3D)U+=``;else if($.opts._type===q0.SCATTER)U+=``;else if(V){let w=Q.length;Q[0].labels.forEach((F)=>w+=F.filter((M)=>M&&M!=="").length),U+=``,U+=""}else{let w=Q.length+Q[0].labels.length*Q[0].labels[0].length+Q[0].labels.length,F=Q.length+Q[0].labels.length*Q[0].labels[0].length+1;U+=``,U+=''}if($.opts._type===q0.BUBBLE||$.opts._type===q0.BUBBLE3D)Q.forEach((w,F)=>{if(F===0)U+="X-Axis";else U+=`${k0(w.name||`Y-Axis${F}`)}`,U+=`${k0(`Size${F}`)}`});else Q.forEach((w)=>{U+=`${k0((w.name||" ").replace("X-Axis","X-Values"))}`});if($.opts._type!==q0.BUBBLE&&$.opts._type!==q0.BUBBLE3D&&$.opts._type!==q0.SCATTER)Q[0].labels.slice().reverse().forEach((w)=>{w.filter((F)=>F&&F!=="").forEach((F)=>{U+=`${k0(F)}`})});U+=` -`,W.file("xl/sharedStrings.xml",U)}{let U='';if($.opts._type===q0.BUBBLE||$.opts._type===q0.BUBBLE3D){U+=``,U+=``;let w=1;Q.forEach((F,M)=>{if(M===0)U+=``;else U+=``,w++,U+=``})}else if($.opts._type===q0.SCATTER)U+=`
`,U+=``,Q.forEach((w,F)=>{U+=``});else U+=`
`,U+=``,Q[0].labels.forEach((w,F)=>{U+=``}),Q.forEach((w,F)=>{U+=``});U+="",U+='',U+="
",W.file("xl/tables/table1.xml",U)}{let U='';if(U+='',$.opts._type===q0.BUBBLE||$.opts._type===q0.BUBBLE3D)U+=``;else if($.opts._type===q0.SCATTER)U+=``;else U+=``;if(U+='',U+='',$.opts._type===q0.BUBBLE||$.opts._type===q0.BUBBLE3D){U+="",U+=``,U+='0';for(let w=1;w${w}`;U+="",Q[0].values.forEach((w,F)=>{U+=``,U+=`${w}`;let M=2;for(let k=1;k${Q[k].values[F]||""}`,M++,U+=`${Q[k].sizes[F]||""}`,M++;U+=""})}else if($.opts._type===q0.SCATTER){U+="",U+=``;for(let w=0;w${w}`;U+="",Q[0].values.forEach((w,F)=>{U+=``,U+=`${w}`;for(let M=1;M${Q[M].values[F]||Q[M].values[F]===0?Q[M].values[F]:""}`;U+=""})}else if(U+="",!V){U+=``,Q[0].labels.forEach((w,F)=>{U+=`0`});for(let w=0;w${w+1}`;U+="",Q[0].labels[0].forEach((w,F)=>{U+=``;for(let M=Q[0].labels.length-1;M>=0;M--)U+=``,U+=`${Q.length+F+1}`,U+="";for(let M=0;M${Q[M].values[F]||""}`;U+=""})}else{U+=``;for(let k=0;k0`;for(let k=Q[0].labels.length-1;k${k}`;U+="";let w=Q.length,F=Q[0].labels[0].length,M=Q[0].labels.length;for(let k=0;k`;let f=w,L=Q[0].labels.slice().reverse();L.forEach((D,z)=>{if(D[k]){let H=z===0?1:L[z-1].filter((v)=>v&&v!=="").length;f+=H,U+=`${f}`}});for(let D=0;D${Q[D].values[k]||0}`;U+=""}}U+="",U+='',U+=` -`,W.file("xl/worksheets/sheet1.xml",U)}W.generateAsync({type:"base64"}).then((U)=>{q.file(`ppt/embeddings/Microsoft_Excel_Worksheet${$.globalId}.xlsx`,U,{base64:!0}),q.file("ppt/charts/_rels/"+$.fileName+".rels",``),q.file(`ppt/charts/${$.fileName}`,xB($)),K("")}).catch((U)=>{J(U)})})})}function xB($){var q,Q,K,J;let Z='',G=!1;{if(Z+='',Z+='',Z+=``,Z+="",$.opts.showTitle)Z+=H5({title:$.opts.title||"Chart Title",color:$.opts.titleColor,fontFace:$.opts.titleFontFace,fontSize:$.opts.titleFontSize||DB,titleAlign:$.opts.titleAlign,titleBold:$.opts.titleBold,titlePos:$.opts.titlePos,titleRotate:$.opts.titleRotate},$.opts.x,$.opts.y),Z+='';else Z+='';if($.opts._type===q0.BAR3D)Z+=``;if(Z+="",$.opts.layout)Z+="",Z+=" ",Z+=' ',Z+=' ',Z+=' ',Z+=' ',Z+=' ',Z+=' ',Z+=' ',Z+=" ",Z+="";else Z+=""}if(Array.isArray($.opts._type))$.opts._type.forEach((W)=>{let B=Object.assign(Object.assign({},$.opts),W.options),V=B.secondaryValAxis?N5:o2,U=B.secondaryCatAxis?x7:B8;G=G||B.secondaryValAxis,Z+=$J(W.type,W.data,B,V,U)});else Z+=$J($.opts._type,$.data,$.opts,o2,B8);if($.opts._type!==q0.PIE&&$.opts._type!==q0.DOUGHNUT){if($.opts.valAxes&&$.opts.valAxes.length>1&&!G)throw Error("Secondary axis must be used by one of the multiple charts");if($.opts.catAxes){if(!$.opts.valAxes||$.opts.valAxes.length!==$.opts.catAxes.length)throw Error("There must be the same number of value and category axes.");Z+=A7(Object.assign(Object.assign({},$.opts),$.opts.catAxes[0]),B8,o2)}else Z+=A7($.opts,B8,o2);if($.opts.valAxes){if(Z+=X7(Object.assign(Object.assign({},$.opts),$.opts.valAxes[0]),o2),$.opts.valAxes[1])Z+=X7(Object.assign(Object.assign({},$.opts),$.opts.valAxes[1]),N5)}else if(Z+=X7($.opts,o2),$.opts._type===q0.BAR3D)Z+=OB($.opts,UJ,o2);if(((q=$.opts)===null||q===void 0?void 0:q.catAxes)&&((Q=$.opts)===null||Q===void 0?void 0:Q.catAxes[1]))Z+=A7(Object.assign(Object.assign({},$.opts),$.opts.catAxes[1]),x7,N5)}{if($.opts.showDataTable)Z+="",Z+=` `,Z+=` `,Z+=` `,Z+=` `,Z+=" ",Z+=" ",Z+=' ',Z+=" ",Z+=" ",Z+=" ",Z+=' ',Z+=" ",Z+=" ",Z+=' ',Z+=` `,Z+=' ',Z+=' ',Z+=' ',Z+=' ',Z+=" ",Z+=" ",Z+=' ',Z+=" ",Z+=" ",Z+="";if(Z+=" ",Z+=((K=$.opts.plotArea.fill)===null||K===void 0?void 0:K.color)?B2($.opts.plotArea.fill):"",Z+=$.opts.plotArea.border?`${B2($.opts.plotArea.border.color)}`:"",Z+=" ",Z+=" ",Z+="",$.opts.showLegend){if(Z+="",Z+='',Z+='',$.opts.legendFontFace||$.opts.legendFontSize||$.opts.legendColor){if(Z+="",Z+=" ",Z+=" ",Z+=" ",Z+=" ",Z+=$.opts.legendFontSize?``:"",$.opts.legendColor)Z+=B2($.opts.legendColor);if($.opts.legendFontFace)Z+='';if($.opts.legendFontFace)Z+='';Z+=" ",Z+=" ",Z+=' ',Z+=" ",Z+=""}Z+=""}}if(Z+=' ',Z+=' ',$.opts._type===q0.SCATTER)Z+='';return Z+="",Z+="",Z+=((J=$.opts.chartArea.fill)===null||J===void 0?void 0:J.color)?B2($.opts.chartArea.fill):"",Z+=$.opts.chartArea.border?`${B2($.opts.chartArea.border.color)}`:"",Z+=" ",Z+="",Z+='',Z+="",Z}function $J($,q,Q,K,J,Z){let G=-1,W=1,B=null,V="";switch($){case q0.AREA:case q0.BAR:case q0.BAR3D:case q0.LINE:case q0.RADAR:if(V+=``,$===q0.AREA&&Q.barGrouping==="stacked")V+='';if($===q0.BAR||$===q0.BAR3D)V+='',V+='';if($===q0.RADAR)V+='';V+='',q.forEach((U)=>{var w;G++,V+="",V+=` `,V+=" ",V+=" ",V+=" Sheet1!$"+j0(U._dataIndex+U.labels.length+1)+"$1",V+=' '+k0(U.name)+"",V+=" ",V+=" ";let F=Q.chartColors?Q.chartColors[G%Q.chartColors.length]:null;if(V+=" ",F==="transparent")V+="";else if(Q.chartColorsOpacity)V+=""+R0(F,``)+"";else V+=""+R0(F)+"";if($===q0.LINE||$===q0.RADAR)if(Q.lineSize===0)V+="";else V+=`${R0(F)}`,V+='';else if(Q.dataBorder)V+=`${R0(Q.dataBorder.color)}`;if(V+=T1(Q.shadow,P1),V+=" ",V+=' ',$!==q0.RADAR){if(V+="",V+=``,Q.dataLabelBkgrdColors)V+=`${R0(F)}`;if(V+="",V+=``,V+=`${R0(Q.dataLabelColor||Q2)}`,V+=``,V+="",Q.dataLabelPosition)V+=``;V+='',V+=``,V+=``,V+=``,V+=""}if($===q0.LINE||$===q0.RADAR){if(V+="",V+=' ',Q.lineDataSymbolSize)V+=``;V+=" ",V+=` ${R0(Q.chartColors[U._dataIndex+1>Q.chartColors.length?Math.floor(Math.random()*Q.chartColors.length):U._dataIndex])}`,V+=` ${R0(Q.lineDataSymbolLineColor||F)}`,V+=" ",V+=" ",V+=""}if(($===q0.BAR||$===q0.BAR3D)&&q.length===1&&(Q.chartColors&&Q.chartColors!==z8&&Q.chartColors.length>1||((w=Q.invertedColors)===null||w===void 0?void 0:w.length)))U.values.forEach((M,k)=>{let f=M<0?Q.invertedColors||Q.chartColors||z8:Q.chartColors||[];if(V+=" ",V+=` `,V+=' ',V+=' ',V+=" ",Q.lineSize===0)V+="";else if($===q0.BAR)V+="",V+=' ',V+="";else V+="",V+=" ",V+=' ',V+=" ",V+="";V+=T1(Q.shadow,P1),V+=" ",V+=" "});{if(V+="",Q.catLabelFormatCode)V+=" ",V+=` Sheet1!$A$2:$A$${U.labels[0].length+1}`,V+=" ",V+=" "+(Q.catLabelFormatCode||"General")+"",V+=` `,U.labels[0].forEach((M,k)=>V+=`${k0(M)}`),V+=" ",V+=" ";else V+=" ",V+=` Sheet1!$A$2:$${j0(U.labels.length)}$${U.labels[0].length+1}`,V+=" ",V+=` `,U.labels.forEach((M)=>{V+="",M.forEach((k,f)=>V+=`${k0(k)}`),V+=""}),V+=" ",V+=" ";V+=""}if(V+="",V+=" ",V+=`Sheet1!$${j0(U._dataIndex+U.labels.length+1)}$2:$${j0(U._dataIndex+U.labels.length+1)}$${U.labels[0].length+1}`,V+=" ",V+=" "+(Q.valLabelFormatCode||Q.dataTableFormatCode||"General")+"",V+=` `,U.values.forEach((M,k)=>V+=`${M||M===0?M:""}`),V+=" ",V+=" ",V+="",$===q0.LINE)V+='';V+=""});{if(V+=" ",V+=` `,V+=" ",V+=" ",V+=" ",V+=" ",V+=` `,V+=" "+R0(Q.dataLabelColor||Q2)+"",V+=' ',V+=" ",V+=" ",V+=" ",Q.dataLabelPosition)V+=' ';V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=` `,V+=" "}if($===q0.BAR)V+=` `,V+=` `;else if($===q0.BAR3D)V+=` `,V+=` `,V+=' ';else if($===q0.LINE)V+=' ';V+=``,V+=``;break;case q0.SCATTER:V+="",V+='',V+='',G=-1,q.filter((U,w)=>w>0).forEach((U,w)=>{G++,V+="",V+=` `,V+=` `,V+=" ",V+=" ",V+=` Sheet1!$${j0(w+2)}$1`,V+=' '+k0(U.name)+"",V+=" ",V+=" ",V+=" ";{let F=Q.chartColors[G%Q.chartColors.length];if(F==="transparent")V+="";else if(Q.chartColorsOpacity)V+=""+R0(F,'')+"";else V+=""+R0(F)+"";if(Q.lineSize===0)V+="";else V+=`${R0(F)}`,V+=``;V+=T1(Q.shadow,P1)}V+=" ";{if(V+="",V+=' ',Q.lineDataSymbolSize)V+=``;V+="",V+=`${R0(Q.chartColors[w+1>Q.chartColors.length?Math.floor(Math.random()*Q.chartColors.length):w])}`,V+=`${R0(Q.lineDataSymbolLineColor||Q.chartColors[G%Q.chartColors.length])}`,V+="",V+="",V+=""}if(Q.showLabel){let F=Y5("-xxxx-xxxx-xxxx-xxxxxxxxxxxx");if(U.labels[0]&&(Q.dataLabelFormatScatter==="custom"||Q.dataLabelFormatScatter==="customXY"))V+="",U.labels[0].forEach((M,k)=>{if(Q.dataLabelFormatScatter==="custom"||Q.dataLabelFormatScatter==="customXY"){if(V+=" ",V+=` `,V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=' ',V+=" "+k0(M)+"",V+=" ",Q.dataLabelFormatScatter==="customXY"&&!/^ *$/.test(M))V+=" ",V+=' ',V+=" (",V+=" ",V+=' ',V+=' ',V+=" ",V+=" ",V+=" ",V+=" ["+k0(U.name)+"",V+=" ",V+=" ",V+=' ',V+=" , ",V+=" ",V+=' ',V+=' ',V+=" ",V+=" ",V+=" ",V+=" ["+k0(U.name)+"]",V+=" ",V+=" ",V+=' ',V+=" )",V+=" ",V+=' ';if(V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",Q.dataLabelPosition)V+=' ';V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=" ",V+=' ',V+=' ',V+=` `,V+=" ",V+=" ",V+=""}}),V+="";if(Q.dataLabelFormatScatter==="XY"){if(V+="",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=' ',V+=" ",V+=" ",Q.dataLabelPosition)V+=' ';V+=' ',V+=` `,V+=` `,V+=` `,V+=' ',V+=' ',V+=" ",V+=' ',V+=' ',V+=" ",V+=" ",V+=""}}if(q.length===1&&Q.chartColors!==z8)U.values.forEach((F,M)=>{let k=F<0?Q.invertedColors||Q.chartColors||z8:Q.chartColors||[];if(V+=" ",V+=` `,V+=' ',V+=' ',V+=" ",Q.lineSize===0)V+="";else V+="",V+=' ',V+="";V+=T1(Q.shadow,P1),V+=" ",V+=" "});V+="",V+=" ",V+=` Sheet1!$A$2:$A$${q[0].values.length+1}`,V+=" ",V+=" General",V+=` `,q[0].values.forEach((F,M)=>{V+=`${F||F===0?F:""}`}),V+=" ",V+=" ",V+="",V+="",V+=" ",V+=` Sheet1!$${j0(w+2)}$2:$${j0(w+2)}$${q[0].values.length+1}`,V+=" ",V+=" General",V+=` `,q[0].values.forEach((F,M)=>{V+=`${U.values[M]||U.values[M]===0?U.values[M]:""}`}),V+=" ",V+=" ",V+="",V+='',V+=""});{if(V+=" ",V+=` `,V+=" ",V+=" ",V+=" ",V+=" ",V+=` `,V+=" "+R0(Q.dataLabelColor||Q2)+"",V+=' ',V+=" ",V+=" ",V+=" ",Q.dataLabelPosition)V+=' ';V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=" "}V+=``,V+="";break;case q0.BUBBLE:case q0.BUBBLE3D:V+="",V+='',G=-1,q.filter((U,w)=>w>0).forEach((U,w)=>{G++,V+="",V+=` `,V+=` `,V+=" ",V+=" ",V+=" Sheet1!$"+j0(W+1)+"$1",V+=' '+k0(U.name)+"",V+=" ",V+=" ";{V+="";let F=Q.chartColors[G%Q.chartColors.length];if(F==="transparent")V+="";else if(Q.chartColorsOpacity)V+=`${R0(F,'')}`;else V+=""+R0(F)+"";if(Q.lineSize===0)V+="";else if(Q.dataBorder)V+=`${R0(Q.dataBorder.color)}`;else V+=`${R0(F)}`,V+=``;V+=T1(Q.shadow,P1),V+=""}V+="",V+=" ",V+=` Sheet1!$A$2:$A$${q[0].values.length+1}`,V+=" ",V+=" General",V+=` `,q[0].values.forEach((F,M)=>{V+=`${F||F===0?F:""}`}),V+=" ",V+=" ",V+="",V+="",V+=" ",V+=`Sheet1!$${j0(W+1)}$2:$${j0(W+1)}$${q[0].values.length+1}`,W++,V+=" ",V+=" General",V+=` `,q[0].values.forEach((F,M)=>{V+=`${U.values[M]||U.values[M]===0?U.values[M]:""}`}),V+=" ",V+=" ",V+="",V+=" ",V+=" ",V+=`Sheet1!$${j0(W+1)}$2:$${j0(W+1)}$${U.sizes.length+1}`,W++,V+=" ",V+=" General",V+=` `,U.sizes.forEach((F,M)=>{V+=`${F||""}`}),V+=" ",V+=" ",V+=" ",V+=' ',V+=""});{if(V+="",V+=``,V+="",V+=``,V+=`${R0(Q.dataLabelColor||Q2)}`,V+=``,V+="",Q.dataLabelPosition)V+=``;V+='',V+=``,V+=``,V+="",V+=' ',V+=' ',V+=" ",V+="",V+=""}V+=``,V+="";break;case q0.DOUGHNUT:case q0.PIE:if(B=q[0],V+="",V+=' ',V+="",V+=' ',V+=' ',V+=" ",V+=" ",V+=" Sheet1!$B$1",V+=" ",V+=' ',V+=' '+k0(B.name)+"",V+=" ",V+=" ",V+=" ",V+=" ",V+=' ',V+=' ',Q.dataNoEffects)V+="";else V+=T1(Q.shadow,P1);if(V+=" ",B.labels[0].forEach((U,w)=>{if(V+="",V+=` `,V+=' ',V+=" ",V+=`${R0(Q.chartColors[w+1>Q.chartColors.length?Math.floor(Math.random()*Q.chartColors.length):w])}`,Q.dataBorder)V+=`${R0(Q.dataBorder.color)}`;V+=T1(Q.shadow,P1),V+=" ",V+=""}),V+="",B.labels[0].forEach((U,w)=>{if(V+="",V+=` `,V+=` `,V+=" ",V+=" ",V+=" ",V+=` `,V+=" "+R0(Q.dataLabelColor||Q2)+"",V+=` `,V+=" ",V+=" ",V+=" ",$===q0.PIE&&Q.dataLabelPosition)V+=``;V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=" "}),V+=` `,V+=" ",V+=" ",V+=" ",V+=" ",V+=" ",V+=` `,V+=' ',V+=" ",V+=" ",V+=" ",V+=" ",V+=$===q0.PIE?'':"",V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=' ',V+=` `,V+="",V+="",V+=" ",V+=` Sheet1!$A$2:$A$${B.labels[0].length+1}`,V+=" ",V+=` `,B.labels[0].forEach((U,w)=>{V+=`${k0(U)}`}),V+=" ",V+=" ",V+="",V+=" ",V+=" ",V+=` Sheet1!$B$2:$B$${B.labels[0].length+1}`,V+=" ",V+=` `,B.values.forEach((U,w)=>{V+=`${U||U===0?U:""}`}),V+=" ",V+=" ",V+=" ",V+=" ",V+=` `,$===q0.DOUGHNUT)V+=``;V+="";break;default:V+="";break}return V}function A7($,q,Q){let K="";if($._type===q0.SCATTER||$._type===q0.BUBBLE||$._type===q0.BUBBLE3D)K+="";else K+="";if(K+=' ',K+=" ",K+='',$.catAxisMaxVal||$.catAxisMaxVal===0)K+=``;if($.catAxisMinVal||$.catAxisMinVal===0)K+=``;if(K+="",K+=' ',K+=' ',K+=$.catGridLine.style!=="none"?b7($.catGridLine):"",$.showCatAxisTitle)K+=H5({color:$.catAxisTitleColor,fontFace:$.catAxisTitleFontFace,fontSize:$.catAxisTitleFontSize,titleRotate:$.catAxisTitleRotate,title:$.catAxisTitle||"Axis Title"});if($._type===q0.SCATTER||$._type===q0.BUBBLE||$._type===q0.BUBBLE3D)K+=' ';else K+=' ';if($._type===q0.SCATTER)K+=' ',K+=' ',K+=' ';else K+=' ',K+=' ',K+=' ';if(K+=" ",K+=` `,K+=!$.catAxisLineShow?"":""+R0($.catAxisLineColor||u1.color)+"",K+=' ',K+=" ",K+=" ",K+=" ",K+=" ",$.catAxisLabelRotate)K+=``;else K+="";if(K+=" ",K+=" ",K+=" ",K+=` `,K+=" "+R0($.catAxisLabelColor||Q2)+"",K+=' ',K+=" ",K+=" ",K+=' ',K+=" ",K+=" ",K+=' ',K+=` `,K+=' ',K+=' ',K+=` `,$.catAxisLabelFrequency)K+=' ';if($.catLabelFormatCode||$._type===q0.SCATTER||$._type===q0.BUBBLE||$._type===q0.BUBBLE3D){if($.catLabelFormatCode){if(["catAxisBaseTimeUnit","catAxisMajorTimeUnit","catAxisMinorTimeUnit"].forEach((J)=>{if($[J]&&(typeof $[J]!=="string"||!["days","months","years"].includes($[J].toLowerCase())))console.warn(`"${J}" must be one of: 'days','months','years' !`),$[J]=null}),$.catAxisBaseTimeUnit)K+='';if($.catAxisMajorTimeUnit)K+='';if($.catAxisMinorTimeUnit)K+=''}if($.catAxisMajorUnit)K+=``;if($.catAxisMinorUnit)K+=``}if($._type===q0.SCATTER||$._type===q0.BUBBLE||$._type===q0.BUBBLE3D)K+="";else K+="";return K}function X7($,q){let Q=q===o2?$.barDir==="col"?"l":"b":$.barDir!=="col"?"r":"t";if(q===N5)Q="r";let K=q===o2?B8:x7,J="";if(J+="",J+=' ',J+=" ",$.valAxisLogScaleBase)J+=``;if(J+='',$.valAxisMaxVal||$.valAxisMaxVal===0)J+=``;if($.valAxisMinVal||$.valAxisMinVal===0)J+=``;if(J+=" ",J+=` `,J+=' ',$.valGridLine.style!=="none")J+=b7($.valGridLine);if($.showValAxisTitle)J+=H5({color:$.valAxisTitleColor,fontFace:$.valAxisTitleFontFace,fontSize:$.valAxisTitleFontSize,titleRotate:$.valAxisTitleRotate,title:$.valAxisTitle||"Axis Title"});if(J+=``,$._type===q0.SCATTER)J+=' ',J+=' ',J+=' ';else J+=' ',J+=' ',J+=' ';if(J+=" ",J+=` `,J+=!$.valAxisLineShow?"":""+R0($.valAxisLineColor||u1.color)+"",J+=' ',J+=" ",J+=" ",J+=" ",J+=" ",J+=` `,J+=" ",J+=" ",J+=" ",J+=` `,J+=" "+R0($.valAxisLabelColor||Q2)+"",J+=' ',J+=" ",J+=" ",J+=' ',J+=" ",J+=" ",J+=' ',typeof $.catAxisCrossesAt==="number")J+=` `;else if(typeof $.catAxisCrossesAt==="string")J+=' ';else J+=' ';if(J+=' ',$.valAxisMajorUnit)J+=` `;if($.valAxisDisplayUnit)J+=`${$.valAxisDisplayUnitLabel?"":""}`;return J+="",J}function OB($,q,Q){let K="";if(K+="",K+=' ',K+=' ',K+=' ',K+=' ',K+=$.serGridLine.style!=="none"?b7($.serGridLine):"",$.showSerAxisTitle)K+=H5({color:$.serAxisTitleColor,fontFace:$.serAxisTitleFontFace,fontSize:$.serAxisTitleFontSize,titleRotate:$.serAxisTitleRotate,title:$.serAxisTitle||"Axis Title"});if(K+=` `,K+=' ',K+=' ',K+=` `,K+=" ",K+=' ',K+=!$.serAxisLineShow?"":`${R0($.serAxisLineColor||u1.color)}`,K+=' ',K+=" ",K+=" ",K+=" ",K+=" ",K+=" ",K+=" ",K+=" ",K+=" ",K+=` `,K+=` ${R0($.serAxisLabelColor||Q2)}`,K+=` `,K+=" ",K+=" ",K+=' ',K+=" ",K+=" ",K+=' ',K+=' ',$.serAxisLabelFrequency)K+=' ';if($.serLabelFormatCode){if(["serAxisBaseTimeUnit","serAxisMajorTimeUnit","serAxisMinorTimeUnit"].forEach((J)=>{if($[J]&&(typeof $[J]!=="string"||!["days","months","years"].includes(J.toLowerCase())))console.warn(`"${J}" must be one of: 'days','months','years' !`),$[J]=null}),$.serAxisBaseTimeUnit)K+=` `;if($.serAxisMajorTimeUnit)K+=` `;if($.serAxisMinorTimeUnit)K+=` `;if($.serAxisMajorUnit)K+=` `;if($.serAxisMinorUnit)K+=` `}return K+="",K}function H5($,q,Q){let K=$.titleAlign==="left"||$.titleAlign==="right"?``:"",J=$.titleRotate?``:"",Z=$.fontSize?`sz="${Math.round($.fontSize*100)}"`:"",G=$.titleBold?1:0,W="";if($.titlePos&&typeof $.titlePos.x==="number"&&typeof $.titlePos.y==="number"){let B=$.titlePos.x+q,V=$.titlePos.y+Q,U=B===0?0:B*(B/5)/10;if(U>=1)U=U/10;if(U>=0.1)U=U/10;let w=V===0?0:V*(V/5)/10;if(w>=1)w=w/10;if(w>=0.1)w=w/10;W=``}return` - - - ${J} - - - ${K} - - ${R0($.color||Q2)} - - - - - - ${R0($.color||Q2)} - - - ${k0($.title)||""} - - - - - ${W} - - `}function j0($){let q="",Q=$-1;if(Q<=25)q=W8[Q];else q=`${W8[Math.floor(Q/W8.length-1)]}${W8[Q%W8.length]}`;return q}function T1($,q){if(!$)return"";else if(typeof $!=="object")return console.warn("`shadow` options must be an object. Ex: `{shadow: {type:'none'}}`"),"";let Q="",K=Object.assign(Object.assign({},q),$),J=K.type||"outer",Z=Y0(K.blur),G=Y0(K.offset),W=Math.round(K.angle*60000),B=K.color,V=Math.round(K.opacity*1e5),U=K.rotateWithShape?1:0;return Q+=``,Q+=``,Q+=``,Q+=``,Q+="",Q}function b7($){let q="";return q+=" ",q+=` `,q+=' ',q+=' ',q+=" ",q+=" ",q+="",q}function k5($){if(!$||$==="flat")return"flat";else if($==="square")return"sq";else if($==="round")return"rnd";else throw Error(`Invalid chart line cap: ${$}`)}function y7($){var q,Q;let K=typeof process<"u"&&!!((q=process.versions)===null||q===void 0?void 0:q.node)&&((Q=process.release)===null||Q===void 0?void 0:Q.name)==="node",J,Z,G=K?()=>W2(this,void 0,void 0,function*(){({default:J}=yield import("node:fs")),{default:Z}=yield Promise.resolve().then(() => (tK(),sK))}):()=>W2(this,void 0,void 0,function*(){});if(K)G();let W=[],B=$._relsMedia.filter((U)=>U.type!=="online"&&!U.data&&(!U.path||U.path&&!U.path.includes("preencoded"))),V=[];return B.forEach((U)=>{if(!V.includes(U.path))U.isDuplicate=!1,V.push(U.path);else U.isDuplicate=!0}),B.filter((U)=>!U.isDuplicate).forEach((U)=>{W.push((()=>W2(this,void 0,void 0,function*(){if(!Z)yield G();if(K&&J&&U.path.indexOf("http")!==0)try{let w=J.readFileSync(U.path);return U.data=Buffer.from(w).toString("base64"),B.filter((F)=>F.isDuplicate&&F.path===U.path).forEach((F)=>F.data=U.data),"done"}catch(w){throw U.data=j6,B.filter((F)=>F.isDuplicate&&F.path===U.path).forEach((F)=>F.data=U.data),Error(`ERROR: Unable to read media: "${U.path}" -${String(w)}`)}if(K&&Z&&U.path.startsWith("http"))return yield new Promise((w,F)=>{Z.get(U.path,(M)=>{let k="";M.setEncoding("binary"),M.on("data",(f)=>k+=f),M.on("end",()=>{U.data=Buffer.from(k,"binary").toString("base64"),B.filter((f)=>f.isDuplicate&&f.path===U.path).forEach((f)=>f.data=U.data),w("done")}),M.on("error",()=>{U.data=j6,B.filter((f)=>f.isDuplicate&&f.path===U.path).forEach((f)=>f.data=U.data),F(Error(`ERROR! Unable to load image (https.get): ${U.path}`))})})});return yield new Promise((w,F)=>{let M=new XMLHttpRequest;M.onload=()=>{let k=new FileReader;k.onloadend=()=>{if(U.data=k.result,B.filter((f)=>f.isDuplicate&&f.path===U.path).forEach((f)=>f.data=U.data),!U.isSvgPng)w("done");else QJ(U).then(()=>w("done")).catch(F)},k.readAsDataURL(M.response)},M.onerror=()=>{U.data=j6,B.filter((k)=>k.isDuplicate&&k.path===U.path).forEach((k)=>k.data=U.data),F(Error(`ERROR! Unable to load image (xhr.onerror): ${U.path}`))},M.open("GET",U.path),M.responseType="blob",M.send()})}))())}),$._relsMedia.filter((U)=>U.isSvgPng&&U.data).forEach((U)=>{(()=>W2(this,void 0,void 0,function*(){if(K&&!J)yield G();if(K&&J)U.data=j6,W.push(Promise.resolve("done"));else W.push(QJ(U))}))()}),W}function QJ($){return W2(this,void 0,void 0,function*(){return yield new Promise((q,Q)=>{let K=new Image;K.onload=()=>{if(K.width+K.height===0)K.onerror("h/w=0");let J=document.createElement("CANVAS"),Z=J.getContext("2d");J.width=K.width,J.height=K.height,Z.drawImage(K,0,0);try{$.data=J.toDataURL($.type),q("done")}catch(G){K.onerror(G.toString())}J=null},K.onerror=()=>{$.data=j6,Q(Error(`ERROR! Unable to load image (image.onerror): ${$.path}`))},K.src=typeof $.data==="string"?$.data:j6})})}var PB={cover:function($,q){let Q=$.h/$.w,J=q.h/q.w>Q,Z=J?q.h/Q:q.w,G=J?q.h:q.w*Q,W=Math.round(50000*(1-q.w/Z)),B=Math.round(50000*(1-q.h/G));return``},contain:function($,q){let Q=$.h/$.w,J=q.h/q.w>Q,Z=J?q.w:q.h/Q,G=J?q.w*Q:q.h,W=Math.round(50000*(1-q.w/Z)),B=Math.round(50000*(1-q.h/G));return``},crop:function($,q){let Q=q.x,K=$.w-(q.x+q.w),J=q.y,Z=$.h-(q.y+q.h),G=Math.round(1e5*(Q/$.w)),W=Math.round(1e5*(K/$.w)),B=Math.round(1e5*(J/$.h)),V=Math.round(1e5*(Z/$.h));return``}};function n7($){var q;let Q=$._name?'':"",K=1;if($._bkgdImgRid)Q+=``;else if((q=$.background)===null||q===void 0?void 0:q.color)Q+=`${B2($.background)}`;else if(!$.bkgd&&$._name&&$._name===h7)Q+='';if(Q+="",Q+='',Q+='',Q+='',$._slideObjects.forEach((J,Z)=>{var G,W,B,V,U,w,F,M;let k=0,f=0,L=H0("75%","X",$._presLayout),D=0,z,N="",H=null,v=null,j=0,n=0,d=null,_=null,X=(G=J.options)===null||G===void 0?void 0:G.sizing,P=(W=J.options)===null||W===void 0?void 0:W.rounding;if($._slideLayout!==void 0&&$._slideLayout._slideObjects!==void 0&&J.options&&J.options.placeholder)z=$._slideLayout._slideObjects.filter((h)=>h.options.placeholder===J.options.placeholder)[0];if(J.options=J.options||{},typeof J.options.x<"u")k=H0(J.options.x,"X",$._presLayout);if(typeof J.options.y<"u")f=H0(J.options.y,"Y",$._presLayout);if(typeof J.options.w<"u")L=H0(J.options.w,"X",$._presLayout);if(typeof J.options.h<"u")D=H0(J.options.h,"Y",$._presLayout);let g=L,c=D;if(z){if(z.options.x||z.options.x===0)k=H0(z.options.x,"X",$._presLayout);if(z.options.y||z.options.y===0)f=H0(z.options.y,"Y",$._presLayout);if(z.options.w||z.options.w===0)L=H0(z.options.w,"X",$._presLayout);if(z.options.h||z.options.h===0)D=H0(z.options.h,"Y",$._presLayout)}if(J.options.flipH)N+=' flipH="1"';if(J.options.flipV)N+=' flipV="1"';if(J.options.rotate)N+=` rot="${S1(J.options.rotate)}"`;switch(J._type){case D0.table:if(H=J.arrTabRows,v=J.options,j=0,n=0,H[0].forEach((h)=>{d=h.options||null,j+=(d===null||d===void 0?void 0:d.colspan)?Number(d.colspan):1}),_=``,_+=' ',_+=``,_+='',Array.isArray(v.colW)){_+="";for(let h=0;h`}_+=""}else{if(n=v.colW?v.colW:L0,J.options.w&&!v.colW)n=Math.round((typeof J.options.w==="number"?J.options.w:1)/j);_+="";for(let h=0;h`;_+=""}H.forEach((h)=>{var x,l;for(let $0=0;$01){let W0=Array(F0-1).fill(void 0).map(()=>{return{_type:D0.tablecell,options:{rowspan:p},_hmerge:!0}});h.splice($0+1,0,...W0),$0+=F0}else $0+=1}}),H.forEach((h,x)=>{let l=H[x+1];if(!l)return;h.forEach(($0,Z0)=>{var F0,p;let W0=$0._rowContinue||((F0=$0.options)===null||F0===void 0?void 0:F0.rowspan),y=(p=$0.options)===null||p===void 0?void 0:p.colspan,i=$0._hmerge;if(W0&&W0>1){let U0={_type:D0.tablecell,options:{colspan:y},_rowContinue:W0-1,_vmerge:!0,_hmerge:i};l.splice(Z0,0,U0)}})}),H.forEach((h,x)=>{let l=0;if(Array.isArray(v.rowH)&&v.rowH[x])l=v0(Number(v.rowH[x]));else if(v.rowH&&!isNaN(Number(v.rowH)))l=v0(Number(v.rowH));else if(J.options.cy||J.options.h)l=Math.round((J.options.h?v0(J.options.h):typeof J.options.cy==="number"?J.options.cy:1)/H.length);_+=``,h.forEach(($0)=>{var Z0,F0,p,W0,y;let i=$0,U0={rowSpan:((Z0=i.options)===null||Z0===void 0?void 0:Z0.rowspan)>1?i.options.rowspan:void 0,gridSpan:((F0=i.options)===null||F0===void 0?void 0:F0.colspan)>1?i.options.colspan:void 0,vMerge:i._vmerge?1:void 0,hMerge:i._hmerge?1:void 0},m=Object.keys(U0).map((K0)=>[K0,U0[K0]]).filter(([,K0])=>!!K0).map(([K0,R])=>`${String(K0)}="${String(R)}"`).join(" ");if(m)m=" "+m;if(i._hmerge||i._vmerge){_+=``;return}let V0=i.options||{};i.options=V0,["align","bold","border","color","fill","fontFace","fontSize","margin","textDirection","underline","valign"].forEach((K0)=>{if(v[K0]&&!V0[K0]&&V0[K0]!==0)V0[K0]=v[K0]});let w0=V0.valign?` anchor="${V0.valign.replace(/^c$/i,"ctr").replace(/^m$/i,"ctr").replace("center","ctr").replace("middle","ctr").replace("top","t").replace("btm","b").replace("bottom","b")}"`:"",S=V0.textDirection&&V0.textDirection!=="horz"?` vert="${V0.textDirection}"`:"",b=((W0=(p=i._optImp)===null||p===void 0?void 0:p.fill)===null||W0===void 0?void 0:W0.color)?i._optImp.fill.color:((y=i._optImp)===null||y===void 0?void 0:y.fill)&&typeof i._optImp.fill==="string"?i._optImp.fill:"";b=b||V0.fill?V0.fill:"";let O=b?B2(b):"",E=V0.margin===0||V0.margin?V0.margin:JJ;if(!Array.isArray(E)&&typeof E==="number")E=[E,E,E,E];let a="";if(E[0]>=1)a=` marL="${Y0(E[3])}" marR="${Y0(E[1])}" marT="${Y0(E[0])}" marB="${Y0(E[2])}"`;else a=` marL="${v0(E[3])}" marR="${v0(E[1])}" marT="${v0(E[0])}" marB="${v0(E[2])}"`;if(_+=`${KJ(i)}`,V0.border&&Array.isArray(V0.border))[{idx:3,name:"lnL"},{idx:1,name:"lnR"},{idx:0,name:"lnT"},{idx:2,name:"lnB"}].forEach((K0)=>{if(V0.border[K0.idx].type!=="none")_+=``,_+=`${R0(V0.border[K0.idx].color)}`,_+=``,_+=``;else _+=``});_+=O,_+=" ",_+=" "}),_+=""}),_+=" ",_+=" ",_+=" ",_+="",Q+=_,K++;break;case D0.text:case D0.placeholder:if(!J.options.line&&D===0)D=L0*0.3;if(!J.options._bodyProp)J.options._bodyProp={};if(J.options.margin&&Array.isArray(J.options.margin))J.options._bodyProp.lIns=Y0(J.options.margin[0]||0),J.options._bodyProp.rIns=Y0(J.options.margin[1]||0),J.options._bodyProp.bIns=Y0(J.options.margin[2]||0),J.options._bodyProp.tIns=Y0(J.options.margin[3]||0);else if(typeof J.options.margin==="number")J.options._bodyProp.lIns=Y0(J.options.margin),J.options._bodyProp.rIns=Y0(J.options.margin),J.options._bodyProp.bIns=Y0(J.options.margin),J.options._bodyProp.tIns=Y0(J.options.margin);if(Q+="",Q+=``,(B=J.options.hyperlink)===null||B===void 0?void 0:B.url)Q+=``;if((V=J.options.hyperlink)===null||V===void 0?void 0:V.slide)Q+=``;if(Q+="",Q+="':"/>"),Q+=`${J._type==="placeholder"?w5(J):w5(z)}`,Q+="",Q+=``,Q+=``,Q+=``,J.shape==="custGeom")Q+="",Q+="",Q+="",Q+="",Q+="",Q+="",Q+='',Q+="",Q+=``,(w=J.options.points)===null||w===void 0||w.forEach((h,x)=>{if("curve"in h)switch(h.curve.type){case"arc":Q+=``;break;case"cubic":Q+=` - - - - `;break;case"quadratic":Q+=` - - - `;break}else if("close"in h)Q+="";else if(h.moveTo||x===0)Q+=``;else Q+=``}),Q+="",Q+="",Q+="";else{if(Q+='',J.options.rectRadius)Q+=``;else if(J.options.angleRange){for(let h=0;h<2;h++){let x=J.options.angleRange[h];Q+=``}if(J.options.arcThicknessRatio)Q+=``}Q+=""}if(Q+=J.options.fill?B2(J.options.fill):"",J.options.line){if(Q+=J.options.line.width?``:"",J.options.line.color)Q+=B2(J.options.line);if(J.options.line.dashType)Q+=``;if(J.options.line.beginArrowType)Q+=``;if(J.options.line.endArrowType)Q+=``;Q+=""}if(J.options.shadow&&J.options.shadow.type!=="none")J.options.shadow.type=J.options.shadow.type||"outer",J.options.shadow.blur=Y0(J.options.shadow.blur||8),J.options.shadow.offset=Y0(J.options.shadow.offset||4),J.options.shadow.angle=Math.round((J.options.shadow.angle||270)*60000),J.options.shadow.opacity=Math.round((J.options.shadow.opacity||0.75)*1e5),J.options.shadow.color=J.options.shadow.color||eK.color,Q+="",Q+=` `,Q+=` `,Q+=` `,Q+=" ",Q+="";Q+="",Q+=KJ(J),Q+="";break;case D0.image:if(Q+="",Q+=" ",Q+=``,(F=J.hyperlink)===null||F===void 0?void 0:F.url)Q+=``;if((M=J.hyperlink)===null||M===void 0?void 0:M.slide)Q+=``;if(Q+=" ",Q+=' ',Q+=" "+w5(z)+"",Q+=" ",Q+="",($._relsMedia||[]).filter((h)=>h.rId===J.imageRid)[0]&&($._relsMedia||[]).filter((h)=>h.rId===J.imageRid)[0].extn==="svg")Q+=``,Q+=J.options.transparency?` `:"",Q+=" ",Q+=' ',Q+=` `,Q+=" ",Q+=" ",Q+="";else Q+=``,Q+=J.options.transparency?``:"",Q+="";if(X===null||X===void 0?void 0:X.type){let h=X.w?H0(X.w,"X",$._presLayout):L,x=X.h?H0(X.h,"Y",$._presLayout):D,l=H0(X.x||0,"X",$._presLayout),$0=H0(X.y||0,"Y",$._presLayout);Q+=PB[X.type]({w:g,h:c},{w:h,h:x,x:l,y:$0}),g=h,c=x}else Q+=" ";if(Q+="",Q+="",Q+=" ",Q+=` `,Q+=` `,Q+=" ",Q+=` `,J.options.shadow&&J.options.shadow.type!=="none")J.options.shadow.type=J.options.shadow.type||"outer",J.options.shadow.blur=Y0(J.options.shadow.blur||8),J.options.shadow.offset=Y0(J.options.shadow.offset||4),J.options.shadow.angle=Math.round((J.options.shadow.angle||270)*60000),J.options.shadow.opacity=Math.round((J.options.shadow.opacity||0.75)*1e5),J.options.shadow.color=J.options.shadow.color||eK.color,Q+="",Q+=``,Q+=``,Q+=``,Q+=``,Q+="";Q+="",Q+="";break;case D0.media:if(J.mtype==="online")Q+="",Q+=" ",Q+=``,Q+=" ",Q+=" ",Q+=` `,Q+=" ",Q+=" ",Q+=` `,Q+=" ",Q+=` `,Q+=' ',Q+=" ",Q+="";else Q+="",Q+=" ",Q+=``,Q+=' ',Q+=" ",Q+=` `,Q+=" ",Q+=' ',Q+=` `,Q+=" ",Q+=" ",Q+=" ",Q+=" ",Q+=` `,Q+=" ",Q+=` `,Q+=' ',Q+=" ",Q+="";break;case D0.chart:Q+="",Q+=" ",Q+=` `,Q+=" ",Q+=` ${w5(z)}`,Q+=" ",Q+=` `,Q+=' ',Q+=' ',Q+=` `,Q+=" ",Q+=" ",Q+="";break;default:Q+="";break}}),$._slideNumberProps){if(!$._slideNumberProps.align)$._slideNumberProps.align="left";if(Q+="",Q+=" ",Q+=' ',Q+=' ',Q+=" ",Q+=" ",Q+=` `,Q+="",Q+="`,$._slideNumberProps.color)Q+=B2($._slideNumberProps.color);if($._slideNumberProps.fontFace)Q+=``;Q+=""}if(Q+="",Q+="",$._slideNumberProps.align.startsWith("l"))Q+='';else if($._slideNumberProps.align.startsWith("c"))Q+='';else if($._slideNumberProps.align.startsWith("r"))Q+='';else Q+='';Q+=``,Q+=`${$._slideNum}`,Q+=""}return Q+="",Q+="",Q}function d7($,q){let Q=0,K=''+n0+'';return $._rels.forEach((J)=>{if(Q=Math.max(Q,J.rId),J.type.toLowerCase().includes("hyperlink"))if(J.data==="slide")K+=``;else K+=``;else if(J.type.toLowerCase().includes("notesSlide"))K+=``}),($._relsChart||[]).forEach((J)=>{Q=Math.max(Q,J.rId),K+=``}),($._relsMedia||[]).forEach((J)=>{let Z=J.rId.toString();if(Q=Math.max(Q,J.rId),J.type.toLowerCase().includes("image"))K+='';else if(J.type.toLowerCase().includes("audio"))if(K.includes(' Target="'+J.Target+'"'))K+='';else K+='';else if(J.type.toLowerCase().includes("video"))if(K.includes(' Target="'+J.Target+'"'))K+='';else K+='';else if(J.type.toLowerCase().includes("online"))if(K.includes(' Target="'+J.Target+'"'))K+='';else K+=''}),q.forEach((J,Z)=>{K+=``}),K+="",K}function qJ($,q){var Q,K;let J="",Z="",G="",W="",B=q?"a:lvl1pPr":"a:pPr",V=Y0(kB),U=`<${B}${$.options.rtlMode?' rtl="1" ':""}`;{if($.options.align)switch($.options.align){case"left":U+=' algn="l"';break;case"right":U+=' algn="r"';break;case"center":U+=' algn="ctr"';break;case"justify":U+=' algn="just"';break;default:U+="";break}if($.options.lineSpacing)Z=``;else if($.options.lineSpacingMultiple)Z=``;if($.options.indentLevel&&!isNaN(Number($.options.indentLevel))&&$.options.indentLevel>0)U+=` lvl="${$.options.indentLevel}"`;if($.options.paraSpaceBefore&&!isNaN(Number($.options.paraSpaceBefore))&&$.options.paraSpaceBefore>0)G+=``;if($.options.paraSpaceAfter&&!isNaN(Number($.options.paraSpaceAfter))&&$.options.paraSpaceAfter>0)G+=``;if(typeof $.options.bullet==="object"){if((K=(Q=$===null||$===void 0?void 0:$.options)===null||Q===void 0?void 0:Q.bullet)===null||K===void 0?void 0:K.indent)V=Y0($.options.bullet.indent);if($.options.bullet.type){if($.options.bullet.type.toString().toLowerCase()==="number")U+=` marL="${$.options.indentLevel&&$.options.indentLevel>0?V+V*$.options.indentLevel:V}" indent="-${V}"`,J=``}else if($.options.bullet.characterCode){let w=`&#x${$.options.bullet.characterCode};`;if(!/^[0-9A-Fa-f]{4}$/.test($.options.bullet.characterCode))console.warn("Warning: `bullet.characterCode should be a 4-digit unicode charatcer (ex: 22AB)`!"),w=C6.DEFAULT;U+=` marL="${$.options.indentLevel&&$.options.indentLevel>0?V+V*$.options.indentLevel:V}" indent="-${V}"`,J=''}else if($.options.bullet.code){let w=`&#x${$.options.bullet.code};`;if(!/^[0-9A-Fa-f]{4}$/.test($.options.bullet.code))console.warn("Warning: `bullet.code should be a 4-digit hex code (ex: 22AB)`!"),w=C6.DEFAULT;U+=` marL="${$.options.indentLevel&&$.options.indentLevel>0?V+V*$.options.indentLevel:V}" indent="-${V}"`,J=''}else U+=` marL="${$.options.indentLevel&&$.options.indentLevel>0?V+V*$.options.indentLevel:V}" indent="-${V}"`,J=``}else if($.options.bullet)U+=` marL="${$.options.indentLevel&&$.options.indentLevel>0?V+V*$.options.indentLevel:V}" indent="-${V}"`,J=``;else if(!$.options.bullet)U+=' indent="0" marL="0"',J="";if($.options.tabStops&&Array.isArray($.options.tabStops))W=`${$.options.tabStops.map((F)=>``).join("")}`;if(U+=">"+Z+G+J+W,q)U+=MJ($.options,!0);U+=""}return U}function MJ($,q){var Q;let K="",J=q?"a:defRPr":"a:rPr";if(K+="<"+J+' lang="'+($.lang?$.lang:"en-US")+'"'+($.lang?' altLang="en-US"':""),K+=$.fontSize?` sz="${Math.round($.fontSize*100)}"`:"",K+=($===null||$===void 0?void 0:$.bold)?` b="${$.bold?"1":"0"}"`:"",K+=($===null||$===void 0?void 0:$.italic)?` i="${$.italic?"1":"0"}"`:"",K+=($===null||$===void 0?void 0:$.strike)?` strike="${typeof $.strike==="string"?$.strike:"sngStrike"}"`:"",typeof $.underline==="object"&&((Q=$.underline)===null||Q===void 0?void 0:Q.style))K+=` u="${$.underline.style}"`;else if(typeof $.underline==="string")K+=` u="${String($.underline)}"`;else if($.hyperlink)K+=' u="sng"';if($.baseline)K+=` baseline="${Math.round($.baseline*50)}"`;else if($.subscript)K+=' baseline="-40000"';else if($.superscript)K+=' baseline="30000"';if(K+=$.charSpacing?` spc="${Math.round($.charSpacing*100)}" kern="0"`:"",K+=' dirty="0">',$.color||$.fontFace||$.outline||typeof $.underline==="object"&&$.underline.color){if($.outline&&typeof $.outline==="object")K+=`${B2($.outline.color||"FFFFFF")}`;if($.color)K+=B2({color:$.color,transparency:$.transparency});if($.highlight)K+=`${R0($.highlight)}`;if(typeof $.underline==="object"&&$.underline.color)K+=`${B2($.underline.color)}`;if($.glow)K+=`${fB($.glow,LB)}`;if($.fontFace)K+=``}if($.hyperlink){if(typeof $.hyperlink!=="object")throw Error("ERROR: text `hyperlink` option should be an object. Ex: `hyperlink:{url:'https://github.com'}` ");else if(!$.hyperlink.url&&!$.hyperlink.slide)throw Error("ERROR: 'hyperlink requires either `url` or `slide`'");else if($.hyperlink.url)K+=`":"/>"}`;else if($.hyperlink.slide)K+=`":"/>"}`;if($.color)K+=" ",K+=' ',K+=' ',K+=" ",K+=" ",K+=""}return K+=``,K}function TB($){return $.text?`${MJ($.options,!1)}${k0($.text)}`:""}function uB($){let q="";else if($.options.fit==="resize")q+=""}if($.options.shrinkText)q+="";q+=$.options._bodyProp.autoFit?"":"",q+=""}else q+=' wrap="square" rtlCol="0">',q+="";return $._type===D0.tablecell?"":q}function KJ($){let q=$.options||{},Q=[],K=[];if(q&&$._type!==D0.tablecell&&(typeof $.text>"u"||$.text===null))return"";let J=$._type===D0.tablecell?"":"";if(J+=uB($),q.h===0&&q.line&&q.align)J+='';else if($._type==="placeholder")J+=`${qJ($,!0)}`;else J+="";if(typeof $.text==="string"||typeof $.text==="number")Q.push({text:$.text.toString(),options:q||{}});else if($.text&&!Array.isArray($.text)&&typeof $.text==="object"&&Object.keys($.text).includes("text"))Q.push({text:$.text||"",options:$.options||{}});else if(Array.isArray($.text))Q=$.text.map((W)=>({text:W.text,options:W.options}));Q.forEach((W,B)=>{if(!W.text)W.text="";if(W.options=W.options||q||{},B===0&&W.options&&!W.options.bullet&&q.bullet)W.options.bullet=q.bullet;if(typeof W.text==="string"||typeof W.text==="number")W.text=W.text.toString().replace(/\r*\n/g,n0);if(W.text.includes(n0)&&W.text.match(/\n$/g)===null)W.text.split(n0).forEach((V)=>{W.options.breakLine=!0,K.push({text:V,options:W.options})});else K.push(W)});let Z=[],G=[];if(K.forEach((W,B)=>{if(G.length>0&&(W.options.align||q.align)){if(W.options.align!==K[B-1].options.align)Z.push(G),G=[]}else if(G.length>0&&W.options.bullet&&G.length>0)Z.push(G),G=[],W.options.breakLine=!1;if(G.push(W),G.length>0&&W.options.breakLine){if(B+1{var B;let V=!1;J+="";let U=`{if(w.options._lineIdx=F,F>0&&w.options.softBreakBefore)J+="";if(w.options.align=w.options.align||q.align,w.options.lineSpacing=w.options.lineSpacing||q.lineSpacing,w.options.lineSpacingMultiple=w.options.lineSpacingMultiple||q.lineSpacingMultiple,w.options.indentLevel=w.options.indentLevel||q.indentLevel,w.options.paraSpaceBefore=w.options.paraSpaceBefore||q.paraSpaceBefore,w.options.paraSpaceAfter=w.options.paraSpaceAfter||q.paraSpaceAfter,U=qJ(w,!1),J+=U.replace("",""),Object.entries(q).filter(([M])=>!(w.options.hyperlink&&M==="color")).forEach(([M,k])=>{if(M!=="bullet"&&!w.options[M])w.options[M]=k}),J+=TB(w),!w.text&&q.fontSize||w.options.fontSize)V=!0,q.fontSize=q.fontSize||w.options.fontSize}),$._type===D0.tablecell&&(q.fontSize||q.fontFace))if(q.fontFace)J+=`',J+=``,J+=``,J+=``,J+="";else J+=`';else if(V)J+=`';else J+=``;J+=""}),J.indexOf("")===-1)J+="";return J+=$._type===D0.tablecell?"":"",J}function w5($){var q,Q;if(!$)return"";let K=((q=$.options)===null||q===void 0?void 0:q._placeholderIdx)?$.options._placeholderIdx:"",J=((Q=$.options)===null||Q===void 0?void 0:Q._placeholderType)?$.options._placeholderType:"",Z=J&&F8[J]?F8[J].toString():"";return`0?' hasCustomPrompt="1"':""} - />`}function SB($,q,Q){let K=''+n0;return K+='',K+='',K+='',K+='',K+='',K+='',K+='',K+='',K+='',K+='',$.forEach((J)=>{(J._relsMedia||[]).forEach((Z)=>{if(Z.type!=="image"&&Z.type!=="online"&&Z.type!=="chart"&&Z.extn!=="m4v"&&!K.includes(Z.type))K+=''})}),K+='',K+='',K+='',K+='',$.forEach((J,Z)=>{K+=``,K+=``,J._relsChart.forEach((G)=>{K+=``})}),K+='',K+='',K+='',K+='',q.forEach((J,Z)=>{K+=``,(J._relsChart||[]).forEach((G)=>{K+=' '})}),$.forEach((J,Z)=>{K+=``}),Q._relsChart.forEach((J)=>{K+=' '}),Q._relsMedia.forEach((J)=>{if(J.type!=="image"&&J.type!=="online"&&J.type!=="chart"&&J.extn!=="m4v"&&!K.includes(J.type))K+=' '}),K+=' ',K+=' ',K+="",K}function EB(){return`${n0} - - - - `}function _B($,q){return`${n0} - 0 - 0 - Microsoft Office PowerPoint - On-screen Show (16:9) - 0 - ${$.length} - ${$.length} - 0 - 0 - false - - - Fonts Used - 2 - Theme - 1 - Slide Titles - ${$.length} - - - - - Arial - Calibri - Office Theme - ${$.map((Q,K)=>`Slide ${K+1}`).join("")} - - - ${q} - false - false - false - 16.0000 - `}function cB($,q,Q,K){return` - - ${k0($)} - ${k0(q)} - ${k0(Q)} - ${k0(Q)} - ${K} - ${new Date().toISOString().replace(/\.\d\d\dZ/,"Z")} - ${new Date().toISOString().replace(/\.\d\d\dZ/,"Z")} - `}function bB($){let q=1,Q=''+n0;Q+='',Q+='';for(let K=1;K<=$.length;K++)Q+=``;return q++,Q+=``,Q}function nB($){return`${n0}${n7($)}`}function dB($){let q="";return $._slideObjects.forEach((Q)=>{if(Q._type===D0.notes)q+=(Q===null||Q===void 0?void 0:Q.text)&&Q.text[0]?Q.text[0].text:""}),q.replace(/\r*\n/g,n0)}function mB(){return`${n0}7/23/19Click to edit Master text stylesSecond levelThird levelFourth levelFifth level‹#›`}function pB($){return`${n0}${k0(dB($))}${$._slideNum}`}function iB($){return` - - ${n7($)} - `}function oB($,q){let Q=q.map((J,Z)=>``),K=''+n0;return K+='',K+=n7($),K+='',K+=""+Q.join("")+"",K+='',K+=' '+' '+' '+' '+' '+' '+' '+' '+' '+' '+' ',K+="",K}function aB($,q){return d7(q[$-1],[{target:"../slideMasters/slideMaster1.xml",type:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"}])}function lB($,q,Q){return d7($[Q-1],[{target:`../slideLayouts/slideLayout${eB($,q,Q)}.xml`,type:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"},{target:`../notesSlides/notesSlide${Q}.xml`,type:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide"}])}function rB($){return` - - - - `}function sB($,q){let Q=q.map((K,J)=>({target:`../slideLayouts/slideLayout${J+1}.xml`,type:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"}));return Q.push({target:"../theme/theme1.xml",type:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"}),d7($,Q)}function tB(){return`${n0} - - `}function eB($,q,Q){for(let K=0;K`:'',G=((K=$.theme)===null||K===void 0?void 0:K.bodyFontFace)?``:'';return`${Z}${G}`}function Qz($){let q=`${n0}`;q+='',q+="",$.slides.forEach((Q)=>q+=``),q+="",q+=``,q+=``,q+=``,q+="";for(let Q=1;Q<10;Q++)q+=``;if(q+="",$.sections&&$.sections.length>0)q+='',q+='',$.sections.forEach((Q)=>{q+=``,Q._slides.forEach((K)=>q+=``),q+=""}),q+="",q+='',q+="";return q+="",q}function qz(){return`${n0}`}function Kz(){return`${n0}`}function Jz(){return`${n0}`}var Vz="4.0.1";class m7{set layout($){let q=this.LAYOUTS[$];if(q)this._layout=$,this._presLayout=q;else throw Error("UNKNOWN-LAYOUT")}get layout(){return this._layout}get version(){return this._version}set author($){this._author=$}get author(){return this._author}set company($){this._company=$}get company(){return this._company}set revision($){this._revision=$}get revision(){return this._revision}set subject($){this._subject=$}get subject(){return this._subject}set theme($){this._theme=$}get theme(){return this._theme}set title($){this._title=$}get title(){return this._title}set rtlMode($){this._rtlMode=$}get rtlMode(){return this._rtlMode}get masterSlide(){return this._masterSlide}get slides(){return this._slides}get sections(){return this._sections}get slideLayouts(){return this._slideLayouts}get AlignH(){return this._alignH}get AlignV(){return this._alignV}get ChartType(){return this._chartType}get OutputType(){return this._outputType}get presLayout(){return this._presLayout}get SchemeColor(){return this._schemeColor}get ShapeType(){return this._shapeType}get charts(){return this._charts}get colors(){return this._colors}get shapes(){return this._shapes}constructor(){this._version=Vz,this._alignH=u7,this._alignV=S7,this._chartType=P7,this._outputType=O7,this._schemeColor=G2,this._shapeType=T7,this._charts=q0,this._colors=D5,this._shapes=B1,this.addNewSlide=(J)=>{let Z=this.sections.length>0&&this.sections[this.sections.length-1]._slides.filter((G)=>G._slideNum===this.slides[this.slides.length-1]._slideNum).length>0;return J.sectionTitle=Z?this.sections[this.sections.length-1].title:null,this.addSlide(J)},this.getSlide=(J)=>this.slides.filter((Z)=>Z._slideNum===J)[0],this.setSlideNumber=(J)=>{this.masterSlide._slideNumberProps=J,this.slideLayouts.filter((Z)=>Z._name===h7)[0]._slideNumberProps=J},this.createChartMediaRels=(J,Z,G)=>{J._relsChart.forEach((W)=>G.push(hB(W,Z))),J._relsMedia.forEach((W)=>{if(W.type!=="online"&&W.type!=="hyperlink"){let B=W.data&&typeof W.data==="string"?W.data:"";if(!B.includes(",")&&!B.includes(";"))B="image/png;base64,"+B;else if(!B.includes(","))B="image/png;base64,"+B;else if(!B.includes(";"))B="image/png;"+B;Z.file(W.Target.replace("..","ppt"),B.split(",").pop(),{base64:!0})}})},this.writeFileToBrowser=(J,Z)=>W2(this,void 0,void 0,function*(){let G=document.createElement("a");if(G.setAttribute("style","display:none;"),G.dataset.interception="off",document.body.appendChild(G),window.URL.createObjectURL){let W=window.URL.createObjectURL(new Blob([Z],{type:"application/vnd.openxmlformats-officedocument.presentationml.presentation"}));return G.href=W,G.download=J,G.click(),setTimeout(()=>{window.URL.revokeObjectURL(W),document.body.removeChild(G)},100),yield Promise.resolve(J)}}),this.exportPresentation=(J)=>W2(this,void 0,void 0,function*(){let Z=[],G=[],W=new _7.default;return this.slides.forEach((B)=>{G=G.concat(y7(B))}),this.slideLayouts.forEach((B)=>{G=G.concat(y7(B))}),G=G.concat(y7(this.masterSlide)),yield Promise.all(G).then(()=>W2(this,void 0,void 0,function*(){return this.slides.forEach((B)=>{if(B._slideLayout)yB(B)}),W.folder("_rels"),W.folder("docProps"),W.folder("ppt").folder("_rels"),W.folder("ppt/charts").folder("_rels"),W.folder("ppt/embeddings"),W.folder("ppt/media"),W.folder("ppt/slideLayouts").folder("_rels"),W.folder("ppt/slideMasters").folder("_rels"),W.folder("ppt/slides").folder("_rels"),W.folder("ppt/theme"),W.folder("ppt/notesMasters").folder("_rels"),W.folder("ppt/notesSlides").folder("_rels"),W.file("[Content_Types].xml",SB(this.slides,this.slideLayouts,this.masterSlide)),W.file("_rels/.rels",EB()),W.file("docProps/app.xml",_B(this.slides,this.company)),W.file("docProps/core.xml",cB(this.title,this.subject,this.author,this.revision)),W.file("ppt/_rels/presentation.xml.rels",bB(this.slides)),W.file("ppt/theme/theme1.xml",$z(this)),W.file("ppt/presentation.xml",Qz(this)),W.file("ppt/presProps.xml",qz()),W.file("ppt/tableStyles.xml",Kz()),W.file("ppt/viewProps.xml",Jz()),this.slideLayouts.forEach((B,V)=>{W.file(`ppt/slideLayouts/slideLayout${V+1}.xml`,iB(B)),W.file(`ppt/slideLayouts/_rels/slideLayout${V+1}.xml.rels`,aB(V+1,this.slideLayouts))}),this.slides.forEach((B,V)=>{W.file(`ppt/slides/slide${V+1}.xml`,nB(B)),W.file(`ppt/slides/_rels/slide${V+1}.xml.rels`,lB(this.slides,this.slideLayouts,V+1)),W.file(`ppt/notesSlides/notesSlide${V+1}.xml`,pB(B)),W.file(`ppt/notesSlides/_rels/notesSlide${V+1}.xml.rels`,rB(V+1))}),W.file("ppt/slideMasters/slideMaster1.xml",oB(this.masterSlide,this.slideLayouts)),W.file("ppt/slideMasters/_rels/slideMaster1.xml.rels",sB(this.masterSlide,this.slideLayouts)),W.file("ppt/notesMasters/notesMaster1.xml",mB()),W.file("ppt/notesMasters/_rels/notesMaster1.xml.rels",tB()),this.slideLayouts.forEach((B)=>{this.createChartMediaRels(B,W,Z)}),this.slides.forEach((B)=>{this.createChartMediaRels(B,W,Z)}),this.createChartMediaRels(this.masterSlide,W,Z),yield Promise.all(Z).then(()=>W2(this,void 0,void 0,function*(){if(J.outputType==="STREAM")return yield W.generateAsync({type:"nodebuffer",compression:J.compression?"DEFLATE":"STORE"});else if(J.outputType)return yield W.generateAsync({type:J.outputType});else return yield W.generateAsync({type:"blob",compression:J.compression?"DEFLATE":"STORE"})}))}))});let $={name:"screen4x3",width:9144000,height:6858000},q={name:"screen16x9",width:9144000,height:5143500},Q={name:"screen16x10",width:9144000,height:5715000},K={name:"custom",width:12192000,height:6858000};this.LAYOUTS={LAYOUT_4x3:$,LAYOUT_16x9:q,LAYOUT_16x10:Q,LAYOUT_WIDE:K},this._author="PptxGenJS",this._company="PptxGenJS",this._revision="1",this._subject="PptxGenJS Presentation",this._title="PptxGenJS Presentation",this._presLayout={name:this.LAYOUTS[f6].name,_sizeW:this.LAYOUTS[f6].width,_sizeH:this.LAYOUTS[f6].height,width:this.LAYOUTS[f6].width,height:this.LAYOUTS[f6].height},this._rtlMode=!1,this._slideLayouts=[{_margin:M8,_name:h7,_presLayout:this._presLayout,_rels:[],_relsChart:[],_relsMedia:[],_slide:null,_slideNum:1000,_slideNumberProps:null,_slideObjects:[]}],this._slides=[],this._sections=[],this._masterSlide={addChart:null,addImage:null,addMedia:null,addNotes:null,addShape:null,addTable:null,addText:null,_name:null,_presLayout:this._presLayout,_rId:null,_rels:[],_relsChart:[],_relsMedia:[],_slideId:null,_slideLayout:null,_slideNum:null,_slideNumberProps:null,_slideObjects:[]}}stream($){return W2(this,void 0,void 0,function*(){return yield this.exportPresentation({compression:$===null||$===void 0?void 0:$.compression,outputType:"STREAM"})})}write($){return W2(this,void 0,void 0,function*(){let q=typeof $==="object"&&($===null||$===void 0?void 0:$.outputType)?$.outputType:$?$:null,Q=typeof $==="object"&&($===null||$===void 0?void 0:$.compression)?$.compression:!1;return yield this.exportPresentation({compression:Q,outputType:q})})}writeFile($){return W2(this,void 0,void 0,function*(){var q,Q;let K=typeof process<"u"&&!!((q=process.versions)===null||q===void 0?void 0:q.node)&&((Q=process.release)===null||Q===void 0?void 0:Q.name)==="node";if(typeof $==="string")console.warn("[WARNING] writeFile(string) is deprecated - pass { fileName } instead."),$={fileName:$};let{fileName:J="Presentation.pptx",compression:Z=!1}=$,G=J.toLowerCase().endsWith(".pptx")?J:`${J}.pptx`,W=K?"nodebuffer":null,B=yield this.exportPresentation({compression:Z,outputType:W});if(K){let{promises:V}=yield import("node:fs"),{writeFile:U}=V;return yield U(G,B),G}return yield this.writeFileToBrowser(G,B),G})}addSection($){if(!$)console.warn("addSection requires an argument");else if(!$.title)console.warn("addSection requires a title");let q={_type:"user",_slides:[],title:$.title};if($.order)this.sections.splice($.order,0,q);else this._sections.push(q)}addSlide($){let q=typeof $==="string"?$:($===null||$===void 0?void 0:$.masterName)?$.masterName:"",Q={_name:this.LAYOUTS[f6].name,_presLayout:this.presLayout,_rels:[],_relsChart:[],_relsMedia:[],_slideNum:this.slides.length+1};if(q){let J=this.slideLayouts.filter((Z)=>Z._name===q)[0];if(J)Q=J}let K=new FJ({addSlide:this.addNewSlide,getSlide:this.getSlide,presLayout:this.presLayout,setSlideNum:this.setSlideNumber,slideId:this.slides.length+256,slideRId:this.slides.length+2,slideNumber:this.slides.length+1,slideLayout:Q});if(this._slides.push(K),$===null||$===void 0?void 0:$.sectionTitle){let J=this.sections.filter((Z)=>Z.title===$.sectionTitle)[0];if(!J)console.warn(`addSlide: unable to find section with title: "${$.sectionTitle}"`);else J._slides.push(K)}else if(this.sections&&this.sections.length>0&&!($===null||$===void 0?void 0:$.sectionTitle)){let J=this._sections[this.sections.length-1];if(J._type==="default")J._slides.push(K);else this._sections.push({title:`Default-${this.sections.filter((Z)=>Z._type==="default").length+1}`,_type:"default",_slides:[K]})}return K}defineLayout($){if(!$)console.warn("defineLayout requires `{name, width, height}`");else if(!$.name)console.warn("defineLayout requires `name`");else if(!$.width)console.warn("defineLayout requires `width`");else if(!$.height)console.warn("defineLayout requires `height`");else if(typeof $.height!=="number")console.warn("defineLayout `height` should be a number (inches)");else if(typeof $.width!=="number")console.warn("defineLayout `width` should be a number (inches)");this.LAYOUTS[$.name]={name:$.name,_sizeW:Math.round(Number($.width)*L0),_sizeH:Math.round(Number($.height)*L0),width:Math.round(Number($.width)*L0),height:Math.round(Number($.height)*L0)}}defineSlideMaster($){let q=JSON.parse(JSON.stringify($));if(!q.title)throw Error("defineSlideMaster() object argument requires a `title` value. (https://gitbrent.github.io/PptxGenJS/docs/masters.html)");let Q={_margin:q.margin||M8,_name:q.title,_presLayout:this.presLayout,_rels:[],_relsChart:[],_relsMedia:[],_slide:null,_slideNum:1000+this.slideLayouts.length+1,_slideNumberProps:q.slideNumber||null,_slideObjects:[],background:q.background||null,bkgd:q.bkgd||null};if(jB(q,Q),this.slideLayouts.push(Q),q.background||q.bkgd)zJ(q.background,Q);if(Q._slideNumberProps&&!this.masterSlide._slideNumberProps)this.masterSlide._slideNumberProps=Q._slideNumberProps}tableToSlides($,q={}){IB(this,$,q,(q===null||q===void 0?void 0:q.masterSlideName)?this.slideLayouts.filter((Q)=>Q._name===q.masterSlideName)[0]:null)}}if(typeof globalThis.Buffer>"u")globalThis.Buffer=o;if(typeof globalThis.process>"u")globalThis.process=Uz;globalThis.__bundles=globalThis.__bundles||{};globalThis.__bundles.pptxgenjs=m7;})(); diff --git a/apps/sim/lib/logs/execution/trace-spans/trace-spans.ts b/apps/sim/lib/logs/execution/trace-spans/trace-spans.ts index ba37918435d..858f9fd4939 100644 --- a/apps/sim/lib/logs/execution/trace-spans/trace-spans.ts +++ b/apps/sim/lib/logs/execution/trace-spans/trace-spans.ts @@ -10,6 +10,15 @@ import type { BlockLog, ExecutionResult } from '@/executor/types' const HIDDEN_OUTPUT_KEYS = new Set(['childTraceSpans']) const SUCCESSFUL_CHILD_ERROR_BOUNDARY_BLOCK_TYPES = new Set(['mothership']) +function setFilteredValue(output: Record, key: string, value: unknown): void { + Object.defineProperty(output, key, { + value, + enumerable: true, + configurable: true, + writable: true, + }) +} + /** * Recursively filters hidden keys from nested objects for cleaner display. * Used by both executor (for log output) and UI (for display). @@ -29,7 +38,7 @@ export function filterHiddenOutputKeys(value: unknown): unknown { if (HIDDEN_OUTPUT_KEYS.has(key)) { continue } - filtered[key] = filterHiddenOutputKeys(val) + setFilteredValue(filtered, key, filterHiddenOutputKeys(val)) } return filtered } diff --git a/apps/sim/lib/uploads/utils/user-file-base64.server.test.ts b/apps/sim/lib/uploads/utils/user-file-base64.server.test.ts index 00fe9ab75d4..4e497204463 100644 --- a/apps/sim/lib/uploads/utils/user-file-base64.server.test.ts +++ b/apps/sim/lib/uploads/utils/user-file-base64.server.test.ts @@ -143,6 +143,149 @@ describe('hydrateUserFilesWithBase64', () => { expect(hydrated.file.base64).toBe(Buffer.from('hello').toString('base64')) }) + it('materializes large refs before hydrating nested files', async () => { + const file: UserFile = { + id: 'file-1', + name: 'nested.txt', + key: 'execution/workspace/workflow/source-execution/nested.txt', + url: '/api/files/serve/execution/workspace/workflow/source-execution/nested.txt?context=execution', + size: 5, + type: 'text/plain', + context: 'execution', + } + const ref = { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'object', + size: 256, + key: 'execution/workspace/workflow/source-execution/large-value-lv_ABCDEFGHIJKL.json', + executionId: 'source-execution', + } + + mockDownloadFile.mockImplementation(async ({ key }) => { + if (key.includes('large-value')) { + return Buffer.from(JSON.stringify({ file }), 'utf8') + } + return Buffer.from('hello', 'utf8') + }) + + const hydrated = await hydrateUserFilesWithBase64( + { ref }, + { + workspaceId: 'workspace', + workflowId: 'workflow', + executionId: 'resume-execution', + largeValueExecutionIds: ['source-execution'], + userId: 'user-1', + maxBytes: 1024, + } + ) + + expect((hydrated.ref as unknown as { file: UserFile }).file.base64).toBe( + Buffer.from('hello').toString('base64') + ) + }) + + it('preserves large-value metadata while hydrating visible files when requested', async () => { + mockDownloadFile.mockResolvedValueOnce(Buffer.from('hello', 'utf8')) + const file: UserFile = { + id: 'file-1', + name: 'visible.txt', + key: 'execution/workspace/workflow/execution-1/visible.txt', + url: '/api/files/serve/execution/workspace/workflow/execution-1/visible.txt?context=execution', + size: 5, + type: 'text/plain', + context: 'execution', + } + const ref = { + __simLargeValueRef: true, + version: 1, + id: 'lv_PRESERVEREF1', + kind: 'object', + size: 256, + key: 'execution/workspace/workflow/source-execution/large-value-lv_PRESERVEREF1.json', + executionId: 'source-execution', + } + const manifest = { + __simLargeArrayManifest: true, + version: 2, + kind: 'array', + totalCount: 1, + chunkCount: 1, + byteSize: 256, + chunks: [ + { + ref, + count: 1, + byteSize: 256, + }, + ], + preview: [{ id: 1 }], + } + + const hydrated = await hydrateUserFilesWithBase64( + { file, ref, manifest }, + { + workspaceId: 'workspace', + workflowId: 'workflow', + executionId: 'execution-1', + userId: 'user-1', + maxBytes: 1024, + preserveLargeValueMetadata: true, + } + ) + + expect(hydrated.file.base64).toBe(Buffer.from('hello').toString('base64')) + expect(hydrated.ref).toBe(ref) + expect(hydrated.manifest).toBe(manifest) + expect(mockDownloadFile).toHaveBeenCalledOnce() + }) + + it('hydrates nested prior-execution files discovered from exact-key large refs', async () => { + const file: UserFile = { + id: 'file-1', + name: 'nested.txt', + key: 'execution/workspace/workflow/source-execution/nested.txt', + url: '/api/files/serve/execution/workspace/workflow/source-execution/nested.txt?context=execution', + size: 5, + type: 'text/plain', + context: 'execution', + } + const ref = { + __simLargeValueRef: true, + version: 1, + id: 'lv_MNOPQRSTUVWX', + kind: 'object', + size: 256, + key: 'execution/workspace/workflow/source-execution/large-value-lv_MNOPQRSTUVWX.json', + executionId: 'source-execution', + } + + mockDownloadFile.mockImplementation(async ({ key }) => { + if (key.includes('large-value')) { + return Buffer.from(JSON.stringify({ file }), 'utf8') + } + return Buffer.from('hello', 'utf8') + }) + + const hydrated = await hydrateUserFilesWithBase64( + { ref }, + { + workspaceId: 'workspace', + workflowId: 'workflow', + executionId: 'resume-execution', + largeValueKeys: [ref.key], + userId: 'user-1', + maxBytes: 1024, + } + ) + + expect((hydrated.ref as unknown as { file: UserFile }).file.base64).toBe( + Buffer.from('hello').toString('base64') + ) + }) + it('releases reserved Redis budget when cleaning up execution cache entries', async () => { mockGetRedisClient.mockReturnValue(mockRedis) const rawEntry = JSON.stringify({ bytes: 12, userId: 'user-1' }) diff --git a/apps/sim/lib/uploads/utils/user-file-base64.server.ts b/apps/sim/lib/uploads/utils/user-file-base64.server.ts index 3f666c16ae6..213eb3a9a95 100644 --- a/apps/sim/lib/uploads/utils/user-file-base64.server.ts +++ b/apps/sim/lib/uploads/utils/user-file-base64.server.ts @@ -2,11 +2,21 @@ import type { Logger } from '@sim/logger' import { createLogger } from '@sim/logger' import { getRedisClient } from '@/lib/core/config/redis' import { isUserFileWithMetadata } from '@/lib/core/utils/user-file' -import { LARGE_VALUE_THRESHOLD_BYTES } from '@/lib/execution/payloads/large-value-ref' +import { recordMaterializedAccessKeys } from '@/lib/execution/payloads/access-keys' +import { + isLargeArrayManifest, + materializeLargeArrayManifest, +} from '@/lib/execution/payloads/large-array-manifest' +import { + getLargeValueMaterializationError, + isLargeValueRef, + LARGE_VALUE_THRESHOLD_BYTES, +} from '@/lib/execution/payloads/large-value-ref' import { assertUserFileContentAccess, readUserFileContent, } from '@/lib/execution/payloads/materialization.server' +import { materializeLargeValueRef } from '@/lib/execution/payloads/store' import { type ExecutionRedisBudgetReservation, getExecutionRedisBudgetKeys, @@ -149,6 +159,8 @@ export interface Base64HydrationOptions { workflowId?: string executionId?: string largeValueExecutionIds?: string[] + largeValueKeys?: string[] + fileKeys?: string[] allowLargeValueWorkflowScope?: boolean userId?: string logger?: Logger @@ -156,6 +168,7 @@ export interface Base64HydrationOptions { allowUnknownSize?: boolean timeoutMs?: number cacheTtlSeconds?: number + preserveLargeValueMetadata?: boolean } class InMemoryBase64Cache implements Base64Cache { @@ -401,6 +414,7 @@ async function resolveBase64( workflowId: options.workflowId, executionId: options.executionId, largeValueExecutionIds: options.largeValueExecutionIds, + fileKeys: options.fileKeys, allowLargeValueWorkflowScope: options.allowLargeValueWorkflowScope, userId: options.userId, encoding: 'base64', @@ -427,6 +441,7 @@ async function hydrateUserFile( workflowId: options.workflowId, executionId: options.executionId, largeValueExecutionIds: options.largeValueExecutionIds, + fileKeys: options.fileKeys, allowLargeValueWorkflowScope: options.allowLargeValueWorkflowScope, userId: options.userId, logger, @@ -465,6 +480,36 @@ async function hydrateValue( return value } + if ( + options.preserveLargeValueMetadata && + (isLargeArrayManifest(value) || isLargeValueRef(value)) + ) { + return value + } + + if (isLargeArrayManifest(value)) { + const materialized = await materializeLargeArrayManifest(value, options) + return hydrateValue( + materialized, + withLocalLargeValueExecutionIds(options, materialized), + state, + logger + ) + } + + if (isLargeValueRef(value)) { + const materialized = await materializeLargeValueRef(value, options) + if (materialized === undefined) { + throw getLargeValueMaterializationError(value) + } + return hydrateValue( + materialized, + withLocalLargeValueExecutionIds(options, materialized), + state, + logger + ) + } + if (isUserFileWithMetadata(value)) { return hydrateUserFile(value, options, state, logger) } @@ -491,6 +536,18 @@ async function hydrateValue( return Object.fromEntries(entries) } +function withLocalLargeValueExecutionIds( + options: Base64HydrationOptions, + materializedValue: unknown +): Base64HydrationOptions { + recordMaterializedAccessKeys(options, materializedValue) + return { + ...options, + largeValueKeys: options.largeValueKeys, + fileKeys: options.fileKeys, + } +} + /** * Hydrates UserFile objects within a value to include base64 content. * Returns the original structure with UserFile.base64 set where available. diff --git a/apps/sim/lib/workflows/executor/execute-workflow.ts b/apps/sim/lib/workflows/executor/execute-workflow.ts index 66788e8d8f9..fe02449608a 100644 --- a/apps/sim/lib/workflows/executor/execute-workflow.ts +++ b/apps/sim/lib/workflows/executor/execute-workflow.ts @@ -34,6 +34,8 @@ export interface ExecuteWorkflowOptions { skipLoggingComplete?: boolean includeFileBase64?: boolean base64MaxBytes?: number + largeValueKeys?: string[] + fileKeys?: string[] abortSignal?: AbortSignal /** Use the live/draft workflow state instead of the deployed state. Used by copilot. */ useDraftState?: boolean @@ -43,6 +45,7 @@ export interface ExecuteWorkflowOptions { runFromBlock?: { startBlockId: string sourceSnapshot: SerializableExecutionState + sourceExecutionId?: string } executionMode?: 'sync' | 'stream' | 'async' } @@ -86,6 +89,9 @@ export async function executeWorkflow( useDraftState: streamConfig?.useDraftState ?? false, startTime: new Date().toISOString(), isClientSession: false, + largeValueExecutionIds: Array.from(new Set([executionId])), + largeValueKeys: streamConfig?.largeValueKeys, + fileKeys: streamConfig?.fileKeys, executionMode: streamConfig?.executionMode, } diff --git a/apps/sim/lib/workflows/executor/execution-core.test.ts b/apps/sim/lib/workflows/executor/execution-core.test.ts index e9370ef9454..4f958a6527c 100644 --- a/apps/sim/lib/workflows/executor/execution-core.test.ts +++ b/apps/sim/lib/workflows/executor/execution-core.test.ts @@ -239,6 +239,54 @@ describe('executeWorkflowCore terminal finalization sequencing', () => { expect(findStartBlockMock).toHaveBeenCalledWith(expect.anything(), 'external', false) }) + it('preserves manifest-backed workflow variables during execution setup', async () => { + const manifest = { + __simLargeArrayManifest: true, + version: 2, + kind: 'array', + totalCount: 1, + chunkCount: 1, + byteSize: 16, + chunks: [ + { + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 16, + executionId: 'execution-1', + }, + count: 1, + byteSize: 16, + }, + ], + preview: [{ id: 1 }], + } + executorExecuteMock.mockResolvedValue({ + success: true, + status: 'completed', + output: { done: true }, + logs: [], + metadata: { duration: 123, startTime: 'start', endTime: 'end' }, + }) + + await executeWorkflowCore({ + snapshot: { + ...createSnapshot(), + workflowVariables: { + 'var-1': { id: 'var-1', name: 'issues', type: 'array', value: manifest }, + }, + } as any, + callbacks: {}, + loggingSession: loggingSession as any, + }) + + expect(executorConstructorMock.mock.calls[0]?.[0]?.workflowVariables['var-1'].value).toEqual( + manifest + ) + }) + it('does not await user block start callback after persistence completes', async () => { let releaseCallback: (() => void) | undefined const callbackPromise = new Promise((resolve) => { diff --git a/apps/sim/lib/workflows/executor/execution-core.ts b/apps/sim/lib/workflows/executor/execution-core.ts index 589c4e32363..fe7b40b32fc 100644 --- a/apps/sim/lib/workflows/executor/execution-core.ts +++ b/apps/sim/lib/workflows/executor/execution-core.ts @@ -12,6 +12,7 @@ import { isPlainRecord } from '@/lib/core/utils/records' import { getPersonalAndWorkspaceEnv } from '@/lib/environment/utils' import { clearExecutionCancellation } from '@/lib/execution/cancellation' import { warmLargeValueRefs } from '@/lib/execution/payloads/hydration' +import { parseLargeExecutionValue } from '@/lib/execution/payloads/large-execution-value' import type { LoggingSession } from '@/lib/logs/execution/logging-session' import { buildTraceSpans } from '@/lib/logs/execution/trace-spans/trace-spans' import { @@ -51,10 +52,16 @@ export interface ExecuteWorkflowCoreOptions { runFromBlock?: { startBlockId: string sourceSnapshot: SerializableExecutionState + sourceExecutionId?: string } } function parseVariableValueByType(value: unknown, type: string): unknown { + const refValue = parseLargeExecutionValue(value) + if (refValue !== undefined) { + return refValue + } + if (value === null || value === undefined) { switch (type) { case 'number': @@ -555,18 +562,26 @@ export async function executeWorkflowCore( } const largeValueExecutionIds = Array.from( - new Set([executionId, ...(metadata.largeValueExecutionIds ?? [])].filter(Boolean)) + new Set( + [executionId, ...(metadata.largeValueExecutionIds ?? [])].filter((id): id is string => + Boolean(id) + ) + ) ) + const largeValueKeys = metadata.largeValueKeys + const fileKeys = metadata.fileKeys const allowLargeValueWorkflowScope = metadata.allowLargeValueWorkflowScope === true || metadata.resumeFromSnapshot === true || - Boolean(runFromBlock?.sourceSnapshot) + Boolean(runFromBlock?.sourceSnapshot && !runFromBlock.sourceExecutionId) const contextExtensions: ContextExtensions = { stream: !!onStream, selectedOutputs, executionId, largeValueExecutionIds, + largeValueKeys, + fileKeys, allowLargeValueWorkflowScope, workspaceId: providedWorkspaceId, userId, @@ -600,21 +615,12 @@ export async function executeWorkflowCore( workflowId, executionId, largeValueExecutionIds, + largeValueKeys, + fileKeys, allowLargeValueWorkflowScope, userId, }) } - if (runFromBlock?.sourceSnapshot) { - await warmLargeValueRefs(runFromBlock.sourceSnapshot, { - workspaceId: providedWorkspaceId, - workflowId, - executionId, - largeValueExecutionIds, - allowLargeValueWorkflowScope, - userId, - }) - } - for (const variable of Object.values(workflowVariables)) { if ( isPlainRecord(variable) && diff --git a/apps/sim/lib/workflows/executor/execution-state.ts b/apps/sim/lib/workflows/executor/execution-state.ts index 1d4b72ecef0..3fd2d215c12 100644 --- a/apps/sim/lib/workflows/executor/execution-state.ts +++ b/apps/sim/lib/workflows/executor/execution-state.ts @@ -3,6 +3,11 @@ import { workflowExecutionLogs } from '@sim/db/schema' import { and, desc, eq, sql } from 'drizzle-orm' import type { SerializableExecutionState } from '@/executor/execution/types' +export interface ExecutionStateRecord { + executionId: string + state: SerializableExecutionState +} + function isSerializableExecutionState(value: unknown): value is SerializableExecutionState { if (!value || typeof value !== 'object') return false const state = value as Record @@ -55,8 +60,18 @@ export async function getExecutionStateForWorkflow( export async function getLatestExecutionState( workflowId: string ): Promise { + const record = await getLatestExecutionStateWithExecutionId(workflowId) + return record?.state ?? null +} + +export async function getLatestExecutionStateWithExecutionId( + workflowId: string +): Promise { const [row] = await db - .select({ executionData: workflowExecutionLogs.executionData }) + .select({ + executionId: workflowExecutionLogs.executionId, + executionData: workflowExecutionLogs.executionData, + }) .from(workflowExecutionLogs) .where( and( @@ -67,5 +82,6 @@ export async function getLatestExecutionState( .orderBy(desc(workflowExecutionLogs.startedAt)) .limit(1) - return extractExecutionState(row?.executionData) + const state = extractExecutionState(row?.executionData) + return row && state ? { executionId: row.executionId, state } : null } diff --git a/apps/sim/lib/workflows/streaming/streaming.test.ts b/apps/sim/lib/workflows/streaming/streaming.test.ts new file mode 100644 index 00000000000..f802dc5bfa4 --- /dev/null +++ b/apps/sim/lib/workflows/streaming/streaming.test.ts @@ -0,0 +1,606 @@ +/** + * @vitest-environment node + */ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { readSSEStream } from '@/lib/core/utils/sse' +import { clearLargeValueCacheForTests } from '@/lib/execution/payloads/cache' +import { createStreamingResponse } from '@/lib/workflows/streaming/streaming' + +const { mockDownloadFile } = vi.hoisted(() => ({ + mockDownloadFile: vi.fn(), +})) + +vi.mock('@/lib/uploads', () => ({ + StorageService: { + downloadFile: mockDownloadFile, + }, +})) + +const manifestChunk = [{ id: 1 }] +const manifestChunkBytes = Buffer.byteLength(JSON.stringify(manifestChunk), 'utf8') +const manifest = { + __simLargeArrayManifest: true, + version: 2, + kind: 'array', + totalCount: 1, + chunkCount: 1, + byteSize: manifestChunkBytes, + chunks: [ + { + ref: { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: manifestChunkBytes, + key: 'execution/workspace-1/workflow-1/execution-1/large-value-lv_ABCDEFGHIJKL.json', + executionId: 'execution-1', + }, + count: 1, + byteSize: manifestChunkBytes, + }, + ], + preview: [{ id: 1 }], +} + +async function collectSSEEvents( + stream: ReadableStream +): Promise[]> { + const reader = stream.getReader() + const decoder = new TextDecoder() + const events: Record[] = [] + let buffer = '' + + try { + while (true) { + const { done, value } = await reader.read() + if (done) { + buffer += decoder.decode() + break + } + buffer += decoder.decode(value, { stream: true }) + } + } finally { + reader.releaseLock() + } + + for (const chunk of buffer.split('\n\n')) { + if (!chunk.startsWith('data: ')) { + continue + } + const payload = chunk.substring(6) + if (payload === '[DONE]') { + continue + } + const event = JSON.parse(payload) as unknown + if (event === '[DONE]') { + continue + } + events.push(event as Record) + } + + return events +} + +describe('createStreamingResponse', () => { + beforeEach(() => { + vi.clearAllMocks() + clearLargeValueCacheForTests() + }) + + it('extracts block-level selected outputs from JSON content payloads', async () => { + const output = { content: JSON.stringify({ answer: 'ok' }) } + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + streamConfig: { + selectedOutputs: ['block'], + includeFileBase64: false, + }, + executeFn: async ({ onBlockComplete }) => { + await onBlockComplete('block', output) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + await expect(readSSEStream(stream)).resolves.toBe(JSON.stringify({ answer: 'ok' }, null, 2)) + }) + + it('extracts selected outputs from JSON content payloads', async () => { + const output = { content: JSON.stringify({ answer: 'ok' }) } + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + streamConfig: { + selectedOutputs: ['block_answer'], + includeFileBase64: false, + }, + executeFn: async ({ onBlockComplete }) => { + await onBlockComplete('block', output) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + await expect(readSSEStream(stream)).resolves.toBe('ok') + }) + + it('auto-materializes whole manifest selected outputs under the inline cap', async () => { + mockDownloadFile.mockResolvedValue(Buffer.from(JSON.stringify(manifestChunk), 'utf8')) + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + streamConfig: { + selectedOutputs: ['block_issues'], + includeFileBase64: false, + }, + executeFn: async ({ onBlockComplete }) => { + const output = { issues: manifest } + await onBlockComplete('block', output) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + await expect(readSSEStream(stream)).resolves.toBe(JSON.stringify(manifestChunk, null, 2)) + }) + + it('auto-materializes whole-block selected outputs containing manifests', async () => { + mockDownloadFile.mockResolvedValue(Buffer.from(JSON.stringify(manifestChunk), 'utf8')) + const output = { issues: manifest } + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + streamConfig: { + selectedOutputs: ['block'], + includeFileBase64: true, + }, + executeFn: async ({ onBlockComplete }) => { + await onBlockComplete('block', output) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + await expect(readSSEStream(stream)).resolves.toBe( + JSON.stringify({ issues: manifestChunk }, null, 2) + ) + expect(mockDownloadFile).toHaveBeenCalled() + }) + + it('inlines materialized selected outputs without recompacting them into refs', async () => { + const largeString = 'x'.repeat(8 * 1024 * 1024 + 1) + const largeStringJson = JSON.stringify(largeString) + const ref = { + __simLargeValueRef: true, + version: 1, + id: 'lv_LARGESTRING1', + kind: 'string', + size: Buffer.byteLength(largeStringJson, 'utf8'), + key: 'execution/workspace-1/workflow-1/execution-1/large-value-lv_LARGESTRING1.json', + executionId: 'execution-1', + } + mockDownloadFile.mockResolvedValue(Buffer.from(largeStringJson, 'utf8')) + + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + streamConfig: { + selectedOutputs: ['block_text'], + includeFileBase64: false, + }, + executeFn: async ({ onBlockComplete }) => { + const output = { text: ref } + await onBlockComplete('block', output) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + const streamed = await readSSEStream(stream) + expect(streamed).toHaveLength(largeString.length) + expect(streamed).not.toContain('__simLargeValueRef') + }) + + it('deduplicates repeated equivalent selected outputs before streaming', async () => { + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + streamConfig: { + selectedOutputs: ['block_text', 'block.text', 'block_text'], + includeFileBase64: false, + }, + executeFn: async ({ onBlockComplete }) => { + const output = { text: 'ok' } + await onBlockComplete('block', output) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + const events = await collectSSEEvents(stream) + const chunkEvents = events.filter((event) => 'chunk' in event) + expect(chunkEvents).toHaveLength(1) + expect(chunkEvents[0]).toMatchObject({ blockId: 'block', chunk: 'ok' }) + }) + + it('fails when distinct selected outputs aggregate over the inline cap', async () => { + const largeString = 'x'.repeat(9 * 1024 * 1024) + const largeStringJson = JSON.stringify(largeString) + const largeStringBytes = Buffer.byteLength(largeStringJson, 'utf8') + const firstRef = { + __simLargeValueRef: true, + version: 1, + id: 'lv_MULTIREF0001', + kind: 'string', + size: largeStringBytes, + key: 'execution/workspace-1/workflow-1/execution-1/large-value-lv_MULTIREF0001.json', + executionId: 'execution-1', + } + const secondRef = { + __simLargeValueRef: true, + version: 1, + id: 'lv_MULTIREF0002', + kind: 'string', + size: largeStringBytes, + key: 'execution/workspace-1/workflow-1/execution-1/large-value-lv_MULTIREF0002.json', + executionId: 'execution-1', + } + mockDownloadFile.mockImplementation(async ({ key }) => { + if (key === firstRef.key || key === secondRef.key) { + return Buffer.from(largeStringJson, 'utf8') + } + throw new Error(`Unexpected key: ${key}`) + }) + + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + streamConfig: { + selectedOutputs: ['block_first', 'block_second'], + includeFileBase64: false, + }, + executeFn: async ({ onBlockComplete }) => { + const output = { first: firstRef, second: secondRef } + await onBlockComplete('block', output) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + const events = await collectSSEEvents(stream) + expect(events).toContainEqual({ + event: 'error', + blockId: 'block', + error: + 'Selected output is too large to inline; select a nested field or use pagination/preview.', + }) + expect(events.some((event) => event.event === 'final')).toBe(false) + }) + + it('accounts escaped string JSON bytes against the aggregate selected-output cap', async () => { + const first = '\\'.repeat(Math.floor((16 * 1024 * 1024 - 2) / 2)) + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + streamConfig: { + selectedOutputs: ['block_first', 'block_second'], + includeFileBase64: false, + }, + executeFn: async ({ onBlockComplete }) => { + const output = { first, second: 'ok' } + await onBlockComplete('block', output) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + const events = await collectSSEEvents(stream) + expect(events).toContainEqual({ + event: 'error', + blockId: 'block', + error: + 'Selected output is too large to inline; select a nested field or use pagination/preview.', + }) + expect(events.some((event) => event.event === 'final')).toBe(false) + }) + + it('fails when nested refs aggregate over the inline selected-output cap', async () => { + const largeString = 'x'.repeat(9 * 1024 * 1024) + const largeStringJson = JSON.stringify(largeString) + const largeStringBytes = Buffer.byteLength(largeStringJson, 'utf8') + const nestedRefA = { + __simLargeValueRef: true, + version: 1, + id: 'lv_NESTEDREF001', + kind: 'string', + size: largeStringBytes, + key: 'execution/workspace-1/workflow-1/execution-1/large-value-lv_NESTEDREF001.json', + executionId: 'execution-1', + } + const nestedRefB = { + __simLargeValueRef: true, + version: 1, + id: 'lv_NESTEDREF002', + kind: 'string', + size: largeStringBytes, + key: 'execution/workspace-1/workflow-1/execution-1/large-value-lv_NESTEDREF002.json', + executionId: 'execution-1', + } + const nestedChunk = [nestedRefA, nestedRefB] + const nestedChunkBytes = Buffer.byteLength(JSON.stringify(nestedChunk), 'utf8') + const nestedManifest = { + ...manifest, + totalCount: 2, + byteSize: nestedChunkBytes, + chunks: [ + { + ref: { + ...manifest.chunks[0].ref, + size: nestedChunkBytes, + }, + count: 2, + byteSize: nestedChunkBytes, + }, + ], + preview: [], + } + mockDownloadFile.mockImplementation(async ({ key }) => { + if (key === nestedManifest.chunks[0].ref.key) { + return Buffer.from(JSON.stringify(nestedChunk), 'utf8') + } + if (key === nestedRefA.key) { + return Buffer.from(largeStringJson, 'utf8') + } + if (key === nestedRefB.key) { + return Buffer.from(largeStringJson, 'utf8') + } + throw new Error(`Unexpected key: ${key}`) + }) + + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + streamConfig: { + selectedOutputs: ['block_issues'], + includeFileBase64: false, + }, + executeFn: async ({ onBlockComplete }) => { + const output = { issues: nestedManifest } + await onBlockComplete('block', output) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + const events = await collectSSEEvents(stream) + expect(events).toContainEqual({ + event: 'error', + blockId: 'block', + error: + 'Selected output is too large to inline; select a nested field or use pagination/preview.', + }) + expect(events.some((event) => event.event === 'final')).toBe(false) + expect(JSON.stringify(events)).not.toContain('__simLargeValueRef') + }) + + it('fails clearly instead of streaming raw manifest internals when selected output is over cap', async () => { + const oversizedManifest = { + ...manifest, + byteSize: 16 * 1024 * 1024 + 1, + chunks: [ + { + ...manifest.chunks[0], + ref: { + ...manifest.chunks[0].ref, + size: 16 * 1024 * 1024 + 1, + }, + byteSize: 16 * 1024 * 1024 + 1, + }, + ], + } + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + streamConfig: { + selectedOutputs: ['block_issues'], + includeFileBase64: false, + }, + executeFn: async ({ onBlockComplete }) => { + const output = { issues: oversizedManifest } + await onBlockComplete('block', output) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + const events = await collectSSEEvents(stream) + expect(events).toContainEqual({ + event: 'error', + blockId: 'block', + error: + 'Selected output is too large to inline; select a nested field or use pagination/preview.', + }) + expect(events.some((event) => event.event === 'final')).toBe(false) + expect(JSON.stringify(events)).not.toContain('__simLargeArrayManifest') + expect(mockDownloadFile).not.toHaveBeenCalled() + }) + + it('uses live large-value keys for selected-output materialization', async () => { + const largeValueKeys: string[] = [] + const ref = { + __simLargeValueRef: true, + version: 1, + id: 'lv_MNOPQRSTUVWX', + kind: 'object', + size: 15, + key: 'execution/workspace-1/workflow-1/source-execution/large-value-lv_MNOPQRSTUVWX.json', + executionId: 'source-execution', + } + mockDownloadFile.mockResolvedValue(Buffer.from(JSON.stringify({ nested: 'ok' }), 'utf8')) + + const stream = await createStreamingResponse({ + requestId: 'request-1', + executionId: 'execution-1', + workspaceId: 'workspace-1', + workflowId: 'workflow-1', + largeValueKeys, + streamConfig: { + selectedOutputs: ['block.value.nested'], + }, + executeFn: async ({ onBlockComplete }) => { + largeValueKeys.push(ref.key) + await onBlockComplete('block', { value: ref }) + return { + success: true, + output: {}, + logs: [ + { + blockId: 'block', + output: { value: ref }, + startedAt: new Date().toISOString(), + endedAt: new Date().toISOString(), + durationMs: 1, + success: true, + }, + ], + } as any + }, + }) + + await expect(readSSEStream(stream)).resolves.toBe('ok') + }) +}) diff --git a/apps/sim/lib/workflows/streaming/streaming.ts b/apps/sim/lib/workflows/streaming/streaming.ts index f33dd239471..c848854346f 100644 --- a/apps/sim/lib/workflows/streaming/streaming.ts +++ b/apps/sim/lib/workflows/streaming/streaming.ts @@ -4,10 +4,20 @@ import { createTimeoutAbortController, getTimeoutErrorMessage } from '@/lib/core import { extractBlockIdFromOutputId, extractPathFromOutputId, - traverseObjectPath, + parseOutputContentSafely, } from '@/lib/core/utils/response-format' import { encodeSSE } from '@/lib/core/utils/sse' +import { + getInlineJsonByteLength, + materializeInlineExecutionValue, +} from '@/lib/execution/payloads/inline-materialization.server' +import { + assertInlineMaterializationSize, + type ExecutionMaterializationContext, + MAX_INLINE_MATERIALIZATION_BYTES, +} from '@/lib/execution/payloads/materialization.server' import { compactExecutionPayload } from '@/lib/execution/payloads/serializer' +import { isExecutionResourceLimitError } from '@/lib/execution/resource-errors' import { buildTraceSpans } from '@/lib/logs/execution/trace-spans/trace-spans' import { processStreamingBlockLogs } from '@/lib/tokenization' import { @@ -15,6 +25,7 @@ import { hydrateUserFilesWithBase64, } from '@/lib/uploads/utils/user-file-base64.server' import type { BlockLog, ExecutionResult, StreamingExecution } from '@/executor/types' +import { navigatePathAsync } from '@/executor/variables/resolvers/reference-async.server' /** * Extended streaming execution type that includes blockId on the execution. @@ -27,6 +38,8 @@ interface StreamingExecutionWithBlockId extends Omit streamCompletionTimes: Map completedBlockIds: Set + selectedOutputBytes: number + streamedSelectedOutputKeys: Set + selectedOutputError?: string +} + +interface SelectedOutputDescriptor { + outputId: string + blockId: string + path: string + key: string } function resolveStreamedContent(state: StreamingState): Map { @@ -70,24 +95,115 @@ function resolveStreamedContent(state: StreamingState): Map { return result } -function extractOutputValue(output: unknown, path: string): unknown { - return traverseObjectPath(output, path) +type OutputExtractionContext = Pick< + StreamingResponseOptions, + | 'requestId' + | 'workspaceId' + | 'workflowId' + | 'executionId' + | 'largeValueExecutionIds' + | 'largeValueKeys' + | 'fileKeys' + | 'allowLargeValueWorkflowScope' + | 'userId' +> & { base64MaxBytes?: number } + +async function extractOutputValue( + output: unknown, + path: string, + context: OutputExtractionContext +): Promise { + const parsedOutput = parseOutputContentSafely(output) + const outputValue = path + ? await navigatePathAsync(parsedOutput, path.split('.'), { + executionContext: { + workflowId: context.workflowId ?? '', + workspaceId: context.workspaceId, + executionId: context.executionId, + largeValueExecutionIds: context.largeValueExecutionIds, + largeValueKeys: context.largeValueKeys, + fileKeys: context.fileKeys, + allowLargeValueWorkflowScope: context.allowLargeValueWorkflowScope, + userId: context.userId, + metadata: { requestId: context.requestId }, + base64MaxBytes: context.base64MaxBytes, + }, + allowLargeValueRefs: true, + }) + : parsedOutput + + return outputValue } function isDangerousKey(key: string): boolean { return DANGEROUS_KEYS.includes(key) } +function getSelectedOutputDescriptors( + selectedOutputs: string[] | undefined +): SelectedOutputDescriptor[] { + const descriptors: SelectedOutputDescriptor[] = [] + const seen = new Set() + for (const outputId of selectedOutputs ?? []) { + const blockId = extractBlockIdFromOutputId(outputId) + const path = extractPathFromOutputId(outputId, blockId) + const key = `${blockId}\u0000${path}` + if (seen.has(key)) { + continue + } + seen.add(key) + descriptors.push({ outputId, blockId, path, key }) + } + return descriptors +} + +function getSelectedOutputErrorMessage(error: unknown): string { + if (isExecutionResourceLimitError(error)) { + return SELECTED_OUTPUT_TOO_LARGE_MESSAGE + } + return getErrorMessage(error, 'Selected output could not be materialized') +} + +function buildMaterializationContext( + context: Omit +): ExecutionMaterializationContext { + return { + workspaceId: context.workspaceId, + workflowId: context.workflowId, + executionId: context.executionId, + largeValueExecutionIds: context.largeValueExecutionIds, + largeValueKeys: context.largeValueKeys, + fileKeys: context.fileKeys, + allowLargeValueWorkflowScope: context.allowLargeValueWorkflowScope, + userId: context.userId, + } +} + +function getRemainingSelectedOutputBytes(usedBytes: number): number { + return MAX_INLINE_MATERIALIZATION_BYTES - usedBytes +} + +function getBase64DecodedByteBudget(remainingJsonBytes: number): number { + return Math.max(0, Math.floor(((remainingJsonBytes - 2) * 3) / 4)) +} + +function assertSelectedOutputBytes(value: unknown): number { + const bytes = getInlineJsonByteLength(value) ?? 0 + assertInlineMaterializationSize(bytes, MAX_INLINE_MATERIALIZATION_BYTES) + return bytes +} + async function buildMinimalResult( result: ExecutionResult, selectedOutputs: string[] | undefined, streamedContent: Map, completedBlockIds: Set, + streamedSelectedOutputKeys: Set, requestId: string, includeFileBase64: boolean, base64MaxBytes: number | undefined, executionId?: string, - context: Pick = {} + context: Omit = { requestId } ): Promise<{ success: boolean; error?: string; output: Record }> { const durableContext = { workspaceId: context.workspaceId, @@ -125,13 +241,18 @@ async function buildMinimalResult( return minimalResult } - for (const outputId of selectedOutputs) { - const blockId = extractBlockIdFromOutputId(outputId) + let selectedOutputBytes = assertSelectedOutputBytes(minimalResult.output) + for (const descriptor of getSelectedOutputDescriptors(selectedOutputs)) { + const { blockId, path } = descriptor if (streamedContent.has(blockId)) { continue } + if (streamedSelectedOutputKeys.has(descriptor.key)) { + continue + } + if (!completedBlockIds.has(blockId)) { continue } @@ -141,7 +262,6 @@ async function buildMinimalResult( continue } - const path = extractPathFromOutputId(outputId, blockId) if (isDangerousKey(path)) { logger.warn(`[${requestId}] Blocked dangerous path: ${path}`) continue @@ -152,22 +272,33 @@ async function buildMinimalResult( continue } - const value = extractOutputValue(blockLog.output, path) + const remainingBytes = getRemainingSelectedOutputBytes(selectedOutputBytes) + const extractionContext = { + ...context, + executionId, + base64MaxBytes: Math.min( + base64MaxBytes ?? MAX_INLINE_MATERIALIZATION_BYTES, + getBase64DecodedByteBudget(remainingBytes) + ), + } + const value = await extractOutputValue(blockLog.output, path, extractionContext) if (value === undefined) { continue } + const materializedValue = await materializeInlineExecutionValue( + value, + buildMaterializationContext(extractionContext), + { maxBytes: remainingBytes } + ) if (!minimalResult.output[blockId]) { minimalResult.output[blockId] = Object.create(null) as Record } - ;(minimalResult.output[blockId] as Record)[path] = value + ;(minimalResult.output[blockId] as Record)[path] = materializedValue + selectedOutputBytes = assertSelectedOutputBytes(minimalResult.output) } - return compactExecutionPayload(minimalResult, { - ...durableContext, - preserveUserFileBase64: includeFileBase64, - preserveRoot: true, - }) + return minimalResult } function updateLogsWithStreamedContent( @@ -236,11 +367,26 @@ export async function createStreamingResponse( processedOutputs: new Set(), streamCompletionTimes: new Map(), completedBlockIds: new Set(), + selectedOutputBytes: 0, + streamedSelectedOutputKeys: new Set(), } - const sendChunk = (blockId: string, content: string) => { + const sendChunk = ( + blockId: string, + content: string, + options: { selectedOutputKey?: string; selectedOutputBytes?: number } = {} + ) => { const separator = state.processedOutputs.size > 0 ? '\n\n' : '' - controller.enqueue(encodeSSE({ blockId, chunk: separator + content })) + const chunk = separator + content + if (options.selectedOutputKey) { + const selectedOutputBytes = + options.selectedOutputBytes ?? Buffer.byteLength(chunk, 'utf8') + const nextSelectedOutputBytes = state.selectedOutputBytes + selectedOutputBytes + assertInlineMaterializationSize(nextSelectedOutputBytes, MAX_INLINE_MATERIALIZATION_BYTES) + state.selectedOutputBytes = nextSelectedOutputBytes + state.streamedSelectedOutputKeys.add(options.selectedOutputKey) + } + controller.enqueue(encodeSSE({ blockId, chunk })) state.processedOutputs.add(blockId) } @@ -305,36 +451,84 @@ export async function createStreamingResponse( return } - const matchingOutputs = streamConfig.selectedOutputs.filter( - (outputId) => extractBlockIdFromOutputId(outputId) === blockId + const matchingOutputs = getSelectedOutputDescriptors(streamConfig.selectedOutputs).filter( + (descriptor) => descriptor.blockId === blockId ) - for (const outputId of matchingOutputs) { - const path = extractPathFromOutputId(outputId, blockId) - const outputValue = extractOutputValue(output, path) - - if (outputValue !== undefined) { - const hydratedOutput = includeFileBase64 - ? await hydrateUserFilesWithBase64(outputValue, { - requestId, - workspaceId: options.workspaceId, - workflowId: options.workflowId, - executionId, - largeValueExecutionIds: options.largeValueExecutionIds, - allowLargeValueWorkflowScope: options.allowLargeValueWorkflowScope, - userId: options.userId, - maxBytes: base64MaxBytes, - }) - : outputValue - const compactHydratedOutput = await compactExecutionPayload(hydratedOutput, { - ...durableContext, - preserveUserFileBase64: includeFileBase64, + for (const descriptor of matchingOutputs) { + if (state.selectedOutputError) { + break + } + try { + const remainingBytes = getRemainingSelectedOutputBytes(state.selectedOutputBytes) + const extractionContext = { + requestId, + workspaceId: options.workspaceId, + workflowId: options.workflowId, + executionId, + largeValueExecutionIds: options.largeValueExecutionIds, + largeValueKeys: options.largeValueKeys, + fileKeys: options.fileKeys, + allowLargeValueWorkflowScope: options.allowLargeValueWorkflowScope, + userId: options.userId, + base64MaxBytes: Math.min( + base64MaxBytes ?? MAX_INLINE_MATERIALIZATION_BYTES, + getBase64DecodedByteBudget(remainingBytes) + ), + } + const materializationContext = buildMaterializationContext(extractionContext) + const outputValue = await extractOutputValue(output, descriptor.path, extractionContext) + + if (outputValue !== undefined) { + const materializedOutput = await materializeInlineExecutionValue( + outputValue, + materializationContext, + { maxBytes: remainingBytes } + ) + const shouldHydrateOutput = includeFileBase64 + const hydratedOutput = shouldHydrateOutput + ? await hydrateUserFilesWithBase64(materializedOutput, { + requestId, + ...materializationContext, + maxBytes: Math.min( + base64MaxBytes ?? MAX_INLINE_MATERIALIZATION_BYTES, + getBase64DecodedByteBudget(remainingBytes) + ), + preserveLargeValueMetadata: true, + }) + : materializedOutput + await materializeInlineExecutionValue(hydratedOutput, materializationContext, { + maxBytes: getRemainingSelectedOutputBytes(state.selectedOutputBytes), + }) + const formattedOutput = + typeof hydratedOutput === 'string' + ? hydratedOutput + : JSON.stringify(hydratedOutput, null, 2) + const selectedOutputBytes = Math.max( + getInlineJsonByteLength(hydratedOutput) ?? 0, + Buffer.byteLength(formattedOutput, 'utf8') + ) + sendChunk(blockId, formattedOutput, { + selectedOutputKey: descriptor.key, + selectedOutputBytes, + }) + } + } catch (error) { + logger.warn(`[${requestId}] Failed to materialize selected output`, { + blockId, + outputId: descriptor.outputId, + error, }) - const formattedOutput = - typeof compactHydratedOutput === 'string' - ? compactHydratedOutput - : JSON.stringify(compactHydratedOutput, null, 2) - sendChunk(blockId, formattedOutput) + const errorMessage = getSelectedOutputErrorMessage(error) + state.selectedOutputError ??= errorMessage + controller.enqueue( + encodeSSE({ + event: 'error', + blockId, + error: errorMessage, + }) + ) + break } } } @@ -374,31 +568,39 @@ export async function createStreamingResponse( } else { await completeLoggingSession(result) - const minimalResult = await buildMinimalResult( - result, - streamConfig.selectedOutputs, - streamedContent, - state.completedBlockIds, - requestId, - streamConfig.includeFileBase64 ?? true, - streamConfig.base64MaxBytes, - executionId, - { - workspaceId: options.workspaceId, - workflowId: options.workflowId, - userId: options.userId, - } - ) - - controller.enqueue( - encodeSSE({ - event: 'final', - data: { - ...minimalResult, - ...(result.status === 'paused' && { status: 'paused' }), - }, - }) - ) + if (!state.selectedOutputError) { + const minimalResult = await buildMinimalResult( + result, + streamConfig.selectedOutputs, + streamedContent, + state.completedBlockIds, + state.streamedSelectedOutputKeys, + requestId, + streamConfig.includeFileBase64 ?? true, + streamConfig.base64MaxBytes, + executionId, + { + requestId, + workspaceId: options.workspaceId, + workflowId: options.workflowId, + largeValueExecutionIds: options.largeValueExecutionIds, + largeValueKeys: result.metadata?.largeValueKeys ?? options.largeValueKeys, + fileKeys: result.metadata?.fileKeys ?? options.fileKeys, + allowLargeValueWorkflowScope: options.allowLargeValueWorkflowScope, + userId: options.userId, + } + ) + + controller.enqueue( + encodeSSE({ + event: 'final', + data: { + ...minimalResult, + ...(result.status === 'paused' && { status: 'paused' }), + }, + }) + ) + } } controller.enqueue(encodeSSE('[DONE]')) @@ -408,11 +610,13 @@ export async function createStreamingResponse( } controller.close() - } catch (error: any) { + } catch (error) { logger.error(`[${requestId}] Stream error:`, error) - controller.enqueue( - encodeSSE({ event: 'error', error: error.message || 'Stream processing error' }) - ) + const errorMessage = + streamConfig.selectedOutputs?.length && isExecutionResourceLimitError(error) + ? SELECTED_OUTPUT_TOO_LARGE_MESSAGE + : getErrorMessage(error, 'Stream processing error') + controller.enqueue(encodeSSE({ event: 'error', error: errorMessage })) if (executionId) { await cleanupExecutionBase64Cache(executionId) diff --git a/apps/sim/lib/workflows/utils.test.ts b/apps/sim/lib/workflows/utils.test.ts index 5f630f39e65..1af508d898b 100644 --- a/apps/sim/lib/workflows/utils.test.ts +++ b/apps/sim/lib/workflows/utils.test.ts @@ -27,7 +27,7 @@ vi.mock('@sim/workflow-authz', () => ({ assertActiveWorkflowContext: vi.fn(), })) -import { validateWorkflowPermissions } from '@/lib/workflows/utils' +import { createHttpResponseFromBlock, validateWorkflowPermissions } from '@/lib/workflows/utils' const mockSession = createSession({ userId: 'user-1', email: 'user1@test.com' }) const mockWorkflow = createWorkflowRecord({ @@ -36,6 +36,15 @@ const mockWorkflow = createWorkflowRecord({ workspaceId: 'ws-1', }) +const largeValueRef = { + __simLargeValueRef: true, + version: 1, + id: 'lv_ABCDEFGHIJKL', + kind: 'array', + size: 12 * 1024 * 1024, + executionId: 'execution-1', +} + const allowed = (workspacePermission: 'read' | 'write' | 'admin') => ({ allowed: true, status: 200, @@ -231,3 +240,27 @@ describe('validateWorkflowPermissions', () => { }) }) }) + +describe('createHttpResponseFromBlock', () => { + it('rejects large refs that cannot be materialized for HTTP response output', async () => { + await expect( + createHttpResponseFromBlock({ + output: { + data: { issues: largeValueRef }, + status: 200, + }, + } as any) + ).rejects.toThrow('This execution value is too large to inline') + }) + + it('returns raw response data when no large execution values are present', async () => { + const response = await createHttpResponseFromBlock({ + output: { + data: { issues: [] }, + status: 200, + }, + } as any) + + await expect(response.json()).resolves.toEqual({ issues: [] }) + }) +}) diff --git a/apps/sim/lib/workflows/utils.ts b/apps/sim/lib/workflows/utils.ts index 30afa6d81d3..3b12ccde4d6 100644 --- a/apps/sim/lib/workflows/utils.ts +++ b/apps/sim/lib/workflows/utils.ts @@ -6,7 +6,8 @@ import { authorizeWorkflowByWorkspacePermission } from '@sim/workflow-authz' import { and, asc, eq, inArray, isNull, max, min, sql } from 'drizzle-orm' import { NextResponse } from 'next/server' import { getSession } from '@/lib/auth' -import { materializeLargeValueRefsSync } from '@/lib/execution/payloads/cache' +import { materializeInlineExecutionValue } from '@/lib/execution/payloads/inline-materialization.server' +import type { ExecutionMaterializationContext } from '@/lib/execution/payloads/materialization.server' import { getNextWorkflowColor } from '@/lib/workflows/colors' import { buildDefaultWorkflowArtifacts } from '@/lib/workflows/defaults' import { saveWorkflowToNormalizedTables } from '@/lib/workflows/persistence/utils' @@ -316,11 +317,12 @@ export const workflowHasResponseBlock = ( return responseBlock !== undefined } -export const createHttpResponseFromBlock = ( - executionResult: Pick -): NextResponse => { +export const createHttpResponseFromBlock = async ( + executionResult: Pick, + context?: ExecutionMaterializationContext +): Promise => { const { data = {}, status = 200, headers = {} } = executionResult.output - const responseData = materializeLargeValueRefsSync(data) + const responseData = await materializeInlineExecutionValue(data, context) const responseHeaders = new Headers({ 'Content-Type': 'application/json', diff --git a/apps/sim/stores/terminal/console/store.test.ts b/apps/sim/stores/terminal/console/store.test.ts index 00b2b3bb3cc..baabbbf790a 100644 --- a/apps/sim/stores/terminal/console/store.test.ts +++ b/apps/sim/stores/terminal/console/store.test.ts @@ -5,7 +5,9 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' vi.unmock('@/stores/terminal') vi.unmock('@/stores/terminal/console/store') +vi.unmock('@/stores/notifications') +import { useNotificationStore } from '@/stores/notifications' import { useTerminalConsoleStore } from '@/stores/terminal/console/store' describe('terminal console store', () => { @@ -17,6 +19,9 @@ describe('terminal console store', () => { isOpen: false, _hasHydrated: true, }) + useNotificationStore.setState({ + notifications: [], + }) }) it('normalizes oversized payloads when adding console entries', () => { @@ -117,6 +122,37 @@ describe('terminal console store', () => { expect(after.getWorkflowEntries('wf-1')[0].output).toMatchObject({ status: 'updated' }) }) + it('uses the block name from error updates in notifications', () => { + useTerminalConsoleStore.getState().addConsole({ + workflowId: 'wf-1', + blockId: 'block-1', + blockName: 'Unknown Block', + blockType: 'function', + executionId: 'exec-1', + executionOrder: 1, + isRunning: true, + }) + + useTerminalConsoleStore.getState().updateConsole( + 'block-1', + { + blockName: 'Transform Data', + blockType: 'function', + executionOrder: 1, + error: 'Boom', + success: false, + }, + 'exec-1' + ) + + const [entry] = useTerminalConsoleStore.getState().getWorkflowEntries('wf-1') + const [notification] = useNotificationStore.getState().notifications + + expect(entry.blockName).toBe('Transform Data') + expect(notification.message).toBe('Transform Data: Boom') + expect(notification.action?.message).toContain('Error in Transform Data.') + }) + describe('cancelRunningEntries', () => { it('flips a plain running entry to canceled', () => { useTerminalConsoleStore.getState().addConsole({ diff --git a/apps/sim/stores/terminal/console/store.ts b/apps/sim/stores/terminal/console/store.ts index 8f666420a75..f607c06ccaf 100644 --- a/apps/sim/stores/terminal/console/store.ts +++ b/apps/sim/stores/terminal/console/store.ts @@ -507,6 +507,14 @@ export const useTerminalConsoleStore = create()( : normalizeConsoleOutput(mergedOutput) } + if (update.blockName !== undefined) { + updatedEntry.blockName = update.blockName + } + + if (update.blockType !== undefined) { + updatedEntry.blockType = update.blockType + } + if (update.error !== undefined) { updatedEntry.error = normalizeConsoleError(update.error) } @@ -605,7 +613,7 @@ export const useTerminalConsoleStore = create()( .find((entry) => matchesEntryForUpdate(entry, blockId, executionId, update)) notifyBlockError({ error: update.error, - blockName: matchingEntry?.blockName || 'Unknown Block', + blockName: update.blockName || matchingEntry?.blockName || 'Unknown Block', workflowId: matchingEntry?.workflowId, logContext: { blockId }, }) diff --git a/apps/sim/stores/terminal/console/types.ts b/apps/sim/stores/terminal/console/types.ts index 09124547494..d7a0fdadf2c 100644 --- a/apps/sim/stores/terminal/console/types.ts +++ b/apps/sim/stores/terminal/console/types.ts @@ -38,6 +38,8 @@ export interface ConsoleUpdate { content?: string output?: Partial replaceOutput?: NormalizedBlockOutput + blockName?: string + blockType?: string executionOrder?: number error?: string | Error | null warning?: string diff --git a/apps/sim/tools/function/execute.ts b/apps/sim/tools/function/execute.ts index 6821131b30a..36360fb8de7 100644 --- a/apps/sim/tools/function/execute.ts +++ b/apps/sim/tools/function/execute.ts @@ -139,6 +139,8 @@ export const functionExecuteTool: ToolConfig // The structured output from the tool error?: string // Error message if success is false resources?: MothershipResource[] // Resources to auto-open/show in UI + largeValueKeys?: string[] + fileKeys?: string[] timing?: { startTime: string // ISO timestamp when the tool execution started endTime: string // ISO timestamp when the tool execution ended From 3930485dff8df920c006398f9df8972f0e5a4f0a Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 19 May 2026 11:19:44 -0700 Subject: [PATCH 02/13] feat(models): add gemini 3.5 flash (#4660) --- apps/sim/providers/models.ts | 39 +++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/apps/sim/providers/models.ts b/apps/sim/providers/models.ts index 53c212c4bc5..82497c87d04 100644 --- a/apps/sim/providers/models.ts +++ b/apps/sim/providers/models.ts @@ -1204,6 +1204,26 @@ export const PROVIDER_DEFINITIONS: Record = { icon: GeminiIcon, color: '#4285F4', models: [ + { + id: 'gemini-3.5-flash', + pricing: { + input: 1.5, + cachedInput: 0.15, + output: 9.0, + updatedAt: '2026-05-19', + }, + capabilities: { + temperature: { min: 0, max: 2 }, + thinking: { + levels: ['minimal', 'low', 'medium', 'high'], + default: 'medium', + }, + maxOutputTokens: 65536, + }, + contextWindow: 1048576, + releaseDate: '2026-05-19', + recommended: true, + }, { id: 'gemini-3.1-pro-preview', pricing: { @@ -1222,7 +1242,6 @@ export const PROVIDER_DEFINITIONS: Record = { }, contextWindow: 1048576, releaseDate: '2026-02-19', - recommended: true, }, { id: 'gemini-3.1-flash-lite-preview', @@ -1366,6 +1385,24 @@ export const PROVIDER_DEFINITIONS: Record = { toolUsageControl: true, }, models: [ + { + id: 'vertex/gemini-3.5-flash', + pricing: { + input: 1.5, + cachedInput: 0.15, + output: 9.0, + updatedAt: '2026-05-19', + }, + capabilities: { + temperature: { min: 0, max: 2 }, + thinking: { + levels: ['minimal', 'low', 'medium', 'high'], + default: 'medium', + }, + }, + contextWindow: 1048576, + releaseDate: '2026-05-19', + }, { id: 'vertex/gemini-3.1-pro-preview', pricing: { From ef14b2b580d27483c3f8b0fab74aae14763fb332 Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 19 May 2026 12:04:23 -0700 Subject: [PATCH 03/13] fix(security): remove localhost CORS origin, consolidate CORS in proxy (#4658) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(security): remove localhost CORS origin, consolidate CORS in proxy Move all /api/* CORS handling from next.config.ts to proxy.ts so the runtime can resolve allowed origin per-request instead of baking it at build time (which produced "Access-Control-Allow-Origin: http://localhost:3000" with credentials:true in production). - proxy.ts: per-route CORS policy table covering auth, MCP, form, and workflow execute endpoints; OPTIONS preflight short-circuit; Vary: Origin when origin is not '*'; form routes defer to route handler's addCorsHeaders to avoid double-setting - next.config.ts: drop all /api/* Access-Control-Allow-* headers; keep COEP/COOP/CSP - deployment.ts: addCorsHeaders sets Vary: Origin alongside reflected Allow-Origin - Dockerfile: drop NEXT_PUBLIC_APP_URL build placeholder (Zod has skipValidation:true; build path doesn't read it) - Remove 8 dead OPTIONS handlers and their preflight tests now that the proxy handles preflight uniformly * refactor(cors): consolidate API CORS into proxy as single source of truth Move CORS for /api/chat/* and /api/form/* into the proxy policy table with reflected-origin + credentials:false, and delete the per-route addCorsHeaders helper. Routes no longer set CORS headers — the proxy is the only writer. Co-Authored-By: Claude Opus 4.7 * refactor(cors): convert proxy CORS policy chain to a rule table + add tests Replace the if/else chain in resolveApiCorsPolicy with a CORS_RULES table so each route's policy lives in one place and is trivially scannable. Add proxy.test.ts covering each rule and the wildcard-with-credentials invariant. Co-Authored-By: Claude Opus 4.7 * fix(cors): scope embed CORS rule to /api/{chat,form}/[identifier] only The embed policy (reflected origin, credentials:false) was matching workspace-internal session-authed routes — /api/chat, /api/chat/manage/*, /api/chat/validate, and the form equivalents — which need the default credentialed policy. Tighten the matcher to the embed paths only and add tests covering the exclusion. Co-Authored-By: Claude Opus 4.7 * refactor(cors): replace embed-path regex with explicit segment check The regex form `^/api/(chat|form)/(?!manage|validate)[^/]+(/(otp|sso))?$` was opaque on review and would silently exclude any future identifier subroute outside the hard-coded (otp|sso) group from the embed policy. Replace it with an imperative segment check and a named EMBED_RESERVED_SEGMENTS Set, so the policy boundary is visible at the top of the function and adding a reserved subpath is a one-line diff. Add a test asserting that future identifier subroutes also get the embed policy. Co-Authored-By: Claude Opus 4.7 * fix(cors): allow PUT in embed CORS policy for OTP verification Both /api/chat/[identifier]/otp and /api/form/[identifier]/otp export PUT for OTP code verification. The embed policy advertised only GET/POST/OPTIONS, so cross-origin embed clients failed preflight on verify. Add PUT and assert it in the embed policy test. Co-Authored-By: Claude Opus 4.7 --------- Co-authored-by: Claude Opus 4.7 --- .../api/chat/[identifier]/otp/route.test.ts | 5 - .../app/api/chat/[identifier]/otp/route.ts | 77 +++------ .../app/api/chat/[identifier]/route.test.ts | 14 +- apps/sim/app/api/chat/[identifier]/route.ts | 81 +++------ .../app/api/chat/[identifier]/sso/route.ts | 13 +- apps/sim/app/api/chat/utils.test.ts | 3 - apps/sim/app/api/files/delete/route.test.ts | 10 +- apps/sim/app/api/files/delete/route.ts | 8 - .../app/api/files/presigned/batch/route.ts | 14 -- .../sim/app/api/files/presigned/route.test.ts | 14 +- apps/sim/app/api/files/presigned/route.ts | 14 -- apps/sim/app/api/files/upload/route.test.ts | 10 +- apps/sim/app/api/files/upload/route.ts | 10 +- apps/sim/app/api/files/utils.ts | 10 -- .../api/form/[identifier]/otp/route.test.ts | 4 - .../app/api/form/[identifier]/otp/route.ts | 80 +++------ apps/sim/app/api/form/[identifier]/route.ts | 154 ++++++------------ apps/sim/app/api/form/utils.test.ts | 19 +-- apps/sim/app/api/mcp/copilot/route.ts | 13 -- .../api/templates/approved/sanitized/route.ts | 18 -- apps/sim/app/api/tools/image/route.ts | 12 -- apps/sim/lib/core/security/deployment.ts | 23 +-- apps/sim/next.config.ts | 87 +--------- apps/sim/proxy.test.ts | 145 +++++++++++++++++ apps/sim/proxy.ts | 148 +++++++++++++++++ docker/app.Dockerfile | 5 - 26 files changed, 441 insertions(+), 550 deletions(-) create mode 100644 apps/sim/proxy.test.ts diff --git a/apps/sim/app/api/chat/[identifier]/otp/route.test.ts b/apps/sim/app/api/chat/[identifier]/otp/route.test.ts index 547a164b069..a860df8eb28 100644 --- a/apps/sim/app/api/chat/[identifier]/otp/route.test.ts +++ b/apps/sim/app/api/chat/[identifier]/otp/route.test.ts @@ -26,7 +26,6 @@ const { mockDbUpdate, mockSendEmail, mockRenderOTPEmail, - mockAddCorsHeaders, mockSetChatAuthCookie, mockGetStorageMethod, mockZodParse, @@ -50,7 +49,6 @@ const { const mockDbUpdate = vi.fn() const mockSendEmail = vi.fn() const mockRenderOTPEmail = vi.fn() - const mockAddCorsHeaders = vi.fn() const mockSetChatAuthCookie = vi.fn() const mockGetStorageMethod = vi.fn() const mockZodParse = vi.fn() @@ -69,7 +67,6 @@ const { mockDbUpdate, mockSendEmail, mockRenderOTPEmail, - mockAddCorsHeaders, mockSetChatAuthCookie, mockGetStorageMethod, mockZodParse, @@ -131,7 +128,6 @@ vi.mock('@/components/emails', () => ({ })) vi.mock('@/lib/core/security/deployment', () => ({ - addCorsHeaders: mockAddCorsHeaders, isEmailAllowed: (email: string, allowedEmails: string[]) => { if (allowedEmails.includes(email)) return true const atIndex = email.indexOf('@') @@ -248,7 +244,6 @@ describe('Chat OTP API Route', () => { mockSendEmail.mockResolvedValue({ success: true }) mockRenderOTPEmail.mockResolvedValue('OTP Email') - mockAddCorsHeaders.mockImplementation((response: unknown) => response) mockCreateSuccessResponse.mockImplementation((data: unknown) => ({ json: () => Promise.resolve(data), status: 200, diff --git a/apps/sim/app/api/chat/[identifier]/otp/route.ts b/apps/sim/app/api/chat/[identifier]/otp/route.ts index fcccc003e86..aeb1b69f450 100644 --- a/apps/sim/app/api/chat/[identifier]/otp/route.ts +++ b/apps/sim/app/api/chat/[identifier]/otp/route.ts @@ -7,7 +7,7 @@ import { renderOTPEmail } from '@/components/emails' import { requestChatEmailOtpContract, verifyChatEmailOtpContract } from '@/lib/api/contracts/chats' import { getValidationErrorMessage, parseRequest } from '@/lib/api/server' import { RateLimiter } from '@/lib/core/rate-limiter' -import { addCorsHeaders, isEmailAllowed } from '@/lib/core/security/deployment' +import { isEmailAllowed } from '@/lib/core/security/deployment' import { decodeOTPValue, deleteOTP, @@ -47,15 +47,12 @@ export const POST = withRouteHandler( ) const response = createErrorResponse('Too many requests. Please try again later.', 429) response.headers.set('Retry-After', String(retryAfter)) - return addCorsHeaders(response, request) + return response } const parsed = await parseRequest(requestChatEmailOtpContract, request, context, { validationErrorResponse: (error) => - addCorsHeaders( - createErrorResponse(getValidationErrorMessage(error, 'Invalid request'), 400), - request - ), + createErrorResponse(getValidationErrorMessage(error, 'Invalid request'), 400), }) if (!parsed.success) return parsed.response const { email } = parsed.data.body @@ -75,16 +72,13 @@ export const POST = withRouteHandler( if (deploymentResult.length === 0) { logger.warn(`[${requestId}] Chat not found for identifier: ${identifier}`) - return addCorsHeaders(createErrorResponse('Chat not found', 404), request) + return createErrorResponse('Chat not found', 404) } const deployment = deploymentResult[0] if (deployment.authType !== 'email') { - return addCorsHeaders( - createErrorResponse('This chat does not use email authentication', 400), - request - ) + return createErrorResponse('This chat does not use email authentication', 400) } const allowedEmails: string[] = Array.isArray(deployment.allowedEmails) @@ -92,10 +86,7 @@ export const POST = withRouteHandler( : [] if (!isEmailAllowed(email, allowedEmails)) { - return addCorsHeaders( - createErrorResponse('Email not authorized for this chat', 403), - request - ) + return createErrorResponse('Email not authorized for this chat', 403) } const emailRateLimit = await rateLimiter.checkRateLimitDirect( @@ -114,7 +105,7 @@ export const POST = withRouteHandler( 429 ) response.headers.set('Retry-After', String(retryAfter)) - return addCorsHeaders(response, request) + return response } const otp = generateOTP() @@ -135,17 +126,14 @@ export const POST = withRouteHandler( if (!emailResult.success) { logger.error(`[${requestId}] Failed to send OTP email:`, emailResult.message) - return addCorsHeaders( - createErrorResponse('Failed to send verification email', 500), - request - ) + return createErrorResponse('Failed to send verification email', 500) } logger.info(`[${requestId}] OTP sent to ${email} for chat ${deployment.id}`) - return addCorsHeaders(createSuccessResponse({ message: 'Verification code sent' }), request) + return createSuccessResponse({ message: 'Verification code sent' }) } catch (error) { logger.error(`[${requestId}] Error processing OTP request:`, error) - return addCorsHeaders(createErrorResponse('Failed to process request', 500), request) + return createErrorResponse('Failed to process request', 500) } } ) @@ -158,10 +146,7 @@ export const PUT = withRouteHandler( try { const parsed = await parseRequest(verifyChatEmailOtpContract, request, context, { validationErrorResponse: (error) => - addCorsHeaders( - createErrorResponse(getValidationErrorMessage(error, 'Invalid request'), 400), - request - ), + createErrorResponse(getValidationErrorMessage(error, 'Invalid request'), 400), }) if (!parsed.success) return parsed.response const { email, otp } = parsed.data.body @@ -184,17 +169,14 @@ export const PUT = withRouteHandler( if (deploymentResult.length === 0) { logger.warn(`[${requestId}] Chat not found for identifier: ${identifier}`) - return addCorsHeaders(createErrorResponse('Chat not found', 404), request) + return createErrorResponse('Chat not found', 404) } const deployment = deploymentResult[0] const storedValue = await getOTP('chat', deployment.id, email) if (!storedValue) { - return addCorsHeaders( - createErrorResponse('No verification code found, request a new one', 400), - request - ) + return createErrorResponse('No verification code found, request a new one', 400) } const { otp: storedOTP, attempts } = decodeOTPValue(storedValue) @@ -202,43 +184,34 @@ export const PUT = withRouteHandler( if (attempts >= MAX_OTP_ATTEMPTS) { await deleteOTP('chat', deployment.id, email) logger.warn(`[${requestId}] OTP already locked out for ${email}`) - return addCorsHeaders( - createErrorResponse('Too many failed attempts. Please request a new code.', 429), - request - ) + return createErrorResponse('Too many failed attempts. Please request a new code.', 429) } if (storedOTP !== otp) { const result = await incrementOTPAttempts('chat', deployment.id, email, storedValue) if (result === 'locked') { logger.warn(`[${requestId}] OTP invalidated after max failed attempts for ${email}`) - return addCorsHeaders( - createErrorResponse('Too many failed attempts. Please request a new code.', 429), - request - ) + return createErrorResponse('Too many failed attempts. Please request a new code.', 429) } - return addCorsHeaders(createErrorResponse('Invalid verification code', 400), request) + return createErrorResponse('Invalid verification code', 400) } await deleteOTP('chat', deployment.id, email) - const response = addCorsHeaders( - createSuccessResponse({ - id: deployment.id, - title: deployment.title, - description: deployment.description, - customizations: deployment.customizations, - authType: deployment.authType, - outputConfigs: deployment.outputConfigs, - }), - request - ) + const response = createSuccessResponse({ + id: deployment.id, + title: deployment.title, + description: deployment.description, + customizations: deployment.customizations, + authType: deployment.authType, + outputConfigs: deployment.outputConfigs, + }) setChatAuthCookie(response, deployment.id, deployment.authType, deployment.password) return response } catch (error) { logger.error(`[${requestId}] Error verifying OTP:`, error) - return addCorsHeaders(createErrorResponse('Failed to process request', 500), request) + return createErrorResponse('Failed to process request', 500) } } ) diff --git a/apps/sim/app/api/chat/[identifier]/route.test.ts b/apps/sim/app/api/chat/[identifier]/route.test.ts index 426545aece0..b1b36d60b6d 100644 --- a/apps/sim/app/api/chat/[identifier]/route.test.ts +++ b/apps/sim/app/api/chat/[identifier]/route.test.ts @@ -63,13 +63,11 @@ const createMockStream = () => { }) } -const { mockAddCorsHeaders, mockValidateChatAuth, mockSetChatAuthCookie, mockValidateAuthToken } = - vi.hoisted(() => ({ - mockAddCorsHeaders: vi.fn().mockImplementation((response: Response) => response), - mockValidateChatAuth: vi.fn().mockResolvedValue({ authorized: true }), - mockSetChatAuthCookie: vi.fn(), - mockValidateAuthToken: vi.fn().mockReturnValue(false), - })) +const { mockValidateChatAuth, mockSetChatAuthCookie, mockValidateAuthToken } = vi.hoisted(() => ({ + mockValidateChatAuth: vi.fn().mockResolvedValue({ authorized: true }), + mockSetChatAuthCookie: vi.fn(), + mockValidateAuthToken: vi.fn().mockReturnValue(false), +})) const mockCreateErrorResponse = workflowsApiUtilsMockFns.mockCreateErrorResponse const mockCreateSuccessResponse = workflowsApiUtilsMockFns.mockCreateSuccessResponse @@ -81,7 +79,6 @@ vi.mock('@sim/db', () => ({ })) vi.mock('@/lib/core/security/deployment', () => ({ - addCorsHeaders: mockAddCorsHeaders, validateAuthToken: mockValidateAuthToken, setDeploymentAuthCookie: vi.fn(), isEmailAllowed: vi.fn().mockReturnValue(false), @@ -181,7 +178,6 @@ describe('Chat Identifier API Route', () => { }, }) - mockAddCorsHeaders.mockImplementation((response: Response) => response) mockValidateChatAuth.mockResolvedValue({ authorized: true }) mockValidateAuthToken.mockReturnValue(false) mockCreateErrorResponse.mockImplementation((message: string, status: number, code?: string) => { diff --git a/apps/sim/app/api/chat/[identifier]/route.ts b/apps/sim/app/api/chat/[identifier]/route.ts index f35d950a21c..7a4a12d5754 100644 --- a/apps/sim/app/api/chat/[identifier]/route.ts +++ b/apps/sim/app/api/chat/[identifier]/route.ts @@ -6,7 +6,7 @@ import { and, eq, isNull } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { deployedChatPostContract } from '@/lib/api/contracts/chats' import { parseRequest } from '@/lib/api/server' -import { addCorsHeaders, validateAuthToken } from '@/lib/core/security/deployment' +import { validateAuthToken } from '@/lib/core/security/deployment' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { preprocessExecution } from '@/lib/execution/preprocessing' @@ -49,13 +49,9 @@ export const POST = withRouteHandler( const parsed = await parseRequest(deployedChatPostContract, request, context, { validationErrorResponse: (err) => { const message = err.issues.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ') - return addCorsHeaders( - createErrorResponse(`Invalid request body: ${message}`, 400, 'VALIDATION_ERROR'), - request - ) + return createErrorResponse(`Invalid request body: ${message}`, 400, 'VALIDATION_ERROR') }, - invalidJsonResponse: () => - addCorsHeaders(createErrorResponse('Invalid request body', 400), request), + invalidJsonResponse: () => createErrorResponse('Invalid request body', 400), }) if (!parsed.success) return parsed.response const parsedBody = parsed.data.body @@ -80,7 +76,7 @@ export const POST = withRouteHandler( if (deploymentResult.length === 0) { logger.warn(`[${requestId}] Chat not found for identifier: ${identifier}`) - return addCorsHeaders(createErrorResponse('Chat not found', 404), request) + return createErrorResponse('Chat not found', 404) } const deployment = deploymentResult[0] @@ -99,10 +95,7 @@ export const POST = withRouteHandler( logger.warn( `[${requestId}] Cannot log: workflow ${deployment.workflowId} has no workspace` ) - return addCorsHeaders( - createErrorResponse('This chat is currently unavailable', 403), - request - ) + return createErrorResponse('This chat is currently unavailable', 403) } const executionId = generateId() @@ -127,27 +120,18 @@ export const POST = withRouteHandler( traceSpans: [], }) - return addCorsHeaders( - createErrorResponse('This chat is currently unavailable', 403), - request - ) + return createErrorResponse('This chat is currently unavailable', 403) } const authResult = await validateChatAuth(requestId, deployment, request, parsedBody) if (!authResult.authorized) { - return addCorsHeaders( - createErrorResponse(authResult.error || 'Authentication required', 401), - request - ) + return createErrorResponse(authResult.error || 'Authentication required', 401) } const { input, password, email, conversationId, files } = parsedBody if ((password || email) && !input) { - const response = addCorsHeaders( - createSuccessResponse(toChatConfigResponse(deployment)), - request - ) + const response = createSuccessResponse(toChatConfigResponse(deployment)) if (deployment.authType !== 'sso') { setChatAuthCookie(response, deployment.id, deployment.authType, deployment.password) @@ -157,7 +141,7 @@ export const POST = withRouteHandler( } if (!input && (!files || files.length === 0)) { - return addCorsHeaders(createErrorResponse('No input provided', 400), request) + return createErrorResponse('No input provided', 400) } const executionId = generateId() @@ -182,12 +166,9 @@ export const POST = withRouteHandler( if (!preprocessResult.success) { logger.warn(`[${requestId}] Preprocessing failed: ${preprocessResult.error?.message}`) - return addCorsHeaders( - createErrorResponse( - preprocessResult.error?.message || 'Failed to process request', - preprocessResult.error?.statusCode || 500 - ), - request + return createErrorResponse( + preprocessResult.error?.message || 'Failed to process request', + preprocessResult.error?.statusCode || 500 ) } @@ -196,10 +177,7 @@ export const POST = withRouteHandler( const workspaceId = workflowRecord?.workspaceId if (!workspaceId) { logger.error(`[${requestId}] Workflow ${deployment.workflowId} has no workspaceId`) - return addCorsHeaders( - createErrorResponse('Workflow has no associated workspace', 500), - request - ) + return createErrorResponse('Workflow has no associated workspace', 500) } try { @@ -302,20 +280,14 @@ export const POST = withRouteHandler( status: 200, headers: SSE_HEADERS, }) - return addCorsHeaders(streamResponse, request) + return streamResponse } catch (error: any) { logger.error(`[${requestId}] Error processing chat request:`, error) - return addCorsHeaders( - createErrorResponse(error.message || 'Failed to process request', 500), - request - ) + return createErrorResponse(error.message || 'Failed to process request', 500) } } catch (error: any) { logger.error(`[${requestId}] Error processing chat request:`, error) - return addCorsHeaders( - createErrorResponse(error.message || 'Failed to process request', 500), - request - ) + return createErrorResponse(error.message || 'Failed to process request', 500) } } ) @@ -345,17 +317,14 @@ export const GET = withRouteHandler( if (deploymentResult.length === 0) { logger.warn(`[${requestId}] Chat not found for identifier: ${identifier}`) - return addCorsHeaders(createErrorResponse('Chat not found', 404), request) + return createErrorResponse('Chat not found', 404) } const deployment = deploymentResult[0] if (!deployment.isActive) { logger.warn(`[${requestId}] Chat is not active: ${identifier}`) - return addCorsHeaders( - createErrorResponse('This chat is currently unavailable', 403), - request - ) + return createErrorResponse('This chat is currently unavailable', 403) } const cookieName = `chat_auth_${deployment.id}` @@ -367,7 +336,7 @@ export const GET = withRouteHandler( authCookie && validateAuthToken(authCookie.value, deployment.id, deployment.password) ) { - return addCorsHeaders(createSuccessResponse(toChatConfigResponse(deployment)), request) + return createSuccessResponse(toChatConfigResponse(deployment)) } const authResult = await validateChatAuth(requestId, deployment, request) @@ -375,19 +344,13 @@ export const GET = withRouteHandler( logger.info( `[${requestId}] Authentication required for chat: ${identifier}, type: ${deployment.authType}` ) - return addCorsHeaders( - createErrorResponse(authResult.error || 'Authentication required', 401), - request - ) + return createErrorResponse(authResult.error || 'Authentication required', 401) } - return addCorsHeaders(createSuccessResponse(toChatConfigResponse(deployment)), request) + return createSuccessResponse(toChatConfigResponse(deployment)) } catch (error: any) { logger.error(`[${requestId}] Error fetching chat info:`, error) - return addCorsHeaders( - createErrorResponse(error.message || 'Failed to fetch chat information', 500), - request - ) + return createErrorResponse(error.message || 'Failed to fetch chat information', 500) } } ) diff --git a/apps/sim/app/api/chat/[identifier]/sso/route.ts b/apps/sim/app/api/chat/[identifier]/sso/route.ts index c6878876a90..c6ab98cfe94 100644 --- a/apps/sim/app/api/chat/[identifier]/sso/route.ts +++ b/apps/sim/app/api/chat/[identifier]/sso/route.ts @@ -7,7 +7,7 @@ import { chatSSOContract } from '@/lib/api/contracts/chats' import { parseRequest } from '@/lib/api/server' import type { TokenBucketConfig } from '@/lib/core/rate-limiter' import { RateLimiter } from '@/lib/core/rate-limiter' -import { addCorsHeaders, isEmailAllowed } from '@/lib/core/security/deployment' +import { isEmailAllowed } from '@/lib/core/security/deployment' import { generateRequestId, getClientIp } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' @@ -41,7 +41,7 @@ export const POST = withRouteHandler( ) const response = createErrorResponse('Too many requests. Please try again later.', 429) response.headers.set('Retry-After', String(retryAfter)) - return addCorsHeaders(response, request) + return response } const parsed = await parseRequest(chatSSOContract, request, context) @@ -62,18 +62,15 @@ export const POST = withRouteHandler( if (!deployment || !deployment.isActive) { logger.warn(`[${requestId}] SSO check on missing/inactive chat: ${identifier}`) - return addCorsHeaders(createErrorResponse('Chat not found', 404), request) + return createErrorResponse('Chat not found', 404) } if (deployment.authType !== 'sso') { - return addCorsHeaders( - createErrorResponse('Chat is not configured for SSO authentication', 400), - request - ) + return createErrorResponse('Chat is not configured for SSO authentication', 400) } const eligible = isEmailAllowed(email, (deployment.allowedEmails as string[]) || []) - return addCorsHeaders(createSuccessResponse({ eligible }), request) + return createSuccessResponse({ eligible }) } ) diff --git a/apps/sim/app/api/chat/utils.test.ts b/apps/sim/app/api/chat/utils.test.ts index 60395c0bbd1..86e46340a92 100644 --- a/apps/sim/app/api/chat/utils.test.ts +++ b/apps/sim/app/api/chat/utils.test.ts @@ -17,7 +17,6 @@ const { mockMergeSubBlockValues, mockValidateAuthToken, mockSetDeploymentAuthCookie, - mockAddCorsHeaders, mockIsEmailAllowed, mockGetSession, } = vi.hoisted(() => ({ @@ -25,7 +24,6 @@ const { mockMergeSubBlockValues: vi.fn().mockReturnValue({}), mockValidateAuthToken: vi.fn().mockReturnValue(false), mockSetDeploymentAuthCookie: vi.fn(), - mockAddCorsHeaders: vi.fn((response: unknown) => response), mockIsEmailAllowed: vi.fn(), mockGetSession: vi.fn(), })) @@ -57,7 +55,6 @@ vi.mock('@/lib/core/security/encryption', () => encryptionMock) vi.mock('@/lib/core/security/deployment', () => ({ validateAuthToken: mockValidateAuthToken, setDeploymentAuthCookie: mockSetDeploymentAuthCookie, - addCorsHeaders: mockAddCorsHeaders, isEmailAllowed: mockIsEmailAllowed, })) diff --git a/apps/sim/app/api/files/delete/route.test.ts b/apps/sim/app/api/files/delete/route.test.ts index df3bad6170f..eed07748581 100644 --- a/apps/sim/app/api/files/delete/route.test.ts +++ b/apps/sim/app/api/files/delete/route.test.ts @@ -91,7 +91,7 @@ vi.mock('fs/promises', () => ({ })) import { createMockRequest } from '@sim/testing' -import { OPTIONS, POST } from '@/app/api/files/delete/route' +import { POST } from '@/app/api/files/delete/route' describe('File Delete API Route', () => { beforeEach(() => { @@ -198,12 +198,4 @@ describe('File Delete API Route', () => { expect(data).toHaveProperty('error', 'InvalidRequestError') expect(data).toHaveProperty('message', 'No file path provided') }) - - it('should handle CORS preflight requests', async () => { - const response = await OPTIONS() - - expect(response.status).toBe(204) - expect(response.headers.get('Access-Control-Allow-Methods')).toBe('GET, POST, DELETE, OPTIONS') - expect(response.headers.get('Access-Control-Allow-Headers')).toBe('Content-Type') - }) }) diff --git a/apps/sim/app/api/files/delete/route.ts b/apps/sim/app/api/files/delete/route.ts index 8e0bbb7ec5b..4eeeb538747 100644 --- a/apps/sim/app/api/files/delete/route.ts +++ b/apps/sim/app/api/files/delete/route.ts @@ -12,7 +12,6 @@ import { extractStorageKey, inferContextFromKey } from '@/lib/uploads/utils/file import { verifyFileAccess } from '@/app/api/files/authorization' import { createErrorResponse, - createOptionsResponse, createSuccessResponse, extractFilename, FileNotFoundError, @@ -119,10 +118,3 @@ function extractStorageKeyFromPath(filePath: string): string { return extractFilename(filePath) } - -/** - * Handle CORS preflight requests - */ -export const OPTIONS = withRouteHandler(async () => { - return createOptionsResponse() -}) diff --git a/apps/sim/app/api/files/presigned/batch/route.ts b/apps/sim/app/api/files/presigned/batch/route.ts index 014a7d4cfd7..ac5015c9a7d 100644 --- a/apps/sim/app/api/files/presigned/batch/route.ts +++ b/apps/sim/app/api/files/presigned/batch/route.ts @@ -156,17 +156,3 @@ export const POST = withRouteHandler(async (request: NextRequest) => { ) } }) - -export const OPTIONS = withRouteHandler(async () => { - return NextResponse.json( - {}, - { - status: 200, - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'POST, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - } - ) -}) diff --git a/apps/sim/app/api/files/presigned/route.test.ts b/apps/sim/app/api/files/presigned/route.test.ts index 724aab5d065..9abfa5be2d4 100644 --- a/apps/sim/app/api/files/presigned/route.test.ts +++ b/apps/sim/app/api/files/presigned/route.test.ts @@ -107,7 +107,7 @@ vi.mock('@/lib/uploads', () => ({ isUsingCloudStorage: mockIsUsingCloudStorageUploads, })) -import { OPTIONS, POST } from '@/app/api/files/presigned/route' +import { POST } from '@/app/api/files/presigned/route' const defaultMockUser = { id: 'test-user-id', @@ -827,16 +827,4 @@ describe('/api/files/presigned', () => { expect(mockValidateAttachmentFileType).not.toHaveBeenCalled() }) }) - - describe('OPTIONS', () => { - it('should handle CORS preflight requests', async () => { - const response = await OPTIONS() - - expect(response.status).toBe(200) - expect(response.headers.get('Access-Control-Allow-Methods')).toBe('POST, OPTIONS') - expect(response.headers.get('Access-Control-Allow-Headers')).toBe( - 'Content-Type, Authorization' - ) - }) - }) }) diff --git a/apps/sim/app/api/files/presigned/route.ts b/apps/sim/app/api/files/presigned/route.ts index 7484712978c..3312434f04d 100644 --- a/apps/sim/app/api/files/presigned/route.ts +++ b/apps/sim/app/api/files/presigned/route.ts @@ -310,17 +310,3 @@ export const POST = withRouteHandler(async (request: NextRequest) => { ) } }) - -export const OPTIONS = withRouteHandler(async () => { - return NextResponse.json( - {}, - { - status: 200, - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'POST, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - } - ) -}) diff --git a/apps/sim/app/api/files/upload/route.test.ts b/apps/sim/app/api/files/upload/route.test.ts index f0ef4ede98b..cf80cbf9b0d 100644 --- a/apps/sim/app/api/files/upload/route.test.ts +++ b/apps/sim/app/api/files/upload/route.test.ts @@ -95,7 +95,7 @@ vi.mock('@/lib/uploads/setup.server', () => ({ })) import { uploadWorkspaceFile } from '@/lib/uploads/contexts/workspace' -import { OPTIONS, POST } from '@/app/api/files/upload/route' +import { POST } from '@/app/api/files/upload/route' /** * Configure mocks for authenticated file upload tests @@ -307,14 +307,6 @@ describe('File Upload API Route', () => { expect(data).toHaveProperty('error') expect(typeof data.error).toBe('string') }) - - it('should handle CORS preflight requests', async () => { - const response = await OPTIONS() - - expect(response.status).toBe(204) - expect(response.headers.get('Access-Control-Allow-Methods')).toBe('GET, POST, DELETE, OPTIONS') - expect(response.headers.get('Access-Control-Allow-Headers')).toBe('Content-Type') - }) }) describe('File Upload Security Tests', () => { diff --git a/apps/sim/app/api/files/upload/route.ts b/apps/sim/app/api/files/upload/route.ts index 2bdd3c81d18..e1dc599cad7 100644 --- a/apps/sim/app/api/files/upload/route.ts +++ b/apps/sim/app/api/files/upload/route.ts @@ -21,11 +21,7 @@ import { validateFileType, } from '@/lib/uploads/utils/validation' import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' -import { - createErrorResponse, - createOptionsResponse, - InvalidRequestError, -} from '@/app/api/files/utils' +import { createErrorResponse, InvalidRequestError } from '@/app/api/files/utils' const ALLOWED_EXTENSIONS = new Set(SUPPORTED_ATTACHMENT_EXTENSIONS) @@ -430,7 +426,3 @@ export const POST = withRouteHandler(async (request: NextRequest) => { return createErrorResponse(error instanceof Error ? error : new Error('File upload failed')) } }) - -export const OPTIONS = withRouteHandler(async () => { - return createOptionsResponse() -}) diff --git a/apps/sim/app/api/files/utils.ts b/apps/sim/app/api/files/utils.ts index ac759b45bcc..b6b05f4cbb6 100644 --- a/apps/sim/app/api/files/utils.ts +++ b/apps/sim/app/api/files/utils.ts @@ -238,13 +238,3 @@ export function createErrorResponse(error: Error, status = 500): NextResponse { export function createSuccessResponse(data: ApiSuccessResponse): NextResponse { return NextResponse.json(data) } - -export function createOptionsResponse(): NextResponse { - return new NextResponse(null, { - status: 204, - headers: { - 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type', - }, - }) -} diff --git a/apps/sim/app/api/form/[identifier]/otp/route.test.ts b/apps/sim/app/api/form/[identifier]/otp/route.test.ts index 4b3b13441d0..5a0a9eb1033 100644 --- a/apps/sim/app/api/form/[identifier]/otp/route.test.ts +++ b/apps/sim/app/api/form/[identifier]/otp/route.test.ts @@ -26,7 +26,6 @@ const { mockDbUpdate, mockSendEmail, mockRenderOTPEmail, - mockAddCorsHeaders, mockSetFormAuthCookie, mockGetStorageMethod, mockZodParse, @@ -57,7 +56,6 @@ const { mockDbUpdate: vi.fn(), mockSendEmail: vi.fn(), mockRenderOTPEmail: vi.fn(), - mockAddCorsHeaders: vi.fn(), mockSetFormAuthCookie: vi.fn(), mockGetStorageMethod: vi.fn(), mockZodParse: vi.fn(), @@ -119,7 +117,6 @@ vi.mock('@/components/emails', () => ({ })) vi.mock('@/lib/core/security/deployment', () => ({ - addCorsHeaders: mockAddCorsHeaders, isEmailAllowed: (email: string, allowedEmails: string[]) => { if (allowedEmails.includes(email)) return true const atIndex = email.indexOf('@') @@ -253,7 +250,6 @@ describe('Form OTP API Route', () => { mockSendEmail.mockResolvedValue({ success: true }) mockRenderOTPEmail.mockResolvedValue('OTP Email') - mockAddCorsHeaders.mockImplementation((response: unknown) => response) mockCreateSuccessResponse.mockImplementation((data: unknown) => ({ json: () => Promise.resolve(data), status: 200, diff --git a/apps/sim/app/api/form/[identifier]/otp/route.ts b/apps/sim/app/api/form/[identifier]/otp/route.ts index 0d9804efa55..55f3f493ca0 100644 --- a/apps/sim/app/api/form/[identifier]/otp/route.ts +++ b/apps/sim/app/api/form/[identifier]/otp/route.ts @@ -7,7 +7,7 @@ import { renderOTPEmail } from '@/components/emails' import { requestFormEmailOtpContract, verifyFormEmailOtpContract } from '@/lib/api/contracts/forms' import { getValidationErrorMessage, parseRequest } from '@/lib/api/server' import { RateLimiter } from '@/lib/core/rate-limiter' -import { addCorsHeaders, isEmailAllowed } from '@/lib/core/security/deployment' +import { isEmailAllowed } from '@/lib/core/security/deployment' import { decodeOTPValue, deleteOTP, @@ -47,15 +47,12 @@ export const POST = withRouteHandler( ) const response = createErrorResponse('Too many requests. Please try again later.', 429) response.headers.set('Retry-After', String(retryAfter)) - return addCorsHeaders(response, request) + return response } const parsed = await parseRequest(requestFormEmailOtpContract, request, context, { validationErrorResponse: (error) => - addCorsHeaders( - createErrorResponse(getValidationErrorMessage(error, 'Invalid request'), 400), - request - ), + createErrorResponse(getValidationErrorMessage(error, 'Invalid request'), 400), }) if (!parsed.success) return parsed.response const { email } = parsed.data.body @@ -74,23 +71,17 @@ export const POST = withRouteHandler( if (deploymentResult.length === 0) { logger.warn(`[${requestId}] Form not found for identifier: ${identifier}`) - return addCorsHeaders(createErrorResponse('Form not found', 404), request) + return createErrorResponse('Form not found', 404) } const deployment = deploymentResult[0] if (!deployment.isActive) { - return addCorsHeaders( - createErrorResponse('This form is currently unavailable', 403), - request - ) + return createErrorResponse('This form is currently unavailable', 403) } if (deployment.authType !== 'email') { - return addCorsHeaders( - createErrorResponse('This form does not use email authentication', 400), - request - ) + return createErrorResponse('This form does not use email authentication', 400) } const allowedEmails: string[] = Array.isArray(deployment.allowedEmails) @@ -98,10 +89,7 @@ export const POST = withRouteHandler( : [] if (!isEmailAllowed(email, allowedEmails)) { - return addCorsHeaders( - createErrorResponse('Email not authorized for this form', 403), - request - ) + return createErrorResponse('Email not authorized for this form', 403) } const emailRateLimit = await rateLimiter.checkRateLimitDirect( @@ -120,7 +108,7 @@ export const POST = withRouteHandler( 429 ) response.headers.set('Retry-After', String(retryAfter)) - return addCorsHeaders(response, request) + return response } const otp = generateOTP() @@ -141,17 +129,14 @@ export const POST = withRouteHandler( if (!emailResult.success) { logger.error(`[${requestId}] Failed to send OTP email:`, emailResult.message) - return addCorsHeaders( - createErrorResponse('Failed to send verification email', 500), - request - ) + return createErrorResponse('Failed to send verification email', 500) } logger.info(`[${requestId}] OTP sent to ${email} for form ${deployment.id}`) - return addCorsHeaders(createSuccessResponse({ message: 'Verification code sent' }), request) + return createSuccessResponse({ message: 'Verification code sent' }) } catch (error) { logger.error(`[${requestId}] Error processing OTP request:`, error) - return addCorsHeaders(createErrorResponse('Failed to process request', 500), request) + return createErrorResponse('Failed to process request', 500) } } ) @@ -164,10 +149,7 @@ export const PUT = withRouteHandler( try { const parsed = await parseRequest(verifyFormEmailOtpContract, request, context, { validationErrorResponse: (error) => - addCorsHeaders( - createErrorResponse(getValidationErrorMessage(error, 'Invalid request'), 400), - request - ), + createErrorResponse(getValidationErrorMessage(error, 'Invalid request'), 400), }) if (!parsed.success) return parsed.response const { email, otp } = parsed.data.body @@ -186,23 +168,17 @@ export const PUT = withRouteHandler( if (deploymentResult.length === 0) { logger.warn(`[${requestId}] Form not found for identifier: ${identifier}`) - return addCorsHeaders(createErrorResponse('Form not found', 404), request) + return createErrorResponse('Form not found', 404) } const deployment = deploymentResult[0] if (!deployment.isActive) { - return addCorsHeaders( - createErrorResponse('This form is currently unavailable', 403), - request - ) + return createErrorResponse('This form is currently unavailable', 403) } if (deployment.authType !== 'email') { - return addCorsHeaders( - createErrorResponse('This form does not use email authentication', 400), - request - ) + return createErrorResponse('This form does not use email authentication', 400) } const allowedEmails: string[] = Array.isArray(deployment.allowedEmails) @@ -210,18 +186,12 @@ export const PUT = withRouteHandler( : [] if (!isEmailAllowed(email, allowedEmails)) { - return addCorsHeaders( - createErrorResponse('Email not authorized for this form', 403), - request - ) + return createErrorResponse('Email not authorized for this form', 403) } const storedValue = await getOTP('form', deployment.id, email) if (!storedValue) { - return addCorsHeaders( - createErrorResponse('No verification code found, request a new one', 400), - request - ) + return createErrorResponse('No verification code found, request a new one', 400) } const { otp: storedOTP, attempts } = decodeOTPValue(storedValue) @@ -229,33 +199,27 @@ export const PUT = withRouteHandler( if (attempts >= MAX_OTP_ATTEMPTS) { await deleteOTP('form', deployment.id, email) logger.warn(`[${requestId}] OTP already locked out for ${email}`) - return addCorsHeaders( - createErrorResponse('Too many failed attempts. Please request a new code.', 429), - request - ) + return createErrorResponse('Too many failed attempts. Please request a new code.', 429) } if (storedOTP !== otp) { const result = await incrementOTPAttempts('form', deployment.id, email, storedValue) if (result === 'locked') { logger.warn(`[${requestId}] OTP invalidated after max failed attempts for ${email}`) - return addCorsHeaders( - createErrorResponse('Too many failed attempts. Please request a new code.', 429), - request - ) + return createErrorResponse('Too many failed attempts. Please request a new code.', 429) } - return addCorsHeaders(createErrorResponse('Invalid verification code', 400), request) + return createErrorResponse('Invalid verification code', 400) } await deleteOTP('form', deployment.id, email) - const response = addCorsHeaders(createSuccessResponse({ authenticated: true }), request) + const response = createSuccessResponse({ authenticated: true }) setFormAuthCookie(response, deployment.id, deployment.authType, deployment.password) return response } catch (error) { logger.error(`[${requestId}] Error verifying OTP:`, error) - return addCorsHeaders(createErrorResponse('Failed to process request', 500), request) + return createErrorResponse('Failed to process request', 500) } } ) diff --git a/apps/sim/app/api/form/[identifier]/route.ts b/apps/sim/app/api/form/[identifier]/route.ts index d5ed51c4af7..46b0f1e068f 100644 --- a/apps/sim/app/api/form/[identifier]/route.ts +++ b/apps/sim/app/api/form/[identifier]/route.ts @@ -6,7 +6,7 @@ import { and, eq, isNull } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { formSubmitBodySchema } from '@/lib/api/contracts/forms' import { parseJsonBody } from '@/lib/api/server' -import { addCorsHeaders, validateAuthToken } from '@/lib/core/security/deployment' +import { validateAuthToken } from '@/lib/core/security/deployment' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { preprocessExecution } from '@/lib/execution/preprocessing' @@ -55,7 +55,7 @@ export const POST = withRouteHandler( try { const parsedJson = await parseJsonBody(request) if (!parsedJson.success) { - return addCorsHeaders(createErrorResponse('Invalid request body', 400), request) + return createErrorResponse('Invalid request body', 400) } const bodyValidation = formSubmitBodySchema.safeParse(parsedJson.data) @@ -64,10 +64,7 @@ export const POST = withRouteHandler( .map((err) => `${err.path.join('.')}: ${err.message}`) .join(', ') logger.warn(`[${requestId}] Validation error: ${errorMessage}`) - return addCorsHeaders( - createErrorResponse(`Invalid request body: ${errorMessage}`, 400), - request - ) + return createErrorResponse(`Invalid request body: ${errorMessage}`, 400) } const parsedBody = bodyValidation.data @@ -89,7 +86,7 @@ export const POST = withRouteHandler( if (deploymentResult.length === 0) { logger.warn(`[${requestId}] Form not found for identifier: ${identifier}`) - return addCorsHeaders(createErrorResponse('Form not found', 404), request) + return createErrorResponse('Form not found', 404) } const deployment = deploymentResult[0] @@ -108,10 +105,7 @@ export const POST = withRouteHandler( logger.warn( `[${requestId}] Cannot log: workflow ${deployment.workflowId} has no workspace` ) - return addCorsHeaders( - createErrorResponse('This form is currently unavailable', 403), - request - ) + return createErrorResponse('This form is currently unavailable', 403) } const executionId = generateId() @@ -136,31 +130,25 @@ export const POST = withRouteHandler( traceSpans: [], }) - return addCorsHeaders( - createErrorResponse('This form is currently unavailable', 403), - request - ) + return createErrorResponse('This form is currently unavailable', 403) } const authResult = await validateFormAuth(requestId, deployment, request, parsedBody) if (!authResult.authorized) { - return addCorsHeaders( - createErrorResponse(authResult.error || 'Authentication required', 401), - request - ) + return createErrorResponse(authResult.error || 'Authentication required', 401) } const { formData, password, email } = parsedBody // If only authentication credentials provided (no form data), just return authenticated if ((password || email) && !formData) { - const response = addCorsHeaders(createSuccessResponse({ authenticated: true }), request) + const response = createSuccessResponse({ authenticated: true }) setFormAuthCookie(response, deployment.id, deployment.authType, deployment.password) return response } if (!formData || Object.keys(formData).length === 0) { - return addCorsHeaders(createErrorResponse('No form data provided', 400), request) + return createErrorResponse('No form data provided', 400) } const executionId = generateId() @@ -184,12 +172,9 @@ export const POST = withRouteHandler( if (!preprocessResult.success) { logger.warn(`[${requestId}] Preprocessing failed: ${preprocessResult.error?.message}`) - return addCorsHeaders( - createErrorResponse( - preprocessResult.error?.message || 'Failed to process request', - preprocessResult.error?.statusCode || 500 - ), - request + return createErrorResponse( + preprocessResult.error?.message || 'Failed to process request', + preprocessResult.error?.statusCode || 500 ) } @@ -198,10 +183,7 @@ export const POST = withRouteHandler( const workspaceId = workflowRecord?.workspaceId if (!workspaceId) { logger.error(`[${requestId}] Workflow ${deployment.workflowId} has no workspaceId`) - return addCorsHeaders( - createErrorResponse('Workflow has no associated workspace', 500), - request - ) + return createErrorResponse('Workflow has no associated workspace', 500) } try { @@ -264,29 +246,20 @@ export const POST = withRouteHandler( // Return success with customizations for thank you screen const customizations = deployment.customizations as Record | null - return addCorsHeaders( - createSuccessResponse({ - success: true, - executionId, - thankYouTitle: customizations?.thankYouTitle || 'Thank you!', - thankYouMessage: - customizations?.thankYouMessage || 'Your response has been submitted successfully.', - }), - request - ) + return createSuccessResponse({ + success: true, + executionId, + thankYouTitle: customizations?.thankYouTitle || 'Thank you!', + thankYouMessage: + customizations?.thankYouMessage || 'Your response has been submitted successfully.', + }) } catch (error: any) { logger.error(`[${requestId}] Error processing form submission:`, error) - return addCorsHeaders( - createErrorResponse(error.message || 'Failed to process form submission', 500), - request - ) + return createErrorResponse(error.message || 'Failed to process form submission', 500) } } catch (error: any) { logger.error(`[${requestId}] Error processing form submission:`, error) - return addCorsHeaders( - createErrorResponse(error.message || 'Failed to process form submission', 500), - request - ) + return createErrorResponse(error.message || 'Failed to process form submission', 500) } } ) @@ -316,17 +289,14 @@ export const GET = withRouteHandler( if (deploymentResult.length === 0) { logger.warn(`[${requestId}] Form not found for identifier: ${identifier}`) - return addCorsHeaders(createErrorResponse('Form not found', 404), request) + return createErrorResponse('Form not found', 404) } const deployment = deploymentResult[0] if (!deployment.isActive) { logger.warn(`[${requestId}] Form is not active: ${identifier}`) - return addCorsHeaders( - createErrorResponse('This form is currently unavailable', 403), - request - ) + return createErrorResponse('This form is currently unavailable', 403) } // Get the workflow's input schema @@ -341,18 +311,15 @@ export const GET = withRouteHandler( authCookie && validateAuthToken(authCookie.value, deployment.id, deployment.password) ) { - return addCorsHeaders( - createSuccessResponse({ - id: deployment.id, - title: deployment.title, - description: deployment.description, - customizations: deployment.customizations, - authType: deployment.authType, - showBranding: deployment.showBranding, - inputSchema, - }), - request - ) + return createSuccessResponse({ + id: deployment.id, + title: deployment.title, + description: deployment.description, + customizations: deployment.customizations, + authType: deployment.authType, + showBranding: deployment.showBranding, + inputSchema, + }) } // Check authentication requirement @@ -362,46 +329,33 @@ export const GET = withRouteHandler( logger.info( `[${requestId}] Authentication required for form: ${identifier}, type: ${deployment.authType}` ) - return addCorsHeaders( - NextResponse.json( - { - success: false, - error: authResult.error || 'Authentication required', - authType: deployment.authType, - title: deployment.title, - customizations: { - primaryColor: (deployment.customizations as any)?.primaryColor, - logoUrl: (deployment.customizations as any)?.logoUrl, - }, + return NextResponse.json( + { + success: false, + error: authResult.error || 'Authentication required', + authType: deployment.authType, + title: deployment.title, + customizations: { + primaryColor: (deployment.customizations as any)?.primaryColor, + logoUrl: (deployment.customizations as any)?.logoUrl, }, - { status: 401 } - ), - request + }, + { status: 401 } ) } - return addCorsHeaders( - createSuccessResponse({ - id: deployment.id, - title: deployment.title, - description: deployment.description, - customizations: deployment.customizations, - authType: deployment.authType, - showBranding: deployment.showBranding, - inputSchema, - }), - request - ) + return createSuccessResponse({ + id: deployment.id, + title: deployment.title, + description: deployment.description, + customizations: deployment.customizations, + authType: deployment.authType, + showBranding: deployment.showBranding, + inputSchema, + }) } catch (error: any) { logger.error(`[${requestId}] Error fetching form info:`, error) - return addCorsHeaders( - createErrorResponse(error.message || 'Failed to fetch form information', 500), - request - ) + return createErrorResponse(error.message || 'Failed to fetch form information', 500) } } ) - -export const OPTIONS = withRouteHandler(async (request: NextRequest) => { - return addCorsHeaders(new NextResponse(null, { status: 204 }), request) -}) diff --git a/apps/sim/app/api/form/utils.test.ts b/apps/sim/app/api/form/utils.test.ts index 1826d9386c1..d6b51c2d778 100644 --- a/apps/sim/app/api/form/utils.test.ts +++ b/apps/sim/app/api/form/utils.test.ts @@ -7,17 +7,13 @@ import { encryptionMock, encryptionMockFns, workflowsUtilsMock } from '@sim/test import type { NextResponse } from 'next/server' import { beforeEach, describe, expect, it, vi } from 'vitest' -const { - mockValidateAuthToken, - mockSetDeploymentAuthCookie, - mockAddCorsHeaders, - mockIsEmailAllowed, -} = vi.hoisted(() => ({ - mockValidateAuthToken: vi.fn().mockReturnValue(false), - mockSetDeploymentAuthCookie: vi.fn(), - mockAddCorsHeaders: vi.fn((response: unknown) => response), - mockIsEmailAllowed: vi.fn(), -})) +const { mockValidateAuthToken, mockSetDeploymentAuthCookie, mockIsEmailAllowed } = vi.hoisted( + () => ({ + mockValidateAuthToken: vi.fn().mockReturnValue(false), + mockSetDeploymentAuthCookie: vi.fn(), + mockIsEmailAllowed: vi.fn(), + }) +) const mockDecryptSecret = encryptionMockFns.mockDecryptSecret @@ -26,7 +22,6 @@ vi.mock('@/lib/core/security/encryption', () => encryptionMock) vi.mock('@/lib/core/security/deployment', () => ({ validateAuthToken: mockValidateAuthToken, setDeploymentAuthCookie: mockSetDeploymentAuthCookie, - addCorsHeaders: mockAddCorsHeaders, isEmailAllowed: mockIsEmailAllowed, })) diff --git a/apps/sim/app/api/mcp/copilot/route.ts b/apps/sim/app/api/mcp/copilot/route.ts index 694009c94c0..9cdb7de7301 100644 --- a/apps/sim/app/api/mcp/copilot/route.ts +++ b/apps/sim/app/api/mcp/copilot/route.ts @@ -386,19 +386,6 @@ export const POST = withRouteHandler(async (request: NextRequest) => { } }) -export const OPTIONS = withRouteHandler(async () => { - return new NextResponse(null, { - status: 204, - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, DELETE', - 'Access-Control-Allow-Headers': - 'Content-Type, Authorization, X-API-Key, X-Requested-With, Accept', - 'Access-Control-Max-Age': '86400', - }, - }) -}) - export const DELETE = withRouteHandler(async (request: NextRequest) => { void request return NextResponse.json(createError(0, -32000, 'Method not allowed.'), { status: 405 }) diff --git a/apps/sim/app/api/templates/approved/sanitized/route.ts b/apps/sim/app/api/templates/approved/sanitized/route.ts index a2eba630a50..6fa0e69d7f5 100644 --- a/apps/sim/app/api/templates/approved/sanitized/route.ts +++ b/apps/sim/app/api/templates/approved/sanitized/route.ts @@ -131,21 +131,3 @@ export const GET = withRouteHandler(async (request: NextRequest) => { ) } }) - -// Add a helpful OPTIONS handler for CORS preflight -export const OPTIONS = withRouteHandler(async (request: NextRequest) => { - const requestId = generateRequestId() - const queryValidation = noInputSchema.safeParse( - Object.fromEntries(request.nextUrl.searchParams.entries()) - ) - if (!queryValidation.success) return validationErrorResponse(queryValidation.error) - logger.info(`[${requestId}] OPTIONS request received for /api/templates/approved/sanitized`) - - return new NextResponse(null, { - status: 200, - headers: { - 'Access-Control-Allow-Methods': 'GET, OPTIONS', - 'Access-Control-Allow-Headers': 'X-API-Key, Content-Type', - }, - }) -}) diff --git a/apps/sim/app/api/tools/image/route.ts b/apps/sim/app/api/tools/image/route.ts index f6105233285..8ea4af44d70 100644 --- a/apps/sim/app/api/tools/image/route.ts +++ b/apps/sim/app/api/tools/image/route.ts @@ -98,15 +98,3 @@ export const GET = withRouteHandler(async (request: NextRequest) => { }) } }) - -export const OPTIONS = withRouteHandler(async () => { - return new NextResponse(null, { - status: 204, - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - 'Access-Control-Max-Age': '86400', - }, - }) -}) diff --git a/apps/sim/lib/core/security/deployment.ts b/apps/sim/lib/core/security/deployment.ts index c3658b9d39a..818ff588edb 100644 --- a/apps/sim/lib/core/security/deployment.ts +++ b/apps/sim/lib/core/security/deployment.ts @@ -1,13 +1,14 @@ import { safeCompare } from '@sim/security/compare' import { sha256Hex } from '@sim/security/hash' import { hmacSha256Hex } from '@sim/security/hmac' -import type { NextRequest, NextResponse } from 'next/server' +import type { NextResponse } from 'next/server' import { env } from '@/lib/core/config/env' import { isDev } from '@/lib/core/config/feature-flags' /** * Shared authentication utilities for deployed chat and form endpoints. - * These functions handle token generation, validation, cookies, and CORS. + * Handles token generation, validation, and auth cookies. CORS for these + * endpoints lives in proxy.ts as the single source of truth. */ function signPayload(payload: string): string { @@ -93,24 +94,6 @@ export function setDeploymentAuthCookie( }) } -/** - * Adds CORS headers to allow cross-origin requests for embedded deployments. - * We reflect the requesting origin to support same-site cross-origin setups - * (e.g. subdomains), but never set Allow-Credentials — auth cookies use - * SameSite=Lax and are handled within same-origin iframe contexts. - */ -export function addCorsHeaders(response: NextResponse, request: NextRequest): NextResponse { - const origin = request.headers.get('origin') - - if (origin) { - response.headers.set('Access-Control-Allow-Origin', origin) - response.headers.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS') - response.headers.set('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With') - } - - return response -} - /** * Checks if an email matches the allowed emails list (exact match or domain match) */ diff --git a/apps/sim/next.config.ts b/apps/sim/next.config.ts index 558264ea768..cce4e528bcb 100644 --- a/apps/sim/next.config.ts +++ b/apps/sim/next.config.ts @@ -156,85 +156,10 @@ const nextConfig: NextConfig = { { key: 'Access-Control-Allow-Headers', value: 'Content-Type, Accept' }, ], }, - { - // API routes CORS headers - source: '/api/:path*', - headers: [ - { key: 'Access-Control-Allow-Credentials', value: 'true' }, - { - key: 'Access-Control-Allow-Origin', - value: env.NEXT_PUBLIC_APP_URL || 'http://localhost:3001', - }, - { - key: 'Access-Control-Allow-Methods', - value: 'GET,POST,OPTIONS,PUT,DELETE', - }, - { - key: 'Access-Control-Allow-Headers', - value: - 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-API-Key, Authorization', - }, - ], - }, - { - source: '/api/auth/oauth2/:path*', - headers: [ - { key: 'Access-Control-Allow-Credentials', value: 'false' }, - { key: 'Access-Control-Allow-Origin', value: '*' }, - { key: 'Access-Control-Allow-Methods', value: 'GET, POST, OPTIONS' }, - { - key: 'Access-Control-Allow-Headers', - value: 'Content-Type, Authorization, Accept', - }, - ], - }, - { - source: '/api/auth/jwks', - headers: [ - { key: 'Access-Control-Allow-Credentials', value: 'false' }, - { key: 'Access-Control-Allow-Origin', value: '*' }, - { key: 'Access-Control-Allow-Methods', value: 'GET, OPTIONS' }, - { key: 'Access-Control-Allow-Headers', value: 'Content-Type, Accept' }, - ], - }, - { - source: '/api/auth/.well-known/:path*', - headers: [ - { key: 'Access-Control-Allow-Credentials', value: 'false' }, - { key: 'Access-Control-Allow-Origin', value: '*' }, - { key: 'Access-Control-Allow-Methods', value: 'GET, OPTIONS' }, - { key: 'Access-Control-Allow-Headers', value: 'Content-Type, Accept' }, - ], - }, - { - source: '/api/mcp/copilot', - headers: [ - { key: 'Access-Control-Allow-Credentials', value: 'false' }, - { key: 'Access-Control-Allow-Origin', value: '*' }, - { - key: 'Access-Control-Allow-Methods', - value: 'GET, POST, OPTIONS, DELETE', - }, - { - key: 'Access-Control-Allow-Headers', - value: 'Content-Type, Authorization, X-API-Key, X-Requested-With, Accept', - }, - ], - }, - // For workflow execution API endpoints + // /api/* CORS is set at runtime in proxy.ts (resolveApiCorsPolicy). { source: '/api/workflows/:id/execute', headers: [ - { key: 'Access-Control-Allow-Origin', value: '*' }, - { - key: 'Access-Control-Allow-Methods', - value: 'GET,POST,OPTIONS,PUT', - }, - { - key: 'Access-Control-Allow-Headers', - value: - 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-API-Key', - }, { key: 'Cross-Origin-Embedder-Policy', value: 'unsafe-none' }, { key: 'Cross-Origin-Opener-Policy', value: 'unsafe-none' }, { @@ -317,16 +242,6 @@ const nextConfig: NextConfig = { { key: 'Cross-Origin-Opener-Policy', value: 'unsafe-none' }, ], }, - // Form API routes - allow cross-origin requests - { - source: '/api/form/:path*', - headers: [ - { key: 'Access-Control-Allow-Origin', value: '*' }, - { key: 'Access-Control-Allow-Methods', value: 'GET, POST, OPTIONS' }, - { key: 'Access-Control-Allow-Headers', value: 'Content-Type, X-Requested-With' }, - { key: 'Access-Control-Allow-Credentials', value: 'true' }, - ], - }, // Apply security headers to routes not handled by middleware runtime CSP // Middleware handles: /, /login, /signup, /workspace/* // Exclude chat and form routes which have their own permissive embed headers diff --git a/apps/sim/proxy.test.ts b/apps/sim/proxy.test.ts new file mode 100644 index 00000000000..0282d670cd3 --- /dev/null +++ b/apps/sim/proxy.test.ts @@ -0,0 +1,145 @@ +/** + * @vitest-environment node + */ +import { createEnvMock } from '@sim/testing' +import type { NextRequest } from 'next/server' +import { describe, expect, it, vi } from 'vitest' + +vi.mock('@/lib/core/config/env', () => + createEnvMock({ NEXT_PUBLIC_APP_URL: 'https://app.sim.test' }) +) + +import { resolveApiCorsPolicy } from '@/proxy' + +function makeRequest(pathname: string, origin?: string): NextRequest { + return { + nextUrl: { pathname }, + headers: { + get: (name: string) => (name.toLowerCase() === 'origin' ? (origin ?? null) : null), + }, + } as unknown as NextRequest +} + +describe('resolveApiCorsPolicy', () => { + it('serves OAuth2 routes with wildcard origin and no credentials', () => { + expect(resolveApiCorsPolicy(makeRequest('/api/auth/oauth2/token'))).toEqual({ + origin: '*', + credentials: false, + methods: 'GET, POST, OPTIONS', + headers: 'Content-Type, Authorization, Accept', + }) + }) + + it('serves JWKS and well-known with wildcard origin', () => { + expect(resolveApiCorsPolicy(makeRequest('/api/auth/jwks')).origin).toBe('*') + expect( + resolveApiCorsPolicy(makeRequest('/api/auth/.well-known/openid-configuration')).origin + ).toBe('*') + }) + + it('serves MCP copilot with DELETE in allowed methods', () => { + const policy = resolveApiCorsPolicy(makeRequest('/api/mcp/copilot')) + expect(policy.origin).toBe('*') + expect(policy.methods).toContain('DELETE') + expect(policy.headers).toContain('X-API-Key') + }) + + it('reflects origin for chat and form embeds, never sets credentials', () => { + const paths = [ + '/api/chat/abc', + '/api/chat/abc/otp', + '/api/chat/abc/sso', + '/api/form/xyz', + '/api/form/xyz/otp', + ] + for (const path of paths) { + const policy = resolveApiCorsPolicy(makeRequest(path, 'https://customer.example')) + expect(policy).toEqual({ + origin: 'https://customer.example', + credentials: false, + methods: 'GET, POST, PUT, OPTIONS', + headers: 'Content-Type, X-Requested-With', + }) + } + }) + + it('allows PUT on the embed policy (used by OTP verification on /[identifier]/otp)', () => { + const policy = resolveApiCorsPolicy( + makeRequest('/api/chat/abc/otp', 'https://customer.example') + ) + expect(policy.methods).toContain('PUT') + }) + + it('falls back to wildcard for chat/form embeds when no origin header is present', () => { + expect(resolveApiCorsPolicy(makeRequest('/api/chat/abc')).origin).toBe('*') + }) + + it('applies the embed policy to future identifier subroutes (not just /otp, /sso)', () => { + const policy = resolveApiCorsPolicy( + makeRequest('/api/chat/abc/transcript', 'https://customer.example') + ) + expect(policy.origin).toBe('https://customer.example') + expect(policy.credentials).toBe(false) + }) + + it('uses the default credentialed policy for workspace-internal chat/form routes', () => { + const paths = [ + '/api/chat', + '/api/chat/manage/abc', + '/api/chat/validate', + '/api/form', + '/api/form/manage/abc', + '/api/form/validate', + ] + for (const path of paths) { + const policy = resolveApiCorsPolicy(makeRequest(path, 'https://customer.example')) + expect(policy.origin).toBe('https://app.sim.test') + expect(policy.credentials).toBe(true) + } + }) + + it('serves workflow execute with wildcard origin and PUT method', () => { + const policy = resolveApiCorsPolicy( + makeRequest('/api/workflows/workflow-123/execute', 'https://other.example') + ) + expect(policy.origin).toBe('*') + expect(policy.credentials).toBe(false) + expect(policy.methods).toContain('PUT') + }) + + it('does not match the workflow execute rule for nested paths', () => { + const policy = resolveApiCorsPolicy( + makeRequest('/api/workflows/workflow-123/execute/extra', 'https://other.example') + ) + expect(policy.origin).toBe('https://app.sim.test') + }) + + it('returns default policy with APP_URL and credentials for other API routes', () => { + const policy = resolveApiCorsPolicy(makeRequest('/api/files/upload')) + expect(policy).toEqual({ + origin: 'https://app.sim.test', + credentials: true, + methods: 'GET,POST,OPTIONS,PUT,DELETE', + headers: expect.stringContaining('Authorization'), + }) + }) + + it('never pairs wildcard origin with credentials (CORS spec invariant)', () => { + const paths = [ + '/api/auth/oauth2/token', + '/api/auth/jwks', + '/api/auth/.well-known/openid-configuration', + '/api/mcp/copilot', + '/api/chat/abc', + '/api/form', + '/api/workflows/wf/execute', + '/api/files/upload', + ] + for (const path of paths) { + const policy = resolveApiCorsPolicy(makeRequest(path)) + if (policy.origin === '*') { + expect(policy.credentials).toBe(false) + } + } + }) +}) diff --git a/apps/sim/proxy.ts b/apps/sim/proxy.ts index ed642956360..a5b8ea6df90 100644 --- a/apps/sim/proxy.ts +++ b/apps/sim/proxy.ts @@ -2,12 +2,149 @@ import { createLogger } from '@sim/logger' import { getSessionCookie } from 'better-auth/cookies' import { type NextRequest, NextResponse } from 'next/server' import { sendToProfound } from './lib/analytics/profound' +import { getEnv } from './lib/core/config/env' import { isAuthDisabled, isHosted } from './lib/core/config/feature-flags' import { generateRuntimeCSP } from './lib/core/security/csp' import { getClientIp } from './lib/core/utils/request' const logger = createLogger('Proxy') +export interface CorsPolicy { + origin: string + credentials: boolean + methods: string + headers: string +} + +const DEFAULT_API_ALLOWED_HEADERS = + 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-API-Key, Authorization' + +const WORKFLOW_EXECUTE_HEADERS = + 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-API-Key' + +/** + * Workspace-internal segments under /api/{chat,form}/* that must NOT + * receive the embed policy. They serve the workspace UI with session + * cookies and need the default credentialed policy. + */ +const EMBED_RESERVED_SEGMENTS = new Set(['manage', 'validate']) + +/** + * True for /api/{chat,form}/[identifier] and any deeper subroute + * (e.g. /otp, /sso). The identifier segment is explicitly checked + * against EMBED_RESERVED_SEGMENTS so workspace-internal routes fall + * through to the default credentialed policy. + */ +function isEmbedPath(pathname: string): boolean { + const segments = pathname.split('/') + if (segments.length < 4) return false + if (segments[1] !== 'api') return false + if (segments[2] !== 'chat' && segments[2] !== 'form') return false + const identifier = segments[3] + if (!identifier || EMBED_RESERVED_SEGMENTS.has(identifier)) return false + return true +} + +interface CorsRule { + match: (pathname: string) => boolean + policy: (request: NextRequest) => CorsPolicy +} + +const CORS_RULES: readonly CorsRule[] = [ + { + match: (p) => p.startsWith('/api/auth/oauth2/'), + policy: () => ({ + origin: '*', + credentials: false, + methods: 'GET, POST, OPTIONS', + headers: 'Content-Type, Authorization, Accept', + }), + }, + { + match: (p) => p === '/api/auth/jwks' || p.startsWith('/api/auth/.well-known/'), + policy: () => ({ + origin: '*', + credentials: false, + methods: 'GET, OPTIONS', + headers: 'Content-Type, Accept', + }), + }, + { + match: (p) => p === '/api/mcp/copilot', + policy: () => ({ + origin: '*', + credentials: false, + methods: 'GET, POST, OPTIONS, DELETE', + headers: 'Content-Type, Authorization, X-API-Key, X-Requested-With, Accept', + }), + }, + { + // Embed endpoints: /api/chat/[identifier] and /api/form/[identifier] + // (plus their /otp and /sso subroutes). These run on customer domains — + // reflect the request origin and omit credentials (auth uses signed + // tokens, not cookies). Workspace-internal subpaths (`manage`, `validate`, + // and the bare collection routes) are deliberately excluded so they + // continue to receive the default credentialed policy. + match: (p) => isEmbedPath(p), + policy: (request) => ({ + origin: request.headers.get('origin') || '*', + credentials: false, + // PUT is required for OTP verification on /[identifier]/otp. + methods: 'GET, POST, PUT, OPTIONS', + headers: 'Content-Type, X-Requested-With', + }), + }, + { + match: (p) => /^\/api\/workflows\/[^/]+\/execute$/.test(p), + policy: () => ({ + origin: '*', + credentials: false, + methods: 'GET,POST,OPTIONS,PUT', + headers: WORKFLOW_EXECUTE_HEADERS, + }), + }, +] + +/** + * Single source of truth for CORS on /api/* — next.config.ts headers are + * baked at build time and would freeze NEXT_PUBLIC_APP_URL into the image. + */ +export function resolveApiCorsPolicy(request: NextRequest): CorsPolicy { + const { pathname } = request.nextUrl + for (const rule of CORS_RULES) { + if (rule.match(pathname)) return rule.policy(request) + } + return { + origin: getEnv('NEXT_PUBLIC_APP_URL') || 'http://localhost:3001', + credentials: true, + methods: 'GET,POST,OPTIONS,PUT,DELETE', + headers: DEFAULT_API_ALLOWED_HEADERS, + } +} + +const CORS_PREFLIGHT_MAX_AGE = '86400' + +function applyCorsHeaders(response: NextResponse, policy: CorsPolicy): void { + response.headers.set('Access-Control-Allow-Origin', policy.origin) + response.headers.set('Access-Control-Allow-Credentials', String(policy.credentials)) + response.headers.set('Access-Control-Allow-Methods', policy.methods) + response.headers.set('Access-Control-Allow-Headers', policy.headers) + if (policy.origin !== '*') { + response.headers.set('Vary', 'Origin') + } +} + +/** + * Short-circuit preflight: Next's auto-OPTIONS for route handlers without + * an explicit OPTIONS export does not carry middleware headers. + */ +function buildPreflightResponse(policy: CorsPolicy): NextResponse { + const response = new NextResponse(null, { status: 204 }) + applyCorsHeaders(response, policy) + response.headers.set('Access-Control-Max-Age', CORS_PREFLIGHT_MAX_AGE) + return response +} + const SUSPICIOUS_UA_PATTERNS = [ /^\s*$/, // Empty user agents /\.\./, // Path traversal attempt @@ -122,6 +259,16 @@ function handleSecurityFiltering(request: NextRequest): NextResponse | null { export async function proxy(request: NextRequest) { const url = request.nextUrl + if (url.pathname.startsWith('/api/')) { + const policy = resolveApiCorsPolicy(request) + if (request.method === 'OPTIONS') { + return buildPreflightResponse(policy) + } + const response = NextResponse.next() + applyCorsHeaders(response, policy) + return response + } + const sessionCookie = getSessionCookie(request) const hasActiveSession = isAuthDisabled || !!sessionCookie @@ -202,6 +349,7 @@ export const config = { '/login', '/signup', '/invite/:path*', // Match invitation routes + '/api/:path*', // Runtime CORS // Catch-all for other pages, excluding static assets and public directories '/((?!api/|api$|_next/static|_next/image|ingest|favicon.ico|logo/|static/|footer/|social/|enterprise/|favicon/|twitter/|robots.txt|sitemap.xml).*)', ], diff --git a/docker/app.Dockerfile b/docker/app.Dockerfile index 0c6087e241f..79400246492 100644 --- a/docker/app.Dockerfile +++ b/docker/app.Dockerfile @@ -74,11 +74,6 @@ ENV NEXT_TELEMETRY_DISABLED=1 \ ARG DATABASE_URL="postgresql://user:pass@localhost:5432/dummy" ENV DATABASE_URL=${DATABASE_URL} -# Provide dummy NEXT_PUBLIC_APP_URL for build-time evaluation -# Runtime environments should override this with the actual URL -ARG NEXT_PUBLIC_APP_URL="http://localhost:3000" -ENV NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL} - # Per-platform cache id keeps arm64/amd64 SWC artifacts isolated. RUN --mount=type=cache,id=next-cache-${TARGETPLATFORM},target=/app/apps/sim/.next/cache \ --mount=type=cache,id=turbo-cache-${TARGETPLATFORM},target=/app/.turbo \ From b98164fd3d5ef4dced628d7d380512e9385955f7 Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 19 May 2026 12:06:19 -0700 Subject: [PATCH 04/13] feat(wiza): add Wiza integration for B2B prospect enrichment and search (#4662) * feat(wiza): add Wiza integration for B2B prospect enrichment and search * fix(wiza): coerce reveal id to string, skip empty filters in prospect search * fix(wiza): throw on invalid JSON in advanced filter fields instead of silently dropping --- apps/docs/components/icons.tsx | 11 + apps/docs/components/ui/icon-mapping.ts | 2 + .../content/docs/en/tools/google_docs.mdx | 3 +- apps/docs/content/docs/en/tools/meta.json | 1 + apps/docs/content/docs/en/tools/wiza.mdx | 251 ++++++++++ .../integrations/data/icon-mapping.ts | 2 + .../integrations/data/integrations.json | 41 +- apps/sim/blocks/blocks/wiza.ts | 427 ++++++++++++++++++ apps/sim/blocks/registry.ts | 2 + apps/sim/components/icons.tsx | 11 + apps/sim/tools/registry.ts | 12 + apps/sim/tools/wiza/company_enrichment.ts | 142 ++++++ apps/sim/tools/wiza/get_credits.ts | 62 +++ apps/sim/tools/wiza/get_individual_reveal.ts | 163 +++++++ apps/sim/tools/wiza/index.ts | 6 + apps/sim/tools/wiza/prospect_search.ts | 246 ++++++++++ .../sim/tools/wiza/start_individual_reveal.ts | 142 ++++++ apps/sim/tools/wiza/types.ts | 178 ++++++++ 18 files changed, 1700 insertions(+), 2 deletions(-) create mode 100644 apps/docs/content/docs/en/tools/wiza.mdx create mode 100644 apps/sim/blocks/blocks/wiza.ts create mode 100644 apps/sim/tools/wiza/company_enrichment.ts create mode 100644 apps/sim/tools/wiza/get_credits.ts create mode 100644 apps/sim/tools/wiza/get_individual_reveal.ts create mode 100644 apps/sim/tools/wiza/index.ts create mode 100644 apps/sim/tools/wiza/prospect_search.ts create mode 100644 apps/sim/tools/wiza/start_individual_reveal.ts create mode 100644 apps/sim/tools/wiza/types.ts diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index 81dbe58d948..6508cb8bbb5 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -6950,3 +6950,14 @@ export function SnowflakeIcon(props: SVGProps) { ) } + +export function WizaIcon(props: SVGProps) { + return ( + + + + ) +} diff --git a/apps/docs/components/ui/icon-mapping.ts b/apps/docs/components/ui/icon-mapping.ts index dd5ab47b8cb..312eb8893ae 100644 --- a/apps/docs/components/ui/icon-mapping.ts +++ b/apps/docs/components/ui/icon-mapping.ts @@ -197,6 +197,7 @@ import { WebflowIcon, WhatsAppIcon, WikipediaIcon, + WizaIcon, WordpressIcon, WorkdayIcon, xIcon, @@ -426,6 +427,7 @@ export const blockTypeToIconMap: Record = { webflow: WebflowIcon, whatsapp: WhatsAppIcon, wikipedia: WikipediaIcon, + wiza: WizaIcon, wordpress: WordpressIcon, workday: WorkdayIcon, x: xIcon, diff --git a/apps/docs/content/docs/en/tools/google_docs.mdx b/apps/docs/content/docs/en/tools/google_docs.mdx index 35dbd4eae8d..069c91f8f6c 100644 --- a/apps/docs/content/docs/en/tools/google_docs.mdx +++ b/apps/docs/content/docs/en/tools/google_docs.mdx @@ -56,7 +56,7 @@ Read content from a Google Docs document ### `google_docs_write` -Write or update content in a Google Docs document +Append content to a Google Docs document. Content is inserted literally; Markdown is not interpreted. For formatted output from Markdown, use the Create operation with the markdown toggle enabled. #### Input @@ -88,6 +88,7 @@ Create a new Google Docs document | `content` | string | No | The content of the document to create | | `folderSelector` | string | No | Google Drive folder ID to create the document in \(e.g., 1ABCxyz...\) | | `folderId` | string | No | The ID of the folder to create the document in \(internal use\) | +| `markdown` | boolean | No | When true, content is interpreted as Markdown and converted to formatted Google Docs content \(headings, bold/italic, lists, tables, links, code blocks, blockquotes\). Default: false \(content inserted as plain text\). | #### Output diff --git a/apps/docs/content/docs/en/tools/meta.json b/apps/docs/content/docs/en/tools/meta.json index 5f04f102bb8..5448fe6407b 100644 --- a/apps/docs/content/docs/en/tools/meta.json +++ b/apps/docs/content/docs/en/tools/meta.json @@ -197,6 +197,7 @@ "webflow", "whatsapp", "wikipedia", + "wiza", "wordpress", "workday", "x", diff --git a/apps/docs/content/docs/en/tools/wiza.mdx b/apps/docs/content/docs/en/tools/wiza.mdx new file mode 100644 index 00000000000..e8d775b07a1 --- /dev/null +++ b/apps/docs/content/docs/en/tools/wiza.mdx @@ -0,0 +1,251 @@ +--- +title: Wiza +description: Find, enrich, and verify B2B contact data with Wiza +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + + + +{/* MANUAL-CONTENT-START:intro */} +[Wiza](https://wiza.co/) is a B2B contact data platform that finds and verifies emails and phone numbers for sales, recruiting, and marketing teams. Wiza pairs a global prospect database with real-time enrichment, so the data you act on stays accurate and deliverable. + +With Wiza, you can: + +- **Search a global prospect database**: Find people using person, company, and financial filters +- **Enrich companies**: Resolve firmographic data from a name, domain, or LinkedIn URL +- **Reveal individual contacts**: Get verified work emails, personal emails, and mobile phone numbers +- **Track credit usage**: Check remaining email, phone, export, and API credits at any time + +In Sim, the Wiza integration lets your agents drive prospecting and enrichment workflows end-to-end: + +- **Prospect Search**: Use `wiza_prospect_search` to discover prospects matching detailed filters. +- **Company Enrichment**: Use `wiza_company_enrichment` to enrich a company from name, domain, LinkedIn ID, or LinkedIn slug. +- **Start Individual Reveal**: Use `wiza_start_individual_reveal` to begin enrichment for a contact via LinkedIn URL, name + company, or email — with configurable enrichment depth (`none`, `partial`, `phone`, `full`). +- **Get Individual Reveal**: Use `wiza_get_individual_reveal` to poll a reveal and retrieve verified emails, phones, and full company context. +- **Get Credits**: Use `wiza_get_credits` to monitor remaining credit balances before scaling up runs. + +Individual reveals are asynchronous: start a reveal, then poll `wiza_get_individual_reveal` until `is_complete` is `true`. Combine these tools to build agents that source, enrich, and qualify leads on demand — without leaving your workflow. +{/* MANUAL-CONTENT-END */} + + +## Usage Instructions + +{/* MANUAL-CONTENT-START:usage */} +### Wiza API Key Setup + +Wiza authenticates via API key. To get yours: + +1. Log in to your [Wiza account](https://app.wiza.co/). +2. Open **Settings → API** and generate a new API key (or copy an existing one). +3. In Sim, open the Wiza block and paste the key into the **Wiza API Key** field. + +The same key is used for every Wiza operation. Wiza enforces a rate limit of 30 requests per minute (43,200 per day) per key. + +### Individual Reveals Are Asynchronous + +`wiza_start_individual_reveal` returns immediately with a reveal `id` and a `status` of `queued` or `resolving`. To retrieve the enriched contact data, call `wiza_get_individual_reveal` with that `id` and check `is_complete`. Possible statuses are `queued`, `resolving`, `finished`, and `failed`. + +For real-time delivery without polling, pass a `callback_url` when starting the reveal — Wiza will POST the completed payload to that URL. + +### Enrichment Levels and Credits + +When starting an individual reveal, choose the enrichment level that matches the data you need: + +- **`none`** — Identity only, no contact info (no credit spend) +- **`partial`** — Verified work email (email credits) +- **`phone`** — Mobile phone (phone credits) +- **`full`** — Email + phone (email + phone credits) + +Use `wiza_get_credits` to monitor remaining email, phone, export, and API credits before running large batches. +{/* MANUAL-CONTENT-END */} + + +Integrates Wiza into the workflow. Search prospects, enrich companies, reveal verified emails and phone numbers for individuals, and check your account credit balance. + + + +## Tools + +### `wiza_prospect_search` + +Search Wiza + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Wiza API key | +| `size` | number | No | Number of sample profiles to return \(0-30, default 0\) | +| `filters` | object | No | Full filters object \(overrides individual filter params if provided\) | +| `first_name` | array | No | Exact first names to match \(e.g., \["John", "Jane"\]\) | +| `last_name` | array | No | Exact last names to match | +| `job_title` | array | No | Job titles to include/exclude \(e.g., \[\{"v":"CEO","s":"i"\},\{"v":"CTO","s":"e"\}\]\) | +| `job_title_level` | array | No | Seniority levels \(e.g., \["cxo", "director", "manager"\]\) | +| `job_role` | array | No | Job role categories \(e.g., \["sales", "engineering", "marketing"\]\) | +| `job_sub_role` | array | No | Detailed role categories \(e.g., \["software", "product"\]\) | +| `location` | array | No | Person's location filters \(city/state/country with include/exclude\) | +| `skill` | array | No | Professional skills \(e.g., \["python", "marketing"\]\) | +| `school` | array | No | Educational institutions | +| `major` | array | No | Field of study | +| `linkedin_slug` | array | No | LinkedIn profile slugs | +| `job_company` | array | No | Current company filters \(include/exclude\) | +| `past_company` | array | No | Past company filters | +| `company_location` | array | No | Company HQ location filters | +| `company_industry` | array | No | Company industry filters \(include/exclude\) | +| `company_size` | array | No | Company headcount brackets \(e.g., \["1-10", "11-50", "51-200"\]\) | +| `company_type` | array | No | Company type \(e.g., \["private", "public", "educational"\]\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `total` | number | Total number of matching prospects | +| `profiles` | array | Sample profiles matching the filter criteria | + +### `wiza_company_enrichment` + +Enrich a company by name, domain, LinkedIn ID, or LinkedIn slug with detailed firmographic data + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Wiza API key | +| `company_name` | string | No | Company name \(e.g., "Wiza"\) | +| `company_domain` | string | No | Company domain \(e.g., "wiza.co"\) | +| `company_linkedin_id` | string | No | Company LinkedIn ID | +| `company_linkedin_slug` | string | No | Company LinkedIn slug from the URL | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `company_name` | string | Company name | +| `company_domain` | string | Company domain | +| `domain` | string | Domain | +| `company_industry` | string | Industry | +| `company_size` | number | Employee count | +| `company_size_range` | string | Headcount range | +| `company_founded` | number | Year founded | +| `company_revenue_range` | string | Revenue range | +| `company_funding` | string | Total funding | +| `company_type` | string | Company type | +| `company_description` | string | Description | +| `company_ticker` | string | Stock ticker | +| `company_last_funding_round` | string | Last funding round | +| `company_last_funding_amount` | string | Last funding amount | +| `company_last_funding_at` | string | Last funding date | +| `company_location` | string | Full location string | +| `company_twitter` | string | Twitter URL | +| `company_facebook` | string | Facebook URL | +| `company_linkedin` | string | LinkedIn URL | +| `company_linkedin_id` | string | LinkedIn ID | +| `company_street` | string | Street address | +| `company_locality` | string | City | +| `company_region` | string | State/region | +| `company_postal_code` | string | Postal code | +| `company_country` | string | Country | +| `credits` | json | Remaining API credits | + +### `wiza_start_individual_reveal` + +Start an individual reveal to enrich a contact via LinkedIn URL, name+company, or email + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Wiza API key | +| `enrichment_level` | string | Yes | Enrichment depth: none, partial, phone, or full | +| `profile_url` | string | No | LinkedIn profile URL \(e.g., https://linkedin.com/in/johndoe\) | +| `full_name` | string | No | Full name \(used with company or domain\) | +| `company` | string | No | Company name \(used with full_name\) | +| `domain` | string | No | Company domain \(used with full_name\) | +| `email` | string | No | Email address \(use alone or with other identifiers\) | +| `accept_work` | boolean | No | Whether to accept work emails \(email_options\) | +| `accept_personal` | boolean | No | Whether to accept personal emails \(email_options\) | +| `callback_url` | string | No | Optional URL to receive a callback with the reveal update | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `id` | number | Individual reveal ID \(use with Get Individual Reveal\) | +| `status` | string | Reveal status: queued, resolving, finished, or failed | +| `is_complete` | boolean | Whether the reveal has completed | + +### `wiza_get_individual_reveal` + +Retrieve the status and enriched data for an individual reveal by ID + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Wiza API key | +| `id` | string | Yes | Individual reveal ID returned from Start Individual Reveal | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `id` | number | Reveal ID | +| `status` | string | queued \| resolving \| finished \| failed | +| `is_complete` | boolean | Whether the reveal has completed | +| `name` | string | Full name | +| `company` | string | Company name | +| `enrichment_level` | string | Enrichment level used | +| `linkedin_profile_url` | string | LinkedIn URL | +| `title` | string | Job title | +| `location` | string | Location | +| `email` | string | Primary email | +| `email_type` | string | Email type | +| `email_status` | string | valid \| risky \| unfound | +| `emails` | array | All emails found | +| `mobile_phone` | string | Mobile phone | +| `phone_number` | string | Direct/office phone | +| `phone_status` | string | found \| unfound | +| `phones` | array | All phones found | +| `company_size` | number | Employee count | +| `company_size_range` | string | Headcount range | +| `company_type` | string | Company type | +| `company_domain` | string | Company domain | +| `company_locality` | string | City | +| `company_region` | string | State/region | +| `company_country` | string | Country | +| `company_street` | string | Street | +| `company_postal_code` | string | Postal code | +| `company_founded` | number | Year founded | +| `company_funding` | string | Funding total | +| `company_revenue` | string | Revenue | +| `company_industry` | string | Industry | +| `company_subindustry` | string | Subindustry | +| `company_linkedin` | string | Company LinkedIn URL | +| `company_location` | string | Full company location | +| `company_description` | string | Company description | +| `credits` | json | Remaining credits balance | + +### `wiza_get_credits` + +Retrieve the remaining credits on your Wiza account + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Wiza API key | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `email_credits` | json | Remaining email credits \(number or "unlimited"\) | +| `phone_credits` | json | Remaining phone credits \(number or "unlimited"\) | +| `export_credits` | number | Remaining export credits | +| `api_credits` | number | Remaining API credits | + + diff --git a/apps/sim/app/(landing)/integrations/data/icon-mapping.ts b/apps/sim/app/(landing)/integrations/data/icon-mapping.ts index 64fe8a8556d..ab6f6b1831c 100644 --- a/apps/sim/app/(landing)/integrations/data/icon-mapping.ts +++ b/apps/sim/app/(landing)/integrations/data/icon-mapping.ts @@ -197,6 +197,7 @@ import { WebflowIcon, WhatsAppIcon, WikipediaIcon, + WizaIcon, WordpressIcon, WorkdayIcon, xIcon, @@ -403,6 +404,7 @@ export const blockTypeToIconMap: Record = { webflow: WebflowIcon, whatsapp: WhatsAppIcon, wikipedia: WikipediaIcon, + wiza: WizaIcon, wordpress: WordpressIcon, workday: WorkdayIcon, x: xIcon, diff --git a/apps/sim/app/(landing)/integrations/data/integrations.json b/apps/sim/app/(landing)/integrations/data/integrations.json index d67628c4ab8..b3d8b3bc4fc 100644 --- a/apps/sim/app/(landing)/integrations/data/integrations.json +++ b/apps/sim/app/(landing)/integrations/data/integrations.json @@ -5202,7 +5202,7 @@ }, { "name": "Write to Document", - "description": "Write or update content in a Google Docs document" + "description": "Append content to a Google Docs document. Content is inserted literally; Markdown is not interpreted. For formatted output from Markdown, use the Create operation with the markdown toggle enabled." }, { "name": "Create Document", @@ -14212,6 +14212,45 @@ "integrationTypes": ["search", "documents"], "tags": ["knowledge-base", "web-scraping"] }, + { + "type": "wiza", + "slug": "wiza", + "name": "Wiza", + "description": "Find, enrich, and verify B2B contact data with Wiza", + "longDescription": "Integrates Wiza into the workflow. Search prospects, enrich companies, reveal verified emails and phone numbers for individuals, and check your account credit balance.", + "bgColor": "#9284BC", + "iconName": "WizaIcon", + "docsUrl": "https://docs.sim.ai/tools/wiza", + "operations": [ + { + "name": "Prospect Search", + "description": "Search Wiza" + }, + { + "name": "Company Enrichment", + "description": "Enrich a company by name, domain, LinkedIn ID, or LinkedIn slug with detailed firmographic data" + }, + { + "name": "Start Individual Reveal", + "description": "Start an individual reveal to enrich a contact via LinkedIn URL, name+company, or email" + }, + { + "name": "Get Individual Reveal", + "description": "Retrieve the status and enriched data for an individual reveal by ID" + }, + { + "name": "Get Credits", + "description": "Retrieve the remaining credits on your Wiza account" + } + ], + "operationCount": 5, + "triggers": [], + "triggerCount": 0, + "authType": "api-key", + "category": "tools", + "integrationTypes": ["sales"], + "tags": ["enrichment", "sales-engagement"] + }, { "type": "wordpress", "slug": "wordpress", diff --git a/apps/sim/blocks/blocks/wiza.ts b/apps/sim/blocks/blocks/wiza.ts new file mode 100644 index 00000000000..938e9318449 --- /dev/null +++ b/apps/sim/blocks/blocks/wiza.ts @@ -0,0 +1,427 @@ +import { WizaIcon } from '@/components/icons' +import type { BlockConfig } from '@/blocks/types' +import { AuthMode, IntegrationType } from '@/blocks/types' +import type { WizaResponse } from '@/tools/wiza/types' + +export const WizaBlock: BlockConfig = { + type: 'wiza', + name: 'Wiza', + description: 'Find, enrich, and verify B2B contact data with Wiza', + authMode: AuthMode.ApiKey, + longDescription: + 'Integrates Wiza into the workflow. Search prospects, enrich companies, reveal verified emails and phone numbers for individuals, and check your account credit balance.', + docsLink: 'https://docs.sim.ai/tools/wiza', + category: 'tools', + integrationType: IntegrationType.Sales, + tags: ['enrichment', 'sales-engagement'], + bgColor: '#9284BC', + icon: WizaIcon, + subBlocks: [ + { + id: 'operation', + title: 'Operation', + type: 'dropdown', + options: [ + { label: 'Prospect Search', id: 'prospect_search' }, + { label: 'Company Enrichment', id: 'company_enrichment' }, + { label: 'Start Individual Reveal', id: 'start_individual_reveal' }, + { label: 'Get Individual Reveal', id: 'get_individual_reveal' }, + { label: 'Get Credits', id: 'get_credits' }, + ], + value: () => 'prospect_search', + }, + { + id: 'apiKey', + title: 'Wiza API Key', + type: 'short-input', + placeholder: 'Enter your Wiza API key', + password: true, + required: true, + }, + + // Prospect Search + { + id: 'size', + title: 'Sample Size', + type: 'short-input', + placeholder: '0-30 (default 0, returns total only)', + condition: { field: 'operation', value: 'prospect_search' }, + }, + { + id: 'job_title', + title: 'Job Titles', + type: 'code', + placeholder: '[{"v":"CEO","s":"i"},{"v":"Founder","s":"i"}]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'job_title_level', + title: 'Job Title Levels', + type: 'code', + placeholder: '["cxo", "director", "manager"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'job_role', + title: 'Job Roles', + type: 'code', + placeholder: '["sales", "engineering", "marketing"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'job_sub_role', + title: 'Job Sub-Roles', + type: 'code', + placeholder: '["software", "product"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'first_name', + title: 'First Names', + type: 'code', + placeholder: '["John", "Jane"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'last_name', + title: 'Last Names', + type: 'code', + placeholder: '["Smith", "Doe"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'location', + title: 'Person Locations', + type: 'code', + placeholder: '[{"v":{"country":"united states"},"b":"city","s":"i"}]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'skill', + title: 'Skills', + type: 'code', + placeholder: '["python", "marketing"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'school', + title: 'Schools', + type: 'code', + placeholder: '["stanford university"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'major', + title: 'Majors', + type: 'code', + placeholder: '["computer science"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'linkedin_slug', + title: 'LinkedIn Slugs', + type: 'code', + placeholder: '["john-doe-123"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'job_company', + title: 'Current Companies', + type: 'code', + placeholder: '[{"v":"wiza","s":"i"}]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'past_company', + title: 'Past Companies', + type: 'code', + placeholder: '[{"v":"google","s":"i"}]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'company_location', + title: 'Company Locations', + type: 'code', + placeholder: '[{"v":{"country":"canada"},"b":"country","s":"i"}]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'company_industry', + title: 'Company Industries', + type: 'code', + placeholder: '[{"v":"computer software","s":"i"}]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'company_size', + title: 'Company Sizes', + type: 'code', + placeholder: '["11-50", "51-200"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'company_type', + title: 'Company Types', + type: 'code', + placeholder: '["private", "public"]', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + { + id: 'filters', + title: 'Full Filters Object (overrides above)', + type: 'code', + placeholder: '{"job_title":[{"v":"CEO","s":"i"}], "company_size":["11-50"]}', + condition: { field: 'operation', value: 'prospect_search' }, + mode: 'advanced', + }, + + // Company Enrichment + { + id: 'company_name', + title: 'Company Name', + type: 'short-input', + placeholder: 'Wiza', + condition: { field: 'operation', value: 'company_enrichment' }, + }, + { + id: 'company_domain', + title: 'Company Domain', + type: 'short-input', + placeholder: 'wiza.co', + condition: { field: 'operation', value: 'company_enrichment' }, + }, + { + id: 'company_linkedin_id', + title: 'Company LinkedIn ID', + type: 'short-input', + placeholder: '11272782', + condition: { field: 'operation', value: 'company_enrichment' }, + mode: 'advanced', + }, + { + id: 'company_linkedin_slug', + title: 'Company LinkedIn Slug', + type: 'short-input', + placeholder: 'wizaco', + condition: { field: 'operation', value: 'company_enrichment' }, + mode: 'advanced', + }, + + // Start Individual Reveal + { + id: 'enrichment_level', + title: 'Enrichment Level', + type: 'dropdown', + options: [ + { label: 'None', id: 'none' }, + { label: 'Partial', id: 'partial' }, + { label: 'Phone', id: 'phone' }, + { label: 'Full', id: 'full' }, + ], + value: () => 'full', + condition: { field: 'operation', value: 'start_individual_reveal' }, + required: { field: 'operation', value: 'start_individual_reveal' }, + }, + { + id: 'profile_url', + title: 'LinkedIn Profile URL', + type: 'short-input', + placeholder: 'https://linkedin.com/in/johndoe', + condition: { field: 'operation', value: 'start_individual_reveal' }, + }, + { + id: 'full_name', + title: 'Full Name', + type: 'short-input', + placeholder: 'John Doe', + condition: { field: 'operation', value: 'start_individual_reveal' }, + }, + { + id: 'company', + title: 'Company', + type: 'short-input', + placeholder: 'Wiza', + condition: { field: 'operation', value: 'start_individual_reveal' }, + }, + { + id: 'domain', + title: 'Company Domain', + type: 'short-input', + placeholder: 'wiza.co', + condition: { field: 'operation', value: 'start_individual_reveal' }, + }, + { + id: 'email', + title: 'Email', + type: 'short-input', + placeholder: 'john@wiza.co', + condition: { field: 'operation', value: 'start_individual_reveal' }, + }, + { + id: 'accept_work', + title: 'Accept Work Emails', + type: 'switch', + condition: { field: 'operation', value: 'start_individual_reveal' }, + mode: 'advanced', + }, + { + id: 'accept_personal', + title: 'Accept Personal Emails', + type: 'switch', + condition: { field: 'operation', value: 'start_individual_reveal' }, + mode: 'advanced', + }, + { + id: 'callback_url', + title: 'Callback URL', + type: 'short-input', + placeholder: 'https://example.com/wiza-callback', + condition: { field: 'operation', value: 'start_individual_reveal' }, + mode: 'advanced', + }, + + // Get Individual Reveal + { + id: 'id', + title: 'Reveal ID', + type: 'short-input', + placeholder: 'Reveal ID returned from Start Individual Reveal', + condition: { field: 'operation', value: 'get_individual_reveal' }, + required: { field: 'operation', value: 'get_individual_reveal' }, + }, + ], + + tools: { + access: [ + 'wiza_prospect_search', + 'wiza_company_enrichment', + 'wiza_start_individual_reveal', + 'wiza_get_individual_reveal', + 'wiza_get_credits', + ], + config: { + tool: (params) => { + switch (params.operation) { + case 'prospect_search': + return 'wiza_prospect_search' + case 'company_enrichment': + return 'wiza_company_enrichment' + case 'start_individual_reveal': + return 'wiza_start_individual_reveal' + case 'get_individual_reveal': + return 'wiza_get_individual_reveal' + case 'get_credits': + return 'wiza_get_credits' + default: + throw new Error(`Invalid Wiza operation: ${params.operation}`) + } + }, + params: (params) => { + const parsed: Record = { ...params } + + const parseJsonField = (field: string) => { + const value = parsed[field] + if (typeof value === 'string' && value.trim() !== '') { + try { + parsed[field] = JSON.parse(value) + } catch (err) { + throw new Error( + `Invalid JSON in Wiza "${field}" filter: ${err instanceof Error ? err.message : String(err)}` + ) + } + } + } + + for (const field of [ + 'filters', + 'first_name', + 'last_name', + 'job_title', + 'job_title_level', + 'job_role', + 'job_sub_role', + 'location', + 'skill', + 'school', + 'major', + 'linkedin_slug', + 'job_company', + 'past_company', + 'company_location', + 'company_industry', + 'company_size', + 'company_type', + ]) { + parseJsonField(field) + } + + if (typeof parsed.size === 'string' && parsed.size.trim() !== '') { + const n = Number(parsed.size) + if (!Number.isNaN(n)) parsed.size = n + } + + return parsed + }, + }, + }, + + inputs: { + apiKey: { type: 'string', description: 'Wiza API key' }, + operation: { type: 'string', description: 'Operation to perform' }, + size: { type: 'number', description: 'Sample size for prospect search (0-30)' }, + filters: { type: 'json', description: 'Full filters object for prospect search' }, + first_name: { type: 'json', description: 'First name filter array' }, + last_name: { type: 'json', description: 'Last name filter array' }, + job_title: { type: 'json', description: 'Job title filter array' }, + job_title_level: { type: 'json', description: 'Job title level filter' }, + job_role: { type: 'json', description: 'Job role filter' }, + job_sub_role: { type: 'json', description: 'Job sub-role filter' }, + location: { type: 'json', description: 'Person location filter' }, + skill: { type: 'json', description: 'Skill filter' }, + school: { type: 'json', description: 'School filter' }, + major: { type: 'json', description: 'Major filter' }, + linkedin_slug: { type: 'json', description: 'LinkedIn slug filter' }, + job_company: { type: 'json', description: 'Current company filter' }, + past_company: { type: 'json', description: 'Past company filter' }, + company_location: { type: 'json', description: 'Company location filter' }, + company_industry: { type: 'json', description: 'Company industry filter' }, + company_size: { type: 'json', description: 'Company size filter' }, + company_type: { type: 'json', description: 'Company type filter' }, + company_name: { type: 'string', description: 'Company name' }, + company_domain: { type: 'string', description: 'Company domain' }, + company_linkedin_id: { type: 'string', description: 'Company LinkedIn ID' }, + company_linkedin_slug: { type: 'string', description: 'Company LinkedIn slug' }, + enrichment_level: { type: 'string', description: 'Enrichment level for individual reveal' }, + profile_url: { type: 'string', description: 'LinkedIn profile URL' }, + full_name: { type: 'string', description: 'Full name' }, + company: { type: 'string', description: 'Company' }, + domain: { type: 'string', description: 'Domain' }, + email: { type: 'string', description: 'Email address' }, + accept_work: { type: 'boolean', description: 'Whether to accept work emails' }, + accept_personal: { type: 'boolean', description: 'Whether to accept personal emails' }, + callback_url: { type: 'string', description: 'Callback URL' }, + id: { type: 'string', description: 'Individual reveal ID' }, + }, + + outputs: { + success: { type: 'boolean', description: 'Whether the operation was successful' }, + output: { type: 'json', description: 'Output data from the Wiza operation' }, + }, +} diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index 268e010543f..2e008d00edb 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -225,6 +225,7 @@ import { WebflowBlock } from '@/blocks/blocks/webflow' import { WebhookRequestBlock } from '@/blocks/blocks/webhook_request' import { WhatsAppBlock } from '@/blocks/blocks/whatsapp' import { WikipediaBlock } from '@/blocks/blocks/wikipedia' +import { WizaBlock } from '@/blocks/blocks/wiza' import { WordPressBlock } from '@/blocks/blocks/wordpress' import { WorkdayBlock } from '@/blocks/blocks/workday' import { WorkflowBlock } from '@/blocks/blocks/workflow' @@ -488,6 +489,7 @@ export const registry: Record = { webhook_request: WebhookRequestBlock, whatsapp: WhatsAppBlock, wikipedia: WikipediaBlock, + wiza: WizaBlock, wordpress: WordPressBlock, workday: WorkdayBlock, workflow: WorkflowBlock, diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index 81dbe58d948..6508cb8bbb5 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -6950,3 +6950,14 @@ export function SnowflakeIcon(props: SVGProps) { ) } + +export function WizaIcon(props: SVGProps) { + return ( + + + + ) +} diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index dad88d1a940..b65d6bda699 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -2937,6 +2937,13 @@ import { wikipediaRandomPageTool, wikipediaSearchTool, } from '@/tools/wikipedia' +import { + wizaCompanyEnrichmentTool, + wizaGetCreditsTool, + wizaGetIndividualRevealTool, + wizaProspectSearchTool, + wizaStartIndividualRevealTool, +} from '@/tools/wiza' import { wordpressCreateCategoryTool, wordpressCreateCommentTool, @@ -5228,6 +5235,11 @@ export const tools: Record = { wikipedia_search: wikipediaSearchTool, wikipedia_content: wikipediaPageContentTool, wikipedia_random: wikipediaRandomPageTool, + wiza_company_enrichment: wizaCompanyEnrichmentTool, + wiza_get_credits: wizaGetCreditsTool, + wiza_get_individual_reveal: wizaGetIndividualRevealTool, + wiza_prospect_search: wizaProspectSearchTool, + wiza_start_individual_reveal: wizaStartIndividualRevealTool, wordpress_create_post: wordpressCreatePostTool, wordpress_update_post: wordpressUpdatePostTool, wordpress_delete_post: wordpressDeletePostTool, diff --git a/apps/sim/tools/wiza/company_enrichment.ts b/apps/sim/tools/wiza/company_enrichment.ts new file mode 100644 index 00000000000..75201dd694c --- /dev/null +++ b/apps/sim/tools/wiza/company_enrichment.ts @@ -0,0 +1,142 @@ +import type { ToolConfig } from '@/tools/types' +import type { WizaCompanyEnrichmentParams, WizaCompanyEnrichmentResponse } from '@/tools/wiza/types' + +export const wizaCompanyEnrichmentTool: ToolConfig< + WizaCompanyEnrichmentParams, + WizaCompanyEnrichmentResponse +> = { + id: 'wiza_company_enrichment', + name: 'Wiza Company Enrichment', + description: + 'Enrich a company by name, domain, LinkedIn ID, or LinkedIn slug with detailed firmographic data', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Wiza API key', + }, + company_name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Company name (e.g., "Wiza")', + }, + company_domain: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Company domain (e.g., "wiza.co")', + }, + company_linkedin_id: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Company LinkedIn ID', + }, + company_linkedin_slug: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Company LinkedIn slug from the URL', + }, + }, + + request: { + url: 'https://wiza.co/api/company_enrichments', + method: 'POST', + headers: (params: WizaCompanyEnrichmentParams) => ({ + Authorization: `Bearer ${params.apiKey}`, + 'Content-Type': 'application/json', + }), + body: (params: WizaCompanyEnrichmentParams) => { + const body: Record = {} + if (params.company_name) body.company_name = params.company_name + if (params.company_domain) body.company_domain = params.company_domain + if (params.company_linkedin_id) body.company_linkedin_id = params.company_linkedin_id + if (params.company_linkedin_slug) body.company_linkedin_slug = params.company_linkedin_slug + return body + }, + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const errorText = await response.text() + throw new Error(`Wiza API error: ${response.status} - ${errorText}`) + } + + const json = await response.json() + const d = json.data ?? {} + + return { + success: true, + output: { + company_name: d.company_name ?? null, + company_domain: d.company_domain ?? null, + domain: d.domain ?? null, + company_industry: d.company_industry ?? null, + company_size: d.company_size ?? null, + company_size_range: d.company_size_range ?? null, + company_founded: d.company_founded ?? null, + company_revenue_range: d.company_revenue_range ?? null, + company_funding: d.company_funding ?? null, + company_type: d.company_type ?? null, + company_description: d.company_description ?? null, + company_ticker: d.company_ticker ?? null, + company_last_funding_round: d.company_last_funding_round ?? null, + company_last_funding_amount: d.company_last_funding_amount ?? null, + company_last_funding_at: d.company_last_funding_at ?? null, + company_location: d.company_location ?? null, + company_twitter: d.company_twitter ?? null, + company_facebook: d.company_facebook ?? null, + company_linkedin: d.company_linkedin ?? null, + company_linkedin_id: d.company_linkedin_id ?? null, + company_street: d.company_street ?? null, + company_locality: d.company_locality ?? null, + company_region: d.company_region ?? null, + company_postal_code: d.company_postal_code ?? null, + company_country: d.company_country ?? null, + credits: d.credits ?? null, + }, + } + }, + + outputs: { + company_name: { type: 'string', description: 'Company name', optional: true }, + company_domain: { type: 'string', description: 'Company domain', optional: true }, + domain: { type: 'string', description: 'Domain', optional: true }, + company_industry: { type: 'string', description: 'Industry', optional: true }, + company_size: { type: 'number', description: 'Employee count', optional: true }, + company_size_range: { type: 'string', description: 'Headcount range', optional: true }, + company_founded: { type: 'number', description: 'Year founded', optional: true }, + company_revenue_range: { type: 'string', description: 'Revenue range', optional: true }, + company_funding: { type: 'string', description: 'Total funding', optional: true }, + company_type: { type: 'string', description: 'Company type', optional: true }, + company_description: { type: 'string', description: 'Description', optional: true }, + company_ticker: { type: 'string', description: 'Stock ticker', optional: true }, + company_last_funding_round: { + type: 'string', + description: 'Last funding round', + optional: true, + }, + company_last_funding_amount: { + type: 'string', + description: 'Last funding amount', + optional: true, + }, + company_last_funding_at: { type: 'string', description: 'Last funding date', optional: true }, + company_location: { type: 'string', description: 'Full location string', optional: true }, + company_twitter: { type: 'string', description: 'Twitter URL', optional: true }, + company_facebook: { type: 'string', description: 'Facebook URL', optional: true }, + company_linkedin: { type: 'string', description: 'LinkedIn URL', optional: true }, + company_linkedin_id: { type: 'string', description: 'LinkedIn ID', optional: true }, + company_street: { type: 'string', description: 'Street address', optional: true }, + company_locality: { type: 'string', description: 'City', optional: true }, + company_region: { type: 'string', description: 'State/region', optional: true }, + company_postal_code: { type: 'string', description: 'Postal code', optional: true }, + company_country: { type: 'string', description: 'Country', optional: true }, + credits: { type: 'json', description: 'Remaining API credits', optional: true }, + }, +} diff --git a/apps/sim/tools/wiza/get_credits.ts b/apps/sim/tools/wiza/get_credits.ts new file mode 100644 index 00000000000..3ff8f02c2e7 --- /dev/null +++ b/apps/sim/tools/wiza/get_credits.ts @@ -0,0 +1,62 @@ +import type { ToolConfig } from '@/tools/types' +import type { WizaGetCreditsParams, WizaGetCreditsResponse } from '@/tools/wiza/types' + +export const wizaGetCreditsTool: ToolConfig = { + id: 'wiza_get_credits', + name: 'Wiza Get Credits', + description: 'Retrieve the remaining credits on your Wiza account', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Wiza API key', + }, + }, + + request: { + url: 'https://wiza.co/api/meta/credits', + method: 'GET', + headers: (params: WizaGetCreditsParams) => ({ + Authorization: `Bearer ${params.apiKey}`, + 'Content-Type': 'application/json', + }), + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const errorText = await response.text() + throw new Error(`Wiza API error: ${response.status} - ${errorText}`) + } + + const data = await response.json() + const credits = data.credits ?? {} + + return { + success: true, + output: { + email_credits: credits.email_credits ?? null, + phone_credits: credits.phone_credits ?? null, + export_credits: credits.export_credits ?? null, + api_credits: credits.api_credits ?? null, + }, + } + }, + + outputs: { + email_credits: { + type: 'json', + description: 'Remaining email credits (number or "unlimited")', + optional: true, + }, + phone_credits: { + type: 'json', + description: 'Remaining phone credits (number or "unlimited")', + optional: true, + }, + export_credits: { type: 'number', description: 'Remaining export credits', optional: true }, + api_credits: { type: 'number', description: 'Remaining API credits', optional: true }, + }, +} diff --git a/apps/sim/tools/wiza/get_individual_reveal.ts b/apps/sim/tools/wiza/get_individual_reveal.ts new file mode 100644 index 00000000000..52661bb8482 --- /dev/null +++ b/apps/sim/tools/wiza/get_individual_reveal.ts @@ -0,0 +1,163 @@ +import type { ToolConfig } from '@/tools/types' +import type { + WizaGetIndividualRevealParams, + WizaGetIndividualRevealResponse, +} from '@/tools/wiza/types' + +export const wizaGetIndividualRevealTool: ToolConfig< + WizaGetIndividualRevealParams, + WizaGetIndividualRevealResponse +> = { + id: 'wiza_get_individual_reveal', + name: 'Wiza Get Individual Reveal', + description: 'Retrieve the status and enriched data for an individual reveal by ID', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Wiza API key', + }, + id: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Individual reveal ID returned from Start Individual Reveal', + }, + }, + + request: { + url: (params: WizaGetIndividualRevealParams) => + `https://wiza.co/api/individual_reveals/${encodeURIComponent(String(params.id).trim())}`, + method: 'GET', + headers: (params: WizaGetIndividualRevealParams) => ({ + Authorization: `Bearer ${params.apiKey}`, + 'Content-Type': 'application/json', + }), + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const errorText = await response.text() + throw new Error(`Wiza API error: ${response.status} - ${errorText}`) + } + + const json = await response.json() + const d = json.data ?? {} + const emails = Array.isArray(d.emails) ? d.emails : [] + const phones = Array.isArray(d.phones) ? d.phones : [] + + return { + success: true, + output: { + id: d.id ?? null, + status: d.status ?? null, + is_complete: d.is_complete ?? null, + name: d.name ?? null, + company: d.company ?? null, + enrichment_level: d.enrichment_level ?? null, + linkedin_profile_url: d.linkedin_profile_url ?? null, + title: d.title ?? null, + location: d.location ?? null, + email: d.email ?? null, + email_type: d.email_type ?? null, + email_status: d.email_status ?? null, + emails: emails.map((e: Record) => ({ + email: (e.email as string) ?? null, + email_type: (e.email_type as string) ?? null, + email_status: (e.email_status as string) ?? null, + })), + mobile_phone: d.mobile_phone ?? null, + phone_number: d.phone_number ?? null, + phone_status: d.phone_status ?? null, + phones: phones.map((p: Record) => ({ + number: (p.number as string) ?? null, + pretty_number: (p.pretty_number as string) ?? null, + type: (p.type as string) ?? null, + })), + company_size: d.company_size ?? null, + company_size_range: d.company_size_range ?? null, + company_type: d.company_type ?? null, + company_domain: d.company_domain ?? null, + company_locality: d.company_locality ?? null, + company_region: d.company_region ?? null, + company_country: d.company_country ?? null, + company_street: d.company_street ?? null, + company_postal_code: d.company_postal_code ?? null, + company_founded: d.company_founded ?? null, + company_funding: d.company_funding ?? null, + company_revenue: d.company_revenue ?? null, + company_industry: d.company_industry ?? null, + company_subindustry: d.company_subindustry ?? null, + company_linkedin: d.company_linkedin ?? null, + company_location: d.company_location ?? null, + company_description: d.company_description ?? null, + credits: d.credits ?? null, + }, + } + }, + + outputs: { + id: { type: 'number', description: 'Reveal ID' }, + status: { type: 'string', description: 'queued | resolving | finished | failed' }, + is_complete: { type: 'boolean', description: 'Whether the reveal has completed' }, + name: { type: 'string', description: 'Full name', optional: true }, + company: { type: 'string', description: 'Company name', optional: true }, + enrichment_level: { type: 'string', description: 'Enrichment level used', optional: true }, + linkedin_profile_url: { type: 'string', description: 'LinkedIn URL', optional: true }, + title: { type: 'string', description: 'Job title', optional: true }, + location: { type: 'string', description: 'Location', optional: true }, + email: { type: 'string', description: 'Primary email', optional: true }, + email_type: { type: 'string', description: 'Email type', optional: true }, + email_status: { type: 'string', description: 'valid | risky | unfound', optional: true }, + emails: { + type: 'array', + description: 'All emails found', + optional: true, + items: { + type: 'object', + properties: { + email: { type: 'string' }, + email_type: { type: 'string' }, + email_status: { type: 'string' }, + }, + }, + }, + mobile_phone: { type: 'string', description: 'Mobile phone', optional: true }, + phone_number: { type: 'string', description: 'Direct/office phone', optional: true }, + phone_status: { type: 'string', description: 'found | unfound', optional: true }, + phones: { + type: 'array', + description: 'All phones found', + optional: true, + items: { + type: 'object', + properties: { + number: { type: 'string' }, + pretty_number: { type: 'string' }, + type: { type: 'string' }, + }, + }, + }, + company_size: { type: 'number', description: 'Employee count', optional: true }, + company_size_range: { type: 'string', description: 'Headcount range', optional: true }, + company_type: { type: 'string', description: 'Company type', optional: true }, + company_domain: { type: 'string', description: 'Company domain', optional: true }, + company_locality: { type: 'string', description: 'City', optional: true }, + company_region: { type: 'string', description: 'State/region', optional: true }, + company_country: { type: 'string', description: 'Country', optional: true }, + company_street: { type: 'string', description: 'Street', optional: true }, + company_postal_code: { type: 'string', description: 'Postal code', optional: true }, + company_founded: { type: 'number', description: 'Year founded', optional: true }, + company_funding: { type: 'string', description: 'Funding total', optional: true }, + company_revenue: { type: 'string', description: 'Revenue', optional: true }, + company_industry: { type: 'string', description: 'Industry', optional: true }, + company_subindustry: { type: 'string', description: 'Subindustry', optional: true }, + company_linkedin: { type: 'string', description: 'Company LinkedIn URL', optional: true }, + company_location: { type: 'string', description: 'Full company location', optional: true }, + company_description: { type: 'string', description: 'Company description', optional: true }, + credits: { type: 'json', description: 'Remaining credits balance', optional: true }, + }, +} diff --git a/apps/sim/tools/wiza/index.ts b/apps/sim/tools/wiza/index.ts new file mode 100644 index 00000000000..21df6dec38d --- /dev/null +++ b/apps/sim/tools/wiza/index.ts @@ -0,0 +1,6 @@ +export { wizaCompanyEnrichmentTool } from './company_enrichment' +export { wizaGetCreditsTool } from './get_credits' +export { wizaGetIndividualRevealTool } from './get_individual_reveal' +export { wizaProspectSearchTool } from './prospect_search' +export { wizaStartIndividualRevealTool } from './start_individual_reveal' +export type * from './types' diff --git a/apps/sim/tools/wiza/prospect_search.ts b/apps/sim/tools/wiza/prospect_search.ts new file mode 100644 index 00000000000..c507f0cbb61 --- /dev/null +++ b/apps/sim/tools/wiza/prospect_search.ts @@ -0,0 +1,246 @@ +import type { ToolConfig } from '@/tools/types' +import type { WizaProspectSearchParams, WizaProspectSearchResponse } from '@/tools/wiza/types' + +export const wizaProspectSearchTool: ToolConfig< + WizaProspectSearchParams, + WizaProspectSearchResponse +> = { + id: 'wiza_prospect_search', + name: 'Wiza Prospect Search', + description: "Search Wiza's database of prospects using person, company, and financial filters", + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Wiza API key', + }, + size: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Number of sample profiles to return (0-30, default 0)', + }, + filters: { + type: 'object', + required: false, + visibility: 'user-or-llm', + description: 'Full filters object (overrides individual filter params if provided)', + }, + first_name: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Exact first names to match (e.g., ["John", "Jane"])', + }, + last_name: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Exact last names to match', + }, + job_title: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: + 'Job titles to include/exclude (e.g., [{"v":"CEO","s":"i"},{"v":"CTO","s":"e"}])', + }, + job_title_level: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Seniority levels (e.g., ["cxo", "director", "manager"])', + }, + job_role: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Job role categories (e.g., ["sales", "engineering", "marketing"])', + }, + job_sub_role: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Detailed role categories (e.g., ["software", "product"])', + }, + location: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: "Person's location filters (city/state/country with include/exclude)", + }, + skill: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Professional skills (e.g., ["python", "marketing"])', + }, + school: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Educational institutions', + }, + major: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Field of study', + }, + linkedin_slug: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'LinkedIn profile slugs', + }, + job_company: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Current company filters (include/exclude)', + }, + past_company: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Past company filters', + }, + company_location: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Company HQ location filters', + }, + company_industry: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Company industry filters (include/exclude)', + }, + company_size: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Company headcount brackets (e.g., ["1-10", "11-50", "51-200"])', + }, + company_type: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Company type (e.g., ["private", "public", "educational"])', + }, + }, + + request: { + url: 'https://wiza.co/api/prospects/search', + method: 'POST', + headers: (params: WizaProspectSearchParams) => ({ + Authorization: `Bearer ${params.apiKey}`, + 'Content-Type': 'application/json', + }), + body: (params: WizaProspectSearchParams) => { + const body: Record = {} + + if (typeof params.size === 'number') { + body.size = Math.max(0, Math.min(params.size, 30)) + } + + if ( + params.filters && + typeof params.filters === 'object' && + !Array.isArray(params.filters) && + Object.keys(params.filters).length > 0 + ) { + body.filters = params.filters + return body + } + + const filters: Record = {} + const arrayKeys: Array = [ + 'first_name', + 'last_name', + 'job_title', + 'job_title_level', + 'job_role', + 'job_sub_role', + 'location', + 'skill', + 'school', + 'major', + 'linkedin_slug', + 'job_company', + 'past_company', + 'company_location', + 'company_industry', + 'company_size', + 'company_type', + ] + + for (const key of arrayKeys) { + const value = params[key] + if (Array.isArray(value) && value.length > 0) { + filters[key as string] = value + } + } + + if (Object.keys(filters).length > 0) { + body.filters = filters + } + return body + }, + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const errorText = await response.text() + throw new Error(`Wiza API error: ${response.status} - ${errorText}`) + } + + const data = await response.json() + const payload = data.data ?? {} + const profiles = Array.isArray(payload.profiles) ? payload.profiles : [] + + return { + success: true, + output: { + total: payload.total ?? 0, + profiles: profiles.map((p: Record) => ({ + full_name: (p.full_name as string) ?? null, + linkedin_url: (p.linkedin_url as string) ?? null, + industry: (p.industry as string) ?? null, + job_title: (p.job_title as string) ?? null, + job_title_role: (p.job_title_role as string) ?? null, + job_title_sub_role: (p.job_title_sub_role as string) ?? null, + job_company_name: (p.job_company_name as string) ?? null, + job_company_website: (p.job_company_website as string) ?? null, + location_name: (p.location_name as string) ?? null, + })), + }, + } + }, + + outputs: { + total: { type: 'number', description: 'Total number of matching prospects' }, + profiles: { + type: 'array', + description: 'Sample profiles matching the filter criteria', + items: { + type: 'object', + properties: { + full_name: { type: 'string' }, + linkedin_url: { type: 'string' }, + industry: { type: 'string' }, + job_title: { type: 'string' }, + job_title_role: { type: 'string' }, + job_title_sub_role: { type: 'string' }, + job_company_name: { type: 'string' }, + job_company_website: { type: 'string' }, + location_name: { type: 'string' }, + }, + }, + }, + }, +} diff --git a/apps/sim/tools/wiza/start_individual_reveal.ts b/apps/sim/tools/wiza/start_individual_reveal.ts new file mode 100644 index 00000000000..10955e4c548 --- /dev/null +++ b/apps/sim/tools/wiza/start_individual_reveal.ts @@ -0,0 +1,142 @@ +import type { ToolConfig } from '@/tools/types' +import type { + WizaStartIndividualRevealParams, + WizaStartIndividualRevealResponse, +} from '@/tools/wiza/types' + +export const wizaStartIndividualRevealTool: ToolConfig< + WizaStartIndividualRevealParams, + WizaStartIndividualRevealResponse +> = { + id: 'wiza_start_individual_reveal', + name: 'Wiza Start Individual Reveal', + description: + 'Start an individual reveal to enrich a contact via LinkedIn URL, name+company, or email', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Wiza API key', + }, + enrichment_level: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Enrichment depth: none, partial, phone, or full', + }, + profile_url: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'LinkedIn profile URL (e.g., https://linkedin.com/in/johndoe)', + }, + full_name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Full name (used with company or domain)', + }, + company: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Company name (used with full_name)', + }, + domain: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Company domain (used with full_name)', + }, + email: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Email address (use alone or with other identifiers)', + }, + accept_work: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether to accept work emails (email_options)', + }, + accept_personal: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether to accept personal emails (email_options)', + }, + callback_url: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional URL to receive a callback with the reveal update', + }, + }, + + request: { + url: 'https://wiza.co/api/individual_reveals', + method: 'POST', + headers: (params: WizaStartIndividualRevealParams) => ({ + Authorization: `Bearer ${params.apiKey}`, + 'Content-Type': 'application/json', + }), + body: (params: WizaStartIndividualRevealParams) => { + const individual: Record = {} + if (params.profile_url) individual.profile_url = params.profile_url + if (params.full_name) individual.full_name = params.full_name + if (params.company) individual.company = params.company + if (params.domain) individual.domain = params.domain + if (params.email) individual.email = params.email + + const body: Record = { + individual_reveal: individual, + enrichment_level: params.enrichment_level, + } + + if (params.accept_work !== undefined || params.accept_personal !== undefined) { + const emailOptions: Record = {} + if (params.accept_work !== undefined) emailOptions.accept_work = params.accept_work + if (params.accept_personal !== undefined) { + emailOptions.accept_personal = params.accept_personal + } + body.email_options = emailOptions + } + + if (params.callback_url) body.callback_url = params.callback_url + + return body + }, + }, + + transformResponse: async (response: Response) => { + if (!response.ok) { + const errorText = await response.text() + throw new Error(`Wiza API error: ${response.status} - ${errorText}`) + } + + const json = await response.json() + const d = json.data ?? {} + + return { + success: true, + output: { + id: d.id ?? null, + status: d.status ?? null, + is_complete: d.is_complete ?? null, + }, + } + }, + + outputs: { + id: { type: 'number', description: 'Individual reveal ID (use with Get Individual Reveal)' }, + status: { + type: 'string', + description: 'Reveal status: queued, resolving, finished, or failed', + }, + is_complete: { type: 'boolean', description: 'Whether the reveal has completed' }, + }, +} diff --git a/apps/sim/tools/wiza/types.ts b/apps/sim/tools/wiza/types.ts new file mode 100644 index 00000000000..f75e794f622 --- /dev/null +++ b/apps/sim/tools/wiza/types.ts @@ -0,0 +1,178 @@ +import type { ToolResponse } from '@/tools/types' + +export interface WizaGetCreditsParams { + apiKey: string +} + +export interface WizaGetCreditsResponse extends ToolResponse { + output: { + email_credits: number | string | null + phone_credits: number | string | null + export_credits: number | null + api_credits: number | null + } +} + +export interface WizaProspectSearchParams { + apiKey: string + size?: number + filters?: Record + first_name?: string[] + last_name?: string[] + job_title?: unknown[] + job_title_level?: string[] + job_role?: string[] + job_sub_role?: string[] + location?: unknown[] + skill?: string[] + school?: string[] + major?: string[] + linkedin_slug?: string[] + job_company?: unknown[] + past_company?: unknown[] + company_location?: unknown[] + company_industry?: unknown[] + company_size?: string[] + company_type?: string[] +} + +interface WizaProspectProfile { + full_name: string | null + linkedin_url: string | null + industry: string | null + job_title: string | null + job_title_role: string | null + job_title_sub_role: string | null + job_company_name: string | null + job_company_website: string | null + location_name: string | null +} + +export interface WizaProspectSearchResponse extends ToolResponse { + output: { + total: number + profiles: WizaProspectProfile[] + } +} + +export interface WizaCompanyEnrichmentParams { + apiKey: string + company_name?: string + company_domain?: string + company_linkedin_id?: string + company_linkedin_slug?: string +} + +export interface WizaCompanyEnrichmentResponse extends ToolResponse { + output: { + company_name: string | null + company_domain: string | null + domain: string | null + company_industry: string | null + company_size: number | null + company_size_range: string | null + company_founded: number | null + company_revenue_range: string | null + company_funding: string | null + company_type: string | null + company_description: string | null + company_ticker: string | null + company_last_funding_round: string | null + company_last_funding_amount: string | null + company_last_funding_at: string | null + company_location: string | null + company_twitter: string | null + company_facebook: string | null + company_linkedin: string | null + company_linkedin_id: string | null + company_street: string | null + company_locality: string | null + company_region: string | null + company_postal_code: string | null + company_country: string | null + credits: Record | null + } +} + +export interface WizaStartIndividualRevealParams { + apiKey: string + enrichment_level: 'none' | 'partial' | 'phone' | 'full' + profile_url?: string + full_name?: string + company?: string + domain?: string + email?: string + accept_work?: boolean + accept_personal?: boolean + callback_url?: string +} + +interface WizaIndividualRevealData { + id: number | null + status: string | null + is_complete: boolean | null + name: string | null + company: string | null + enrichment_level: string | null + linkedin_profile_url: string | null + title: string | null + location: string | null + email: string | null + email_type: string | null + email_status: string | null + emails: Array<{ + email: string | null + email_type: string | null + email_status: string | null + }> + mobile_phone: string | null + phone_number: string | null + phone_status: string | null + phones: Array<{ + number: string | null + pretty_number: string | null + type: string | null + }> + company_size: number | null + company_size_range: string | null + company_type: string | null + company_domain: string | null + company_locality: string | null + company_region: string | null + company_country: string | null + company_street: string | null + company_postal_code: string | null + company_founded: number | null + company_funding: string | null + company_revenue: string | null + company_industry: string | null + company_subindustry: string | null + company_linkedin: string | null + company_location: string | null + company_description: string | null + credits: Record | null +} + +export interface WizaStartIndividualRevealResponse extends ToolResponse { + output: { + id: number | null + status: string | null + is_complete: boolean | null + } +} + +export interface WizaGetIndividualRevealParams { + apiKey: string + id: string +} + +export interface WizaGetIndividualRevealResponse extends ToolResponse { + output: WizaIndividualRevealData +} + +export type WizaResponse = + | WizaGetCreditsResponse + | WizaProspectSearchResponse + | WizaCompanyEnrichmentResponse + | WizaStartIndividualRevealResponse + | WizaGetIndividualRevealResponse From 6414b9381d6032463b82635d02800f40bf8bd412 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 19 May 2026 12:19:54 -0700 Subject: [PATCH 05/13] improvement(cleanup): cleanup refs along in logs cleanup job (#4661) * improvement(cleanup): cleanup refs along in logs cleanup job * address comments * cleanup code --- apps/sim/background/cleanup-logs.ts | 130 +++++++++++-- apps/sim/lib/billing/cleanup-dispatcher.ts | 202 ++++++++++++++------- apps/sim/lib/billing/core/billing.ts | 13 +- apps/sim/lib/billing/core/plan.ts | 73 ++++++-- apps/sim/lib/billing/core/subscription.ts | 7 +- 5 files changed, 329 insertions(+), 96 deletions(-) diff --git a/apps/sim/background/cleanup-logs.ts b/apps/sim/background/cleanup-logs.ts index 41fb5189357..1f09fa16ecc 100644 --- a/apps/sim/background/cleanup-logs.ts +++ b/apps/sim/background/cleanup-logs.ts @@ -1,14 +1,15 @@ import { db } from '@sim/db' -import { jobExecutionLogs, workflowExecutionLogs } from '@sim/db/schema' +import { jobExecutionLogs, pausedExecutions, workflowExecutionLogs } from '@sim/db/schema' import { createLogger } from '@sim/logger' import { task } from '@trigger.dev/sdk' -import { and, inArray, lt } from 'drizzle-orm' +import { and, eq, inArray, isNull, lt, notInArray, or, sql } from 'drizzle-orm' import { type CleanupJobPayload, resolveCleanupScope } from '@/lib/billing/cleanup-dispatcher' import { batchDeleteByWorkspaceAndTimestamp, chunkedBatchDelete, type TableCleanupResult, } from '@/lib/cleanup/batch-delete' +import { collectLargeValueKeys } from '@/lib/execution/payloads/large-execution-value' import { snapshotService } from '@/lib/logs/execution/snapshot/service' import { isUsingCloudStorage, StorageService } from '@/lib/uploads' import { deleteFileMetadata } from '@/lib/uploads/server/metadata' @@ -19,6 +20,38 @@ interface FileDeleteStats { filesTotal: number filesDeleted: number filesDeleteFailed: number + largeValuesTotal: number + largeValuesDeleted: number + largeValuesDeleteFailed: number +} + +const RESUMABLE_PAUSED_STATUSES = ['paused', 'partially_resumed', 'cancelling'] + +async function filterLargeValueKeysWithoutRetainedReferences( + keys: string[], + deletedLogIds: string[] +): Promise { + if (keys.length === 0 || deletedLogIds.length === 0) return [] + + const unreferencedKeys: string[] = [] + for (const key of Array.from(new Set(keys))) { + const [referencingLog] = await db + .select({ id: workflowExecutionLogs.id }) + .from(workflowExecutionLogs) + .where( + and( + notInArray(workflowExecutionLogs.id, deletedLogIds), + sql`position(${key} in ${workflowExecutionLogs.executionData}::text) > 0` + ) + ) + .limit(1) + + if (!referencingLog) { + unreferencedKeys.push(key) + } + } + + return unreferencedKeys } async function deleteExecutionFiles(files: unknown, stats: FileDeleteStats): Promise { @@ -41,12 +74,39 @@ async function deleteExecutionFiles(files: unknown, stats: FileDeleteStats): Pro ) } +async function deleteLargeValueStorageKeys(keys: string[], stats: FileDeleteStats): Promise { + if (!isUsingCloudStorage() || keys.length === 0) return + + const uniqueKeys = Array.from(new Set(keys)) + stats.largeValuesTotal += uniqueKeys.length + + await Promise.all( + uniqueKeys.map(async (key) => { + try { + await StorageService.deleteFile({ key, context: 'execution' }) + await deleteFileMetadata(key) + stats.largeValuesDeleted++ + } catch (error) { + stats.largeValuesDeleteFailed++ + logger.error(`Failed to delete large execution value ${key}:`, { error }) + } + }) + ) +} + async function cleanupWorkflowExecutionLogs( workspaceIds: string[], retentionDate: Date, label: string ): Promise { - const fileStats: FileDeleteStats = { filesTotal: 0, filesDeleted: 0, filesDeleteFailed: 0 } + const fileStats: FileDeleteStats = { + filesTotal: 0, + filesDeleted: 0, + filesDeleteFailed: 0, + largeValuesTotal: 0, + largeValuesDeleted: 0, + largeValuesDeleteFailed: 0, + } const dbStats = await chunkedBatchDelete({ tableDef: workflowExecutionLogs, @@ -54,23 +114,63 @@ async function cleanupWorkflowExecutionLogs( tableName: `${label}/workflow_execution_logs`, selectChunk: (chunkIds, limit) => db - .select({ id: workflowExecutionLogs.id, files: workflowExecutionLogs.files }) + .select({ + id: workflowExecutionLogs.id, + executionId: workflowExecutionLogs.executionId, + executionData: workflowExecutionLogs.executionData, + files: workflowExecutionLogs.files, + }) .from(workflowExecutionLogs) + .leftJoin( + pausedExecutions, + eq(pausedExecutions.executionId, workflowExecutionLogs.executionId) + ) .where( and( inArray(workflowExecutionLogs.workspaceId, chunkIds), - lt(workflowExecutionLogs.startedAt, retentionDate) + lt(workflowExecutionLogs.startedAt, retentionDate), + or( + isNull(pausedExecutions.status), + notInArray(pausedExecutions.status, RESUMABLE_PAUSED_STATUSES) + ) ) ) .limit(limit), onBatch: async (rows) => { - for (const row of rows) await deleteExecutionFiles(row.files, fileStats) + const deletedLogIds = rows.map((row) => row.id) + const largeValueKeys = rows.flatMap((row) => collectLargeValueKeys(row.executionData)) + const unreferencedLargeValueKeys = await filterLargeValueKeysWithoutRetainedReferences( + largeValueKeys, + deletedLogIds + ) + + for (const row of rows) { + await deleteExecutionFiles(row.files, fileStats) + } + await deleteLargeValueStorageKeys(unreferencedLargeValueKeys, fileStats) }, }) return { ...dbStats, ...fileStats } } +async function cleanupFreePlanOrphanedSnapshots( + payload: CleanupJobPayload, + retentionHours: number +): Promise { + if (payload.plan !== 'free') { + return + } + + try { + const retentionDays = Math.floor(retentionHours / 24) + const snapshotsCleaned = await snapshotService.cleanupOrphanedSnapshots(retentionDays + 1) + logger.info(`Cleaned up ${snapshotsCleaned} orphaned snapshots`) + } catch (snapshotError) { + logger.error('Error cleaning up orphaned snapshots:', { snapshotError }) + } +} + export async function runCleanupLogs(payload: CleanupJobPayload): Promise { const startTime = Date.now() @@ -82,12 +182,14 @@ export async function runCleanupLogs(payload: CleanupJobPayload): Promise const { workspaceIds, retentionHours, label } = scope + const retentionDate = new Date(Date.now() - retentionHours * 60 * 60 * 1000) + if (workspaceIds.length === 0) { logger.info(`[${label}] No workspaces to process`) + await cleanupFreePlanOrphanedSnapshots(payload, retentionHours) return } - const retentionDate = new Date(Date.now() - retentionHours * 60 * 60 * 1000) logger.info( `[${label}] Cleaning ${workspaceIds.length} workspaces, cutoff: ${retentionDate.toISOString()}` ) @@ -96,6 +198,9 @@ export async function runCleanupLogs(payload: CleanupJobPayload): Promise logger.info( `[${label}] workflow_execution_logs files: ${workflowResults.filesDeleted}/${workflowResults.filesTotal} deleted, ${workflowResults.filesDeleteFailed} failed` ) + logger.info( + `[${label}] workflow_execution_logs large values: ${workflowResults.largeValuesDeleted}/${workflowResults.largeValuesTotal} deleted, ${workflowResults.largeValuesDeleteFailed} failed` + ) await batchDeleteByWorkspaceAndTimestamp({ tableDef: jobExecutionLogs, @@ -106,16 +211,7 @@ export async function runCleanupLogs(payload: CleanupJobPayload): Promise tableName: `${label}/job_execution_logs`, }) - // Snapshot cleanup runs only on the free job to avoid running it N times for N enterprise workspaces. - if (payload.plan === 'free') { - try { - const retentionDays = Math.floor(retentionHours / 24) - const snapshotsCleaned = await snapshotService.cleanupOrphanedSnapshots(retentionDays + 1) - logger.info(`Cleaned up ${snapshotsCleaned} orphaned snapshots`) - } catch (snapshotError) { - logger.error('Error cleaning up orphaned snapshots:', { snapshotError }) - } - } + await cleanupFreePlanOrphanedSnapshots(payload, retentionHours) const timeElapsed = (Date.now() - startTime) / 1000 logger.info(`[${label}] Job completed in ${timeElapsed.toFixed(2)}s`) diff --git a/apps/sim/lib/billing/cleanup-dispatcher.ts b/apps/sim/lib/billing/cleanup-dispatcher.ts index 2ee91159b70..3c1c5cd81d8 100644 --- a/apps/sim/lib/billing/cleanup-dispatcher.ts +++ b/apps/sim/lib/billing/cleanup-dispatcher.ts @@ -1,14 +1,17 @@ import { db } from '@sim/db' -import { organization, subscription, workspace } from '@sim/db/schema' +import type { WorkspaceMode } from '@sim/db/schema' +import { organization, workspace } from '@sim/db/schema' import { createLogger } from '@sim/logger' import { tasks } from '@trigger.dev/sdk' -import { and, eq, inArray, isNotNull, isNull, sql } from 'drizzle-orm' -import { type PlanCategory, sqlIsPaid, sqlIsPro, sqlIsTeam } from '@/lib/billing/plan-helpers' -import { ENTITLED_SUBSCRIPTION_STATUSES } from '@/lib/billing/subscriptions/utils' +import { eq, isNull } from 'drizzle-orm' +import { getOrganizationSubscription } from '@/lib/billing/core/billing' +import { getHighestPriorityPersonalSubscription } from '@/lib/billing/core/subscription' +import { getPlanType, type PlanCategory } from '@/lib/billing/plan-helpers' import { getJobQueue } from '@/lib/core/async-jobs' import { shouldExecuteInline } from '@/lib/core/async-jobs/config' import type { EnqueueOptions } from '@/lib/core/async-jobs/types' import { isTriggerAvailable } from '@/lib/knowledge/documents/service' +import { isOrganizationWorkspace, WORKSPACE_MODE } from '@/lib/workspaces/policy' const logger = createLogger('RetentionDispatcher') @@ -38,8 +41,18 @@ interface CleanupJobConfig { defaults: Record } +interface WorkspaceCleanupScopeRow { + id: string + billedAccountUserId: string + organizationId: string | null + workspaceMode: WorkspaceMode + organizationSettings: OrganizationRetentionSettings | null +} + const DAY = 24 +type PlanResolutionEntry = readonly [string, PlanCategory] + /** * Single source of truth for cleanup retention: which key each job type reads * from `organization.dataRetentionSettings`, and the default retention (in @@ -61,44 +74,112 @@ export const CLEANUP_CONFIG = { }, } as const satisfies Record -/** - * Bulk-lookup workspace IDs for a non-enterprise plan category. Enterprise is - * per-workspace (routed through the owning organization's retention config). - */ -async function resolveWorkspaceIdsForPlan(plan: NonEnterprisePlan): Promise { - if (plan === 'free') { - const rows = await db - .select({ id: workspace.id }) - .from(workspace) - .leftJoin( - subscription, - and( - eq(subscription.referenceId, workspace.billedAccountUserId), - inArray(subscription.status, ENTITLED_SUBSCRIPTION_STATUSES), - sqlIsPaid(subscription.plan) - ) - ) - .where(and(isNull(subscription.id), isNull(workspace.archivedAt))) - - return rows.map((r) => r.id) - } - - const planPredicate = plan === 'pro' ? sqlIsPro(subscription.plan) : sqlIsTeam(subscription.plan) +async function listActiveWorkspaceCleanupScopeRows(): Promise { const rows = await db - .select({ id: workspace.id }) + .select({ + id: workspace.id, + billedAccountUserId: workspace.billedAccountUserId, + organizationId: workspace.organizationId, + workspaceMode: workspace.workspaceMode, + organizationSettings: organization.dataRetentionSettings, + }) .from(workspace) - .innerJoin( - subscription, - and( - eq(subscription.referenceId, workspace.billedAccountUserId), - inArray(subscription.status, ENTITLED_SUBSCRIPTION_STATUSES), - planPredicate! - ) - ) + .leftJoin(organization, eq(organization.id, workspace.organizationId)) .where(isNull(workspace.archivedAt)) - .groupBy(workspace.id) - return rows.map((r) => r.id) + return rows.map((row) => ({ + ...row, + organizationSettings: + (row.organizationSettings as OrganizationRetentionSettings | null) ?? null, + })) +} + +async function resolvePersonalPlanTypesByBilledUserId( + rows: WorkspaceCleanupScopeRow[] +): Promise> { + const billedUserIds = Array.from(new Set(rows.map((row) => row.billedAccountUserId))) + const entries = await Promise.all( + billedUserIds.map(async (userId) => { + try { + const subscription = await getHighestPriorityPersonalSubscription(userId, { + onError: 'throw', + }) + return [userId, getPlanType(subscription?.plan)] as const + } catch (error) { + logger.error('Skipping cleanup for billed user after plan lookup failed', { + userId, + error, + }) + return null + } + }) + ) + + return new Map(entries.filter((entry): entry is PlanResolutionEntry => entry !== null)) +} + +async function resolvePlanTypesByWorkspaceId( + rows: WorkspaceCleanupScopeRow[] +): Promise> { + const userScopedRows = rows.filter((row) => row.workspaceMode !== WORKSPACE_MODE.ORGANIZATION) + const userPlanByBilledUserId = await resolvePersonalPlanTypesByBilledUserId(userScopedRows) + const entries = await Promise.all( + rows.map(async (row) => { + if (row.workspaceMode === WORKSPACE_MODE.ORGANIZATION) { + const organizationId = isOrganizationWorkspace(row) ? row.organizationId : null + if (!organizationId) { + logger.error('Skipping cleanup for malformed organization workspace', { + workspaceId: row.id, + organizationId: row.organizationId, + }) + return null + } + + try { + const subscription = await getOrganizationSubscription(organizationId, { + onError: 'throw', + }) + if (!subscription) { + logger.warn('Skipping cleanup for organization workspace without an org subscription', { + workspaceId: row.id, + organizationId, + }) + return null + } + + return [row.id, getPlanType(subscription?.plan)] as const + } catch (error) { + logger.error('Skipping cleanup for organization workspace after plan lookup failed', { + workspaceId: row.id, + organizationId, + error, + }) + return null + } + } + + const plan = userPlanByBilledUserId.get(row.billedAccountUserId) + if (plan === undefined) { + return null + } + + return [row.id, plan] as const + }) + ) + + return new Map(entries.filter((entry): entry is PlanResolutionEntry => entry !== null)) +} + +/** + * Bulk-lookup workspace IDs for a non-enterprise plan category using the same + * effective-plan lookup used by execution, limits, and workspace policy. + * Enterprise is per-workspace (routed through the owning organization's + * retention config). + */ +async function resolveWorkspaceIdsForPlan(plan: NonEnterprisePlan): Promise { + const rows = await listActiveWorkspaceCleanupScopeRows() + const planByWorkspaceId = await resolvePlanTypesByWorkspaceId(rows) + return rows.filter((row) => planByWorkspaceId.get(row.id) === plan).map((row) => row.id) } export interface ResolvedCleanupScope { @@ -127,12 +208,26 @@ export async function resolveCleanupScope( } const [row] = await db - .select({ settings: organization.dataRetentionSettings }) + .select({ + id: workspace.id, + organizationId: workspace.organizationId, + workspaceMode: workspace.workspaceMode, + billedAccountUserId: workspace.billedAccountUserId, + settings: organization.dataRetentionSettings, + }) .from(workspace) .innerJoin(organization, eq(organization.id, workspace.organizationId)) .where(eq(workspace.id, payload.workspaceId)) .limit(1) + if (!row || !isOrganizationWorkspace(row)) return null + + const organizationId = row.organizationId + if (!organizationId) return null + + const subscription = await getOrganizationSubscription(organizationId, { onError: 'throw' }) + if (getPlanType(subscription?.plan) !== 'enterprise') return null + const hours = row?.settings?.[config.key] if (hours == null) return null @@ -185,28 +280,13 @@ export async function dispatchCleanupJobs( jobIds.push(jobId) } - // Enterprise: workspaces whose owning org is on an active enterprise sub and - // has a non-NULL value for this job's retention key. groupBy dedupes in case - // multiple entitled subscription rows exist for the same org. - const enterpriseRows = await db - .select({ id: workspace.id }) - .from(workspace) - .innerJoin(organization, eq(organization.id, workspace.organizationId)) - .innerJoin( - subscription, - and( - eq(subscription.referenceId, organization.id), - inArray(subscription.status, ENTITLED_SUBSCRIPTION_STATUSES), - eq(subscription.plan, 'enterprise') - ) - ) - .where( - and( - isNull(workspace.archivedAt), - isNotNull(sql`${organization.dataRetentionSettings}->>${config.key}`) - ) - ) - .groupBy(workspace.id) + const activeWorkspaceRows = await listActiveWorkspaceCleanupScopeRows() + const planByWorkspaceId = await resolvePlanTypesByWorkspaceId(activeWorkspaceRows) + const enterpriseRows = activeWorkspaceRows.filter( + (row) => + planByWorkspaceId.get(row.id) === 'enterprise' && + row.organizationSettings?.[config.key] != null + ) const enterpriseCount = enterpriseRows.length diff --git a/apps/sim/lib/billing/core/billing.ts b/apps/sim/lib/billing/core/billing.ts index e56261a62a9..78c359ed569 100644 --- a/apps/sim/lib/billing/core/billing.ts +++ b/apps/sim/lib/billing/core/billing.ts @@ -28,6 +28,10 @@ import { createLogger } from '@sim/logger' const logger = createLogger('Billing') +interface GetOrganizationSubscriptionOptions { + onError?: 'return-null' | 'throw' +} + /** * Get the organization's subscription row when its status is one of * `ENTITLED_SUBSCRIPTION_STATUSES` (includes `past_due`). Use this @@ -37,7 +41,11 @@ const logger = createLogger('Billing') * (from `core/subscription.ts`), which excludes `past_due`. * Returns `null` when there is no entitled sub. */ -export async function getOrganizationSubscription(organizationId: string) { +export async function getOrganizationSubscription( + organizationId: string, + options: GetOrganizationSubscriptionOptions = {} +) { + const { onError = 'return-null' } = options try { const orgSubs = await db .select() @@ -54,6 +62,9 @@ export async function getOrganizationSubscription(organizationId: string) { return orgSubs.length > 0 ? orgSubs[0] : null } catch (error) { logger.error('Error getting organization subscription', { error, organizationId }) + if (onError === 'throw') { + throw error + } return null } } diff --git a/apps/sim/lib/billing/core/plan.ts b/apps/sim/lib/billing/core/plan.ts index cb8fea848db..8bbd516ee10 100644 --- a/apps/sim/lib/billing/core/plan.ts +++ b/apps/sim/lib/billing/core/plan.ts @@ -13,6 +13,52 @@ const logger = createLogger('PlanLookup') export type HighestPrioritySubscription = Awaited> +interface GetHighestPrioritySubscriptionOptions { + onError?: 'return-null' | 'throw' +} + +function pickHighestPrioritySubscription( + subscriptions: TSubscription[], + predicates: Array<(subscription: TSubscription) => boolean> +): TSubscription | null { + for (const predicate of predicates) { + const match = subscriptions.find(predicate) + if (match) return match + } + + return null +} + +export async function getHighestPriorityPersonalSubscription( + userId: string, + options: GetHighestPrioritySubscriptionOptions = {} +) { + const { onError = 'return-null' } = options + try { + const personalSubs = await db + .select() + .from(subscription) + .where( + and( + eq(subscription.referenceId, userId), + inArray(subscription.status, ENTITLED_SUBSCRIPTION_STATUSES) + ) + ) + + return pickHighestPrioritySubscription(personalSubs, [ + checkEnterprisePlan, + checkTeamPlan, + checkProPlan, + ]) + } catch (error) { + logger.error('Error getting highest priority personal subscription', { error, userId }) + if (onError === 'throw') { + throw error + } + return null + } +} + /** * Get the highest priority paid subscription for a user. * @@ -27,7 +73,11 @@ export type HighestPrioritySubscription = Awaited boolean) => - orgSubs.find(predicate) ?? personalSubs.find(predicate) - - const enterpriseSub = pickAtTier(checkEnterprisePlan) - if (enterpriseSub) return enterpriseSub - - const teamSub = pickAtTier(checkTeamPlan) - if (teamSub) return teamSub - - const proSub = pickAtTier(checkProPlan) - if (proSub) return proSub - - return null + return pickHighestPrioritySubscription( + [...orgSubs, ...personalSubs], + [checkEnterprisePlan, checkTeamPlan, checkProPlan] + ) } catch (error) { logger.error('Error getting highest priority subscription', { error, userId }) + if (onError === 'throw') { + throw error + } return null } } diff --git a/apps/sim/lib/billing/core/subscription.ts b/apps/sim/lib/billing/core/subscription.ts index 75dfd706291..550fdcd3400 100644 --- a/apps/sim/lib/billing/core/subscription.ts +++ b/apps/sim/lib/billing/core/subscription.ts @@ -3,7 +3,10 @@ import { member, organization, subscription, user } from '@sim/db/schema' import { createLogger } from '@sim/logger' import { and, eq, inArray, sql } from 'drizzle-orm' import { getEffectiveBillingStatus, isOrganizationBillingBlocked } from '@/lib/billing/core/access' -import { getHighestPrioritySubscription } from '@/lib/billing/core/plan' +import { + getHighestPriorityPersonalSubscription, + getHighestPrioritySubscription, +} from '@/lib/billing/core/plan' import { getPlanTierCredits, isPro as isPlanPro, @@ -29,7 +32,7 @@ import { getBaseUrl } from '@/lib/core/utils/urls' const logger = createLogger('SubscriptionCore') -export { getHighestPrioritySubscription } +export { getHighestPriorityPersonalSubscription, getHighestPrioritySubscription } export interface SubscriptionMetadata { billingInterval?: 'month' | 'year' From 49f70bc6355a300909abea49435125bf892536bf Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 19 May 2026 13:34:49 -0700 Subject: [PATCH 06/13] fix(docker): restore NEXT_PUBLIC_APP_URL build arg with dummy fallback (#4665) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(docker): restore NEXT_PUBLIC_APP_URL build arg with dummy fallback getBaseUrl() in lib/core/utils/urls is evaluated at module load during next build's page-data collection and throws if NEXT_PUBLIC_APP_URL is unset. PR #4658 removed the build arg, breaking the Docker build at the "/_not-found" page-data collection step. Restore the dummy localhost fallback (mirroring DATABASE_URL). The CORS fix from #4658 is preserved: next.config.ts no longer reads NEXT_PUBLIC_APP_URL at build time, and no module-level expression captures getBaseUrl() — every caller invokes it at request time, where getEnv() reads the deployed container env. The dummy localhost value cannot leak into runtime CORS response headers. Co-Authored-By: Claude Opus 4.7 * chore(docker): trim verbose comment on build-time env args Co-Authored-By: Claude Opus 4.7 --------- Co-authored-by: Claude Opus 4.7 --- docker/app.Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docker/app.Dockerfile b/docker/app.Dockerfile index 79400246492..67eb5f02c77 100644 --- a/docker/app.Dockerfile +++ b/docker/app.Dockerfile @@ -69,11 +69,13 @@ ENV NEXT_TELEMETRY_DISABLED=1 \ VERCEL_TELEMETRY_DISABLED=1 \ DOCKER_BUILD=1 -# Provide dummy database URLs during image build so server code that imports @sim/db -# can be evaluated without crashing. Runtime environments should override these. +# Dummy values so next build can evaluate modules. Override at runtime. ARG DATABASE_URL="postgresql://user:pass@localhost:5432/dummy" ENV DATABASE_URL=${DATABASE_URL} +ARG NEXT_PUBLIC_APP_URL="http://localhost:3000" +ENV NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL} + # Per-platform cache id keeps arm64/amd64 SWC artifacts isolated. RUN --mount=type=cache,id=next-cache-${TARGETPLATFORM},target=/app/apps/sim/.next/cache \ --mount=type=cache,id=turbo-cache-${TARGETPLATFORM},target=/app/.turbo \ From df1e2ddc2eaeac27571e7f4e5028961ef6de8e1c Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 19 May 2026 14:10:42 -0700 Subject: [PATCH 07/13] feat(azure-devops): block and trigger (#4664) * azure devops logo on white * generated ADO tool docs * generated ADO tool docs * added ADO to registries * ADO workflow triggers * ADO workflow triggers * tool layer for ADO, checks passed and manual verified * ADO workflow triggers * block layer for ADO * ADO icon svg * generated docs for ADO triggers * committing the tests for azure devops tools and blocks * Update apps/sim/triggers/azure_devops/utils.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update apps/sim/tools/azure_devops/update_work_item.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update apps/sim/triggers/azure_devops/utils.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * comma syntax error patched * azure devops: validate-integration fixes + manual description - bgColor switched from white to Azure DevOps brand color #0078D4 (block + mdx) - WIQL query_work_items: hydrate ALL matched IDs by chunking through batches of 200 instead of silently truncating; check response.ok on the follow-up fetch and surface a clear error on 4xx/5xx; trim org/project; expose totalMatched in metadata so users can see pre-hydration count - Add MANUAL-CONTENT-START:intro section to the azure_devops.mdx docs page - Update unit tests for new chunking behavior and update-work-item validation Co-Authored-By: Claude Opus 4.7 * azure_devops: second-pass audit fixes + formatter cleanup - Add types barrel export to tools/azure_devops/index.ts - Normalize comment endpoint path casing (/workItems/ -> /workitems/) - Update test assertions to match normalized path - Biome formatter reflow across tools, triggers, registry, and docs icon Co-Authored-By: Claude Opus 4.7 * azure_devops: address PR review comments - Fix bgColor #FFFFFF -> #0078D4 in integrations.json and triggers/azure_devops.mdx - Bump File tool operationCount from 4 to 5 (Read, Fetch, Get, Write, Append) - Apply .trim() to org/project across all 15 remaining tools (consistency with query_work_items) - Fix Found ${data.count} -> Found ${data.count ?? items.length} fallback in list_builds, list_pipelines, list_pipeline_runs content strings Co-Authored-By: Claude Opus 4.7 * idemtpotency * azure_devops: address bugbot review comments - triggers/utils: match build.complete result case-insensitively, accept stopped/cancelled in addition to failed/canceled/partiallySucceeded so PascalCase and legacy Azure DevOps payloads aren't dropped - get_work_items_batch: chunk comma-separated IDs into 200-batch loops with proper status checks (was failing or returning incomplete data on >200 IDs) - Add tests for both behaviors Co-Authored-By: Claude Opus 4.7 * azure_devops: address additional bugbot comments - Block update_work_item now forwards areaPath; the Area Path subblock condition expanded to include update operation - get_build_timeline.failedRecords now also flags partiallySucceeded and succeededWithIssues, normalized case-insensitively. Output description and added a focused test Co-Authored-By: Claude Opus 4.7 * azure_devops: address more bugbot comments - Webhook provider extractIdempotencyId returns null when subscriptionId or notificationId is missing/empty, preventing the literal "azure_devops:undefined:undefined" key from collapsing unrelated deliveries into duplicates - Get Work Items Batch validates that at least one non-empty ID is supplied before issuing the API request, throwing a clear error instead of hitting an empty ids= query - Tests cover both behaviors Co-Authored-By: Claude Opus 4.7 * azure_devops: pin add_comment to documented api-version 7.0-preview.3 Microsoft's Add Comments docs only publish 7.0-preview.3 (the 7.2 view falls back to the 7.0 page). Get Comments stays on the documented 7.2-preview.4. Matches what's strictly in the Azure DevOps REST API reference rather than relying on undocumented version behavior. Co-Authored-By: Claude Opus 4.7 --------- Co-authored-by: Marcus Chandra Co-authored-by: mzxchandra <129460234+mzxchandra@users.noreply.github.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 --- apps/docs/components/icons.tsx | 30 + apps/docs/components/ui/icon-mapping.ts | 2 + .../content/docs/en/tools/azure_devops.mdx | 554 ++++++++++++ apps/docs/content/docs/en/tools/meta.json | 1 + .../content/docs/en/triggers/azure_devops.mdx | 83 ++ apps/docs/content/docs/en/triggers/meta.json | 1 + .../integrations/data/icon-mapping.ts | 2 + .../integrations/data/integrations.json | 105 ++- apps/sim/blocks/blocks/azure_devops.test.ts | 162 ++++ apps/sim/blocks/blocks/azure_devops.ts | 627 ++++++++++++++ apps/sim/blocks/registry.ts | 2 + apps/sim/components/icons.tsx | 30 + .../lib/webhooks/providers/azure-devops.ts | 90 ++ apps/sim/lib/webhooks/providers/registry.ts | 2 + apps/sim/tools/azure_devops/add_comment.ts | 122 +++ .../tools/azure_devops/azure-devops.test.ts | 788 ++++++++++++++++++ .../tools/azure_devops/create_work_item.ts | 247 ++++++ apps/sim/tools/azure_devops/get_build_log.ts | 101 +++ .../tools/azure_devops/get_build_timeline.ts | 164 ++++ apps/sim/tools/azure_devops/get_comments.ts | 186 +++++ apps/sim/tools/azure_devops/get_pipeline.ts | 167 ++++ .../tools/azure_devops/get_pipeline_run.ts | 157 ++++ apps/sim/tools/azure_devops/get_work_item.ts | 103 +++ .../azure_devops/get_work_items_batch.ts | 173 ++++ .../get_work_items_between_builds.ts | 126 +++ apps/sim/tools/azure_devops/index.ts | 37 + .../sim/tools/azure_devops/list_build_logs.ts | 134 +++ apps/sim/tools/azure_devops/list_builds.ts | 203 +++++ .../tools/azure_devops/list_pipeline_runs.ts | 149 ++++ apps/sim/tools/azure_devops/list_pipelines.ts | 133 +++ .../tools/azure_devops/query_work_items.ts | 164 ++++ apps/sim/tools/azure_devops/types.ts | 458 ++++++++++ .../tools/azure_devops/update_work_item.ts | 268 ++++++ apps/sim/tools/azure_devops/utils.ts | 120 +++ apps/sim/tools/registry.ts | 34 + .../sim/triggers/azure_devops/build_failed.ts | 34 + apps/sim/triggers/azure_devops/index.ts | 3 + apps/sim/triggers/azure_devops/utils.ts | 283 +++++++ apps/sim/triggers/azure_devops/webhook.ts | 37 + .../azure_devops/work_item_created.ts | 32 + apps/sim/triggers/registry.ts | 8 + 41 files changed, 6121 insertions(+), 1 deletion(-) create mode 100644 apps/docs/content/docs/en/tools/azure_devops.mdx create mode 100644 apps/docs/content/docs/en/triggers/azure_devops.mdx create mode 100644 apps/sim/blocks/blocks/azure_devops.test.ts create mode 100644 apps/sim/blocks/blocks/azure_devops.ts create mode 100644 apps/sim/lib/webhooks/providers/azure-devops.ts create mode 100644 apps/sim/tools/azure_devops/add_comment.ts create mode 100644 apps/sim/tools/azure_devops/azure-devops.test.ts create mode 100644 apps/sim/tools/azure_devops/create_work_item.ts create mode 100644 apps/sim/tools/azure_devops/get_build_log.ts create mode 100644 apps/sim/tools/azure_devops/get_build_timeline.ts create mode 100644 apps/sim/tools/azure_devops/get_comments.ts create mode 100644 apps/sim/tools/azure_devops/get_pipeline.ts create mode 100644 apps/sim/tools/azure_devops/get_pipeline_run.ts create mode 100644 apps/sim/tools/azure_devops/get_work_item.ts create mode 100644 apps/sim/tools/azure_devops/get_work_items_batch.ts create mode 100644 apps/sim/tools/azure_devops/get_work_items_between_builds.ts create mode 100644 apps/sim/tools/azure_devops/index.ts create mode 100644 apps/sim/tools/azure_devops/list_build_logs.ts create mode 100644 apps/sim/tools/azure_devops/list_builds.ts create mode 100644 apps/sim/tools/azure_devops/list_pipeline_runs.ts create mode 100644 apps/sim/tools/azure_devops/list_pipelines.ts create mode 100644 apps/sim/tools/azure_devops/query_work_items.ts create mode 100644 apps/sim/tools/azure_devops/types.ts create mode 100644 apps/sim/tools/azure_devops/update_work_item.ts create mode 100644 apps/sim/tools/azure_devops/utils.ts create mode 100644 apps/sim/triggers/azure_devops/build_failed.ts create mode 100644 apps/sim/triggers/azure_devops/index.ts create mode 100644 apps/sim/triggers/azure_devops/utils.ts create mode 100644 apps/sim/triggers/azure_devops/webhook.ts create mode 100644 apps/sim/triggers/azure_devops/work_item_created.ts diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index 6508cb8bbb5..ab234725964 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -3126,6 +3126,36 @@ export function AzureIcon(props: SVGProps) { ) } +export function AzureDevOpsIcon(props: SVGProps) { + const id = useId() + const gradientId = `azure_devops_gradient_${id}` + return ( + + + + + + + + + + + + + ) +} + export const GroqIcon = (props: SVGProps) => ( = { ashby: AshbyIcon, athena: AthenaIcon, attio: AttioIcon, + azure_devops: AzureDevOpsIcon, box: BoxCompanyIcon, brandfetch: BrandfetchIcon, brightdata: BrightDataIcon, diff --git a/apps/docs/content/docs/en/tools/azure_devops.mdx b/apps/docs/content/docs/en/tools/azure_devops.mdx new file mode 100644 index 00000000000..38b3bfb69d8 --- /dev/null +++ b/apps/docs/content/docs/en/tools/azure_devops.mdx @@ -0,0 +1,554 @@ +--- +title: Azure DevOps +description: Interact with Azure DevOps pipelines, builds, and work items +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + + + +{/* MANUAL-CONTENT-START:intro */} +[Azure DevOps](https://azure.microsoft.com/en-us/products/devops) is Microsoft's end-to-end DevOps platform for planning, building, testing, and shipping software. It powers engineering at tens of thousands of enterprises across automotive, financial services, government, and any organization built on the Microsoft stack. + +With the Azure DevOps integration in Sim, you can: + +- **Inspect pipelines and runs**: List pipelines, fetch metadata, and walk through run history with status and result +- **Triage build failures**: Pull build timelines to see which stage, job, or task failed, then fetch the exact log for the failing step +- **Audit changes between builds**: Surface the work items that landed between any two builds — useful for release notes and regression hunts +- **Query work items with WIQL**: Run full WIQL queries and get hydrated work item fields back in a single call, not just IDs +- **Manage work item lifecycle**: Create, update, and read Issues, Tasks, and Epics with structured fields — title, description, priority, assignee, area path, iteration, tags, effort, and dates +- **Collaborate via comments**: Add internal or public comments to work items and read full comment history +- **React in real time**: Trigger workflows when builds fail or new work items are created via Azure DevOps service hooks + +These capabilities let your Sim agents close the loop on the DevOps lifecycle — automatically triaging broken builds, drafting release notes between deployments, syncing work items across systems, and keeping engineering operations running while your team focuses on shipping. +{/* MANUAL-CONTENT-END */} + + +## Usage Instructions + +Integrate Azure DevOps into your workflow. List and inspect pipelines and builds, query and manage work items, and add or read comments. + + + +## Tools + +### `azure_devops_list_pipelines` + +List all pipelines in an Azure DevOps project. Returns pipeline ID, name, folder, revision, and URL. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `orderBy` | string | No | Field to sort results by \(e.g. "name"\) | +| `top` | number | No | Maximum number of pipelines to return | +| `continuationToken` | string | No | Continuation token for paginating results | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of pipelines | +| `metadata` | object | Pipelines metadata | +| ↳ `count` | number | Total number of pipelines returned | +| ↳ `pipelines` | array | Array of pipeline objects | +| ↳ `id` | number | Pipeline ID | +| ↳ `name` | string | Pipeline name | +| ↳ `folder` | string | Folder path \(e.g. "\\\\"\) | +| ↳ `revision` | number | Pipeline revision number | +| ↳ `url` | string | Pipeline API URL | + +### `azure_devops_get_pipeline` + +Get details for a specific pipeline in an Azure DevOps project, including configuration and repository info. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `pipelineId` | number | Yes | ID of the pipeline to retrieve | +| `pipelineVersion` | number | No | Specific revision of the pipeline to retrieve \(defaults to latest\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of the pipeline | +| `metadata` | object | Pipeline detail metadata | +| ↳ `pipeline` | object | Full pipeline detail object | +| ↳ `id` | number | Pipeline ID | +| ↳ `name` | string | Pipeline name | +| ↳ `folder` | string | Folder path | +| ↳ `revision` | number | Pipeline revision number | +| ↳ `url` | string | Pipeline API URL | +| ↳ `configuration` | object | Pipeline configuration | +| ↳ `type` | string | Configuration type \(e.g. "yaml"\) | +| ↳ `path` | string | YAML file path in the repository | +| ↳ `repository` | object | Source repository info | +| ↳ `id` | string | Repository ID | +| ↳ `type` | string | Repository type \(e.g. "azureReposGit"\) | +| ↳ `links` | object | Hypermedia links | +| ↳ `self` | string | API self-link | +| ↳ `web` | string | Browser URL for the pipeline | + +### `azure_devops_list_pipeline_runs` + +List runs for a specific pipeline in an Azure DevOps project. Returns run ID, name, state, result, and timestamps. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `pipelineId` | number | Yes | ID of the pipeline whose runs to list | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of pipeline runs | +| `metadata` | object | Pipeline runs metadata | +| ↳ `count` | number | Total number of runs returned | +| ↳ `runs` | array | Array of pipeline run objects | +| ↳ `id` | number | Run ID | +| ↳ `name` | string | Run name \(e.g. "20210601.1"\) | +| ↳ `state` | string | Run state \(e.g. "completed", "inProgress"\) | +| ↳ `result` | string | Run result \(e.g. "succeeded", "failed"\) — absent if still running | +| ↳ `createdDate` | string | ISO 8601 creation timestamp | +| ↳ `finishedDate` | string | ISO 8601 finish timestamp — absent if still running | +| ↳ `url` | string | Run API URL | +| ↳ `webUrl` | string | Browser URL for the run | + +### `azure_devops_get_pipeline_run` + +Get details for a specific pipeline run in an Azure DevOps project. Returns run state, result, timestamps, and the pipeline reference. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `pipelineId` | number | Yes | ID of the pipeline | +| `runId` | number | Yes | ID of the run to retrieve | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of the pipeline run | +| `metadata` | object | Pipeline run metadata | +| ↳ `run` | object | Full pipeline run detail object | +| ↳ `id` | number | Run ID | +| ↳ `name` | string | Run name \(e.g. "20210601.1"\) | +| ↳ `state` | string | Run state \(e.g. "completed", "inProgress"\) | +| ↳ `result` | string | Run result \(e.g. "succeeded", "failed"\) — absent if still running | +| ↳ `createdDate` | string | ISO 8601 creation timestamp | +| ↳ `finishedDate` | string | ISO 8601 finish timestamp — absent if still running | +| ↳ `url` | string | Run API URL | +| ↳ `webUrl` | string | Browser URL for the run | +| ↳ `pipeline` | object | Pipeline reference | +| ↳ `id` | number | Pipeline ID | +| ↳ `name` | string | Pipeline name | +| ↳ `folder` | string | Pipeline folder | +| ↳ `revision` | number | Pipeline revision number | +| ↳ `url` | string | Pipeline API URL | + +### `azure_devops_list_builds` + +List builds in an Azure DevOps project. Optionally filter by pipeline definition, status, result, or branch. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `definitionIds` | string | No | Comma-separated pipeline definition IDs to filter by \(e.g. "1,2,3"\) | +| `top` | number | No | Maximum number of builds to return | +| `statusFilter` | string | No | Filter by build status: inProgress, completed, cancelling, postponed, notStarted, none | +| `resultFilter` | string | No | Filter by build result: succeeded, partiallySucceeded, failed, canceled | +| `branchName` | string | No | Filter by source branch name \(e.g. "refs/heads/main"\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of builds | +| `metadata` | object | Builds metadata | +| ↳ `count` | number | Total number of builds returned | +| ↳ `builds` | array | Array of build objects | +| ↳ `id` | number | Build ID | +| ↳ `buildNumber` | string | Build number \(e.g. "20210601.1"\) | +| ↳ `status` | string | Build status \(e.g. "completed", "inProgress"\) | +| ↳ `result` | string | Build result \(e.g. "succeeded", "failed"\) — absent if still running | +| ↳ `queueTime` | string | ISO 8601 queue timestamp | +| ↳ `startTime` | string | ISO 8601 start timestamp | +| ↳ `finishTime` | string | ISO 8601 finish timestamp — absent if still running | +| ↳ `sourceBranch` | string | Source branch \(e.g. "refs/heads/main"\) | +| ↳ `sourceVersion` | string | Source commit SHA | +| ↳ `definition` | object | Pipeline definition reference | +| ↳ `id` | number | Definition ID | +| ↳ `name` | string | Definition name | +| ↳ `webUrl` | string | Browser URL for the build | + +### `azure_devops_list_build_logs` + +List all log entries for a specific build in Azure DevOps. Returns log IDs, types, and line counts — use the log ID with the Get Build Log tool to fetch actual log text. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `buildId` | number | Yes | The build ID whose logs to list | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of build logs | +| `metadata` | object | Build logs metadata | +| ↳ `count` | number | Total number of log entries returned | +| ↳ `logs` | array | Array of log entry objects | +| ↳ `id` | number | Log entry ID — use with Get Build Log to fetch content | +| ↳ `type` | string | Log type \(e.g. "Container", "Task", "Section"\) | +| ↳ `url` | string | API URL for the log entry | +| ↳ `lineCount` | number | Number of lines in the log | +| ↳ `createdOn` | string | ISO 8601 creation timestamp | +| ↳ `lastChangedOn` | string | ISO 8601 last-changed timestamp | + +### `azure_devops_get_build_log` + +Fetch the text content of a specific build log in Azure DevOps. Use List Build Logs first to get the log ID. Optionally retrieve only a line range with startLine/endLine. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `buildId` | number | Yes | The build ID containing the log | +| `logId` | number | Yes | The log entry ID to fetch \(from List Build Logs\) | +| `startLine` | number | No | First line to return \(1-based, inclusive\) | +| `endLine` | number | No | Last line to return \(1-based, inclusive\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Raw log text | +| `metadata` | object | Log metadata | +| ↳ `lineCount` | number | Number of lines in the returned log text | + +### `azure_devops_get_build_timeline` + +Get the execution timeline for an Azure DevOps build — every stage, job, and task with its result and log ID. Use this to identify which steps failed before fetching their logs with Get Build Log. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `buildId` | number | Yes | ID of the build whose timeline to retrieve | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Summary of the build timeline, highlighting failed steps | +| `metadata` | object | Build timeline metadata | +| ↳ `totalCount` | number | Total number of timeline records | +| ↳ `failedCount` | number | Number of failed records | +| ↳ `records` | array | All timeline records \(stages, jobs, tasks\) | +| ↳ `id` | string | Record GUID | +| ↳ `name` | string | Step name \(e.g. "Run tests"\) | +| ↳ `type` | string | Stage \| Phase \| Job \| Task | +| ↳ `result` | string | succeeded \| failed \| skipped \| canceled \| null | +| ↳ `logId` | number | Log ID to pass to Get Build Log, or null | +| ↳ `errorCount` | number | Number of errors | +| ↳ `warningCount` | number | Number of warnings | +| ↳ `startTime` | string | ISO 8601 start timestamp | +| ↳ `finishTime` | string | ISO 8601 finish timestamp | +| ↳ `failedRecords` | array | Subset of records where result === "failed" — use logId to fetch logs | +| ↳ `id` | string | Record GUID | +| ↳ `name` | string | Step name | +| ↳ `type` | string | Stage \| Phase \| Job \| Task | +| ↳ `result` | string | failed | +| ↳ `logId` | number | Log ID to pass to Get Build Log | +| ↳ `errorCount` | number | Number of errors | +| ↳ `warningCount` | number | Number of warnings | +| ↳ `startTime` | string | ISO 8601 start timestamp | +| ↳ `finishTime` | string | ISO 8601 finish timestamp | + +### `azure_devops_get_work_items_between_builds` + +Get work item references associated with commits between two builds in Azure DevOps. Returns work item IDs and URLs — use Get Work Items Batch for full field details. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `fromBuildId` | number | Yes | The older build ID \(start of range\) | +| `toBuildId` | number | Yes | The newer build ID \(end of range\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of work items between builds | +| `metadata` | object | Work items metadata | +| ↳ `count` | number | Total number of work item references returned | +| ↳ `workItems` | array | Array of work item references | +| ↳ `id` | string | Work item ID | +| ↳ `url` | string | API URL for the work item | + +### `azure_devops_query_work_items` + +Execute a WIQL query to search for work items in Azure DevOps and return full field details. Use TOP N in your query to limit results (Azure enforces a 200-item maximum per batch fetch). + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `wiqlQuery` | string | Yes | WIQL query string \(e.g. "SELECT \[System.Id\] FROM workitems WHERE \[System.State\] = \'Doing\' ORDER BY \[System.Id\] ASC"\). Use TOP N to limit results. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of matching work items | +| `metadata` | object | Work items metadata | +| ↳ `count` | number | Number of work items returned | +| ↳ `workItems` | array | Array of work item details | +| ↳ `id` | number | Work item ID | +| ↳ `title` | string | Work item title | +| ↳ `state` | string | Current state for Basic process \(e.g. To Do, Doing, Done\) | +| ↳ `workItemType` | string | Work item type returned by Azure DevOps \(e.g. Issue, Task, Epic\) | +| ↳ `assignedTo` | string | Display name of assigned user, or null if unassigned | +| ↳ `areaPath` | string | Area path of the work item | +| ↳ `url` | string | API URL for the work item | + +### `azure_devops_get_work_item` + +Fetch full details of a single work item by ID from Azure DevOps, including title, state, type, assignee, and area path. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `workItemId` | number | Yes | The work item ID to fetch | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of the work item | +| `metadata` | object | Work item metadata | +| ↳ `workItem` | object | Full work item details | +| ↳ `id` | number | Work item ID | +| ↳ `title` | string | Work item title | +| ↳ `state` | string | Current state for Basic process \(e.g. To Do, Doing, Done\) | +| ↳ `workItemType` | string | Work item type returned by Azure DevOps \(e.g. Issue, Task, Epic\) | +| ↳ `assignedTo` | string | Display name of assigned user, or null if unassigned | +| ↳ `areaPath` | string | Area path of the work item | +| ↳ `url` | string | API URL for the work item | + +### `azure_devops_get_work_items_batch` + +Fetch full details for multiple work items by ID from Azure DevOps in a single call. Pass comma-separated IDs (e.g. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `ids` | string | Yes | Comma-separated work item IDs to fetch \(e.g. "123,456,789"\). Maximum 200 IDs. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of the fetched work items | +| `metadata` | object | Work items metadata | +| ↳ `count` | number | Number of work items returned | +| ↳ `workItems` | array | Array of work item details | +| ↳ `id` | number | Work item ID | +| ↳ `title` | string | Work item title | +| ↳ `state` | string | Current state for Basic process \(e.g. To Do, Doing, Done\) | +| ↳ `workItemType` | string | Work item type returned by Azure DevOps \(e.g. Issue, Task, Epic\) | +| ↳ `assignedTo` | string | Display name of assigned user, or null if unassigned | +| ↳ `areaPath` | string | Area path of the work item | +| ↳ `url` | string | API URL for the work item | + +### `azure_devops_create_work_item` + +Create a new Basic-process work item (Issue, Task, or Epic) in Azure DevOps. Returns the created work item with its assigned ID. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `workItemType` | string | Yes | Basic-process work item type to create \("Issue", "Task", or "Epic"\). Use Issue for bug or defect tracking. | +| `title` | string | Yes | Title of the new work item | +| `description` | string | No | HTML description of the work item \(optional\) | +| `assignedTo` | string | No | Email or display name of the user to assign the work item to \(optional\) | +| `priority` | number | No | Priority of the work item \(1 = Critical, 2 = High, 3 = Medium, 4 = Low\) | +| `effort` | number | No | Effort \(Microsoft.VSTS.Scheduling.Effort\). Basic process: Issue only. | +| `startDate` | string | No | Start date \(Microsoft.VSTS.Scheduling.StartDate\), ISO 8601. Basic process: Epic only. | +| `targetDate` | string | No | Target date \(Microsoft.VSTS.Scheduling.TargetDate\), ISO 8601. Basic process: Epic only. | +| `activity` | string | No | Activity \(Microsoft.VSTS.Common.Activity\). One of Deployment, Design, Development, Documentation, Requirements, Testing. Basic process: Task only. | +| `remainingWork` | number | No | Remaining work hours \(Microsoft.VSTS.Scheduling.RemainingWork\). Basic process: Task only. | +| `completedWork` | number | No | Completed work hours \(Microsoft.VSTS.Scheduling.CompletedWork\). Basic process: Task only. | +| `areaPath` | string | No | Area path for the work item, e.g. "MyProject\\\\Team" \(optional\) | +| `iterationPath` | string | No | Iteration path for the work item, e.g. "MyProject\\\\Sprint 1" \(optional\) | +| `tags` | string | No | Semicolon-separated tags, e.g. "issue; p1; auth" \(optional\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of the created work item | +| `metadata` | object | Created work item metadata | +| ↳ `workItem` | object | Full details of the created work item | +| ↳ `id` | number | Assigned work item ID | +| ↳ `title` | string | Work item title | +| ↳ `state` | string | Initial state for Basic process \(e.g. To Do, Doing, Done\) | +| ↳ `workItemType` | string | Work item type returned by Azure DevOps \(e.g. Issue, Task, Epic\) | +| ↳ `assignedTo` | string | Display name of assigned user, or null if unassigned | +| ↳ `areaPath` | string | Area path of the work item | +| ↳ `url` | string | API URL for the created work item | + +### `azure_devops_update_work_item` + +Update one or more fields on an existing work item in Azure DevOps. Provide only the fields you want to change. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `workItemId` | number | Yes | ID of the work item to update | +| `title` | string | No | New title for the work item \(optional\) | +| `description` | string | No | New HTML description for the work item \(optional\) | +| `assignedTo` | string | No | Email or display name to reassign the work item to \(optional\) | +| `areaPath` | string | No | New area path for the work item \(optional\) | +| `priority` | number | No | Priority of the work item \(1 = Critical, 2 = High, 3 = Medium, 4 = Low\) \(optional\) | +| `state` | string | No | New state for Basic-process work items: "To Do", "Doing", or "Done" \(optional\) | +| `effort` | number | No | Effort \(Microsoft.VSTS.Scheduling.Effort\). Basic process: Issue only. | +| `startDate` | string | No | Start date \(Microsoft.VSTS.Scheduling.StartDate\), ISO 8601. Basic process: Epic only. | +| `targetDate` | string | No | Target date \(Microsoft.VSTS.Scheduling.TargetDate\), ISO 8601. Basic process: Epic only. | +| `activity` | string | No | Activity \(Microsoft.VSTS.Common.Activity\). One of Deployment, Design, Development, Documentation, Requirements, Testing. Basic process: Task only. | +| `remainingWork` | number | No | Remaining work hours \(Microsoft.VSTS.Scheduling.RemainingWork\). Basic process: Task only. | +| `completedWork` | number | No | Completed work hours \(Microsoft.VSTS.Scheduling.CompletedWork\). Basic process: Task only. | +| `tags` | string | No | Semicolon-separated tags to set on the work item \(optional\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of the updated work item | +| `metadata` | object | Updated work item metadata | +| ↳ `workItem` | object | Full details of the updated work item | +| ↳ `id` | number | Work item ID | +| ↳ `title` | string | Work item title | +| ↳ `state` | string | Current state after update | +| ↳ `workItemType` | string | Work item type returned by Azure DevOps \(e.g. Issue, Task, Epic\) | +| ↳ `assignedTo` | string | Display name of assigned user, or null if unassigned | +| ↳ `areaPath` | string | Area path of the work item | +| ↳ `url` | string | API URL for the work item | + +### `azure_devops_add_comment` + +Add a comment to a work item in Azure DevOps. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `workItemId` | number | Yes | ID of the work item to comment on | +| `text` | string | Yes | Comment text \(HTML supported, e.g. "<p>My comment</p>"\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable confirmation of the added comment | +| `metadata` | object | Added comment metadata | +| ↳ `comment` | object | Full details of the created comment | +| ↳ `workItemId` | number | Work item the comment belongs to | +| ↳ `commentId` | number | Comment ID | +| ↳ `version` | number | Comment version | +| ↳ `text` | string | Comment text | +| ↳ `renderedText` | string | Rendered HTML comment text when available | +| ↳ `createdBy` | string | Display name of the comment author, or null | +| ↳ `createdDate` | string | ISO timestamp when comment was created | +| ↳ `modifiedBy` | string | Display name of the last modifier, or null | +| ↳ `modifiedDate` | string | ISO timestamp when comment was modified | +| ↳ `isDeleted` | boolean | Whether the comment is deleted | +| ↳ `url` | string | API URL for the comment | + +### `azure_devops_get_comments` + +List comments for an Azure DevOps work item. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `organization` | string | Yes | Azure DevOps organization name | +| `project` | string | Yes | Azure DevOps project name | +| `workItemId` | number | Yes | ID of the work item whose comments should be listed | +| `top` | number | No | Maximum number of comments to return | +| `continuationToken` | string | No | Continuation token for paginating comments | +| `includeDeleted` | boolean | No | Whether deleted comments should be returned | +| `expand` | string | No | Additional comment data to include: none, reactions, renderedText, renderedTextOnly, all | +| `order` | string | No | Sort order for comments: asc or desc | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `content` | string | Human-readable summary of work item comments | +| `metadata` | object | Comments metadata | +| ↳ `count` | number | Number of comments returned in this page | +| ↳ `totalCount` | number | Total number of comments on the work item | +| ↳ `continuationToken` | string | Continuation token for the next page | +| ↳ `nextPage` | string | API URL for the next page | +| ↳ `url` | string | API URL for this comments list | +| ↳ `comments` | array | Array of work item comments | +| ↳ `workItemId` | number | Work item ID | +| ↳ `commentId` | number | Comment ID | +| ↳ `version` | number | Comment version | +| ↳ `text` | string | Comment text | +| ↳ `renderedText` | string | Rendered HTML comment text when available | +| ↳ `createdBy` | string | Display name of the comment author | +| ↳ `createdDate` | string | ISO 8601 creation timestamp | +| ↳ `modifiedBy` | string | Display name of the last modifier | +| ↳ `modifiedDate` | string | ISO 8601 modified timestamp | +| ↳ `isDeleted` | boolean | Whether the comment is deleted | +| ↳ `url` | string | API URL for the comment | + + diff --git a/apps/docs/content/docs/en/tools/meta.json b/apps/docs/content/docs/en/tools/meta.json index 5448fe6407b..5e8a637079b 100644 --- a/apps/docs/content/docs/en/tools/meta.json +++ b/apps/docs/content/docs/en/tools/meta.json @@ -17,6 +17,7 @@ "ashby", "athena", "attio", + "azure_devops", "box", "brandfetch", "brightdata", diff --git a/apps/docs/content/docs/en/triggers/azure_devops.mdx b/apps/docs/content/docs/en/triggers/azure_devops.mdx new file mode 100644 index 00000000000..d22c9ae8257 --- /dev/null +++ b/apps/docs/content/docs/en/triggers/azure_devops.mdx @@ -0,0 +1,83 @@ +--- +title: Azure Devops +description: Available Azure Devops triggers for automating workflows +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + + + +Azure Devops provides 3 triggers for automating workflows based on events. + +## Triggers + +### Azure DevOps Build Failed + +Trigger workflow when an Azure DevOps build fails, is canceled, or partially succeeds + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `buildId` | number | Build ID | +| `buildNumber` | string | Build number string \(e.g. 20240101.1\) | +| `result` | string | Build result: failed \| canceled \| partiallySucceeded | +| `pipelineId` | number | Pipeline definition ID | +| `pipelineName` | string | Pipeline definition name | +| `projectName` | string | Azure DevOps project name | +| `branch` | string | Source branch name \(refs/heads/ prefix stripped\) | +| `commitSha` | string | Source commit SHA | +| `triggeredBy` | string | Display name of the person who triggered the build | +| `triggeredByEmail` | string | Email/unique name of the person who triggered the build | +| `startTime` | string | Build start time \(ISO 8601\) | +| `finishTime` | string | Build finish time \(ISO 8601\) | +| `buildUrl` | string | API URL for the build resource | + + +--- + +### Azure DevOps Webhook (All Service Hook Events) + +Trigger on whichever service hook event types you configure in Azure DevOps. Sim does not filter deliveries for this trigger. + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `eventType` | string | Service hook event type \(e.g. build.complete, workitem.created\) | +| `notificationId` | number | Notification ID | +| `subscriptionId` | string | Service hook subscription ID | +| `publisherId` | string | Publisher ID \(e.g. tfs\) | +| `createdDate` | string | Event creation time \(ISO 8601\) | +| `resource` | json | Event resource payload | +| `resourceContainers` | json | Resource container references \(project, collection, etc.\) | +| `message` | json | Short message object | +| `detailedMessage` | json | Detailed message object | + + +--- + +### Azure DevOps Work Item Created + +Trigger workflow when a work item is created in Azure DevOps + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `workItemId` | number | Work item ID | +| `workItemType` | string | Work item type for Basic process \(e.g. Issue, Task, Epic\) | +| `title` | string | Work item title | +| `state` | string | Work item state for Basic process \(e.g. To Do, Doing, Done\) | +| `createdBy` | string | Display name of the creator | +| `assignedTo` | string | Assignee display name, or empty string if unassigned | +| `priority` | number | Priority \(1–4\), or 0 if not set | +| `areaPath` | string | Area path | +| `iterationPath` | string | Iteration path | +| `description` | string | Work item description \(HTML\), or empty string if not set | +| `projectName` | string | Azure DevOps project name | +| `workItemUrl` | string | API URL for the work item resource | + diff --git a/apps/docs/content/docs/en/triggers/meta.json b/apps/docs/content/docs/en/triggers/meta.json index 70d13afd920..ab14483dd52 100644 --- a/apps/docs/content/docs/en/triggers/meta.json +++ b/apps/docs/content/docs/en/triggers/meta.json @@ -8,6 +8,7 @@ "airtable", "ashby", "attio", + "azure_devops", "calcom", "calendly", "circleback", diff --git a/apps/sim/app/(landing)/integrations/data/icon-mapping.ts b/apps/sim/app/(landing)/integrations/data/icon-mapping.ts index ab6f6b1831c..9a1c6030bc9 100644 --- a/apps/sim/app/(landing)/integrations/data/icon-mapping.ts +++ b/apps/sim/app/(landing)/integrations/data/icon-mapping.ts @@ -20,6 +20,7 @@ import { AshbyIcon, AthenaIcon, AttioIcon, + AzureDevOpsIcon, AzureIcon, BoxCompanyIcon, BrainIcon, @@ -226,6 +227,7 @@ export const blockTypeToIconMap: Record = { ashby: AshbyIcon, athena: AthenaIcon, attio: AttioIcon, + azure_devops: AzureDevOpsIcon, box: BoxCompanyIcon, brandfetch: BrandfetchIcon, brightdata: BrightDataIcon, diff --git a/apps/sim/app/(landing)/integrations/data/integrations.json b/apps/sim/app/(landing)/integrations/data/integrations.json index b3d8b3bc4fc..cca205b9006 100644 --- a/apps/sim/app/(landing)/integrations/data/integrations.json +++ b/apps/sim/app/(landing)/integrations/data/integrations.json @@ -1882,6 +1882,105 @@ "integrationTypes": ["security"], "tags": ["identity", "microsoft-365"] }, + { + "type": "azure_devops", + "slug": "azure-devops", + "name": "Azure DevOps", + "description": "Interact with Azure DevOps pipelines, builds, and work items", + "longDescription": "Integrate Azure DevOps into your workflow. List and inspect pipelines and builds, query and manage work items, and add or read comments.", + "bgColor": "#0078D4", + "iconName": "AzureDevOpsIcon", + "docsUrl": "https://docs.sim.ai/tools/azure_devops", + "operations": [ + { + "name": "List Pipelines", + "description": "List all pipelines in an Azure DevOps project. Returns pipeline ID, name, folder, revision, and URL." + }, + { + "name": "Get Pipeline", + "description": "Get details for a specific pipeline in an Azure DevOps project, including configuration and repository info." + }, + { + "name": "List Pipeline Runs", + "description": "List runs for a specific pipeline in an Azure DevOps project. Returns run ID, name, state, result, and timestamps." + }, + { + "name": "Get Pipeline Run", + "description": "Get details for a specific pipeline run in an Azure DevOps project. Returns run state, result, timestamps, and the pipeline reference." + }, + { + "name": "List Builds", + "description": "List builds in an Azure DevOps project. Optionally filter by pipeline definition, status, result, or branch." + }, + { + "name": "List Build Logs", + "description": "List all log entries for a specific build in Azure DevOps. Returns log IDs, types, and line counts — use the log ID with the Get Build Log tool to fetch actual log text." + }, + { + "name": "Get Build Log", + "description": "Fetch the text content of a specific build log in Azure DevOps. Use List Build Logs first to get the log ID. Optionally retrieve only a line range with startLine/endLine." + }, + { + "name": "Get Build Timeline", + "description": "Get the execution timeline for an Azure DevOps build — every stage, job, and task with its result and log ID. Use this to identify which steps failed before fetching their logs with Get Build Log." + }, + { + "name": "Get Work Items Between Builds", + "description": "Get work item references associated with commits between two builds in Azure DevOps. Returns work item IDs and URLs — use Get Work Items Batch for full field details." + }, + { + "name": "Query Work Items", + "description": "Execute a WIQL query to search for work items in Azure DevOps and return full field details. Use TOP N in your query to limit results (Azure enforces a 200-item maximum per batch fetch)." + }, + { + "name": "Get Work Item", + "description": "Fetch full details of a single work item by ID from Azure DevOps, including title, state, type, assignee, and area path." + }, + { + "name": "Get Work Items Batch", + "description": "Fetch full details for multiple work items by ID from Azure DevOps in a single call. Pass comma-separated IDs (e.g. " + }, + { + "name": "Create Work Item", + "description": "Create a new Basic-process work item (Issue, Task, or Epic) in Azure DevOps. Returns the created work item with its assigned ID." + }, + { + "name": "Update Work Item", + "description": "Update one or more fields on an existing work item in Azure DevOps. Provide only the fields you want to change." + }, + { + "name": "Add Comment", + "description": "Add a comment to a work item in Azure DevOps." + }, + { + "name": "Get Comments", + "description": "List comments for an Azure DevOps work item." + } + ], + "operationCount": 16, + "triggers": [ + { + "id": "azure_devops_build_failed", + "name": "Azure DevOps Build Failed", + "description": "Trigger workflow when an Azure DevOps build fails, is canceled, or partially succeeds" + }, + { + "id": "azure_devops_work_item_created", + "name": "Azure DevOps Work Item Created", + "description": "Trigger workflow when a work item is created in Azure DevOps" + }, + { + "id": "azure_devops_webhook", + "name": "Azure DevOps Webhook (All Service Hook Events)", + "description": "Trigger on whichever service hook event types you configure in Azure DevOps. Sim does not filter deliveries for this trigger." + } + ], + "triggerCount": 3, + "authType": "api-key", + "category": "tools", + "integrationTypes": ["developer-tools", "productivity"], + "tags": ["ci-cd", "project-management", "version-control"] + }, { "type": "box", "slug": "box", @@ -4057,6 +4156,10 @@ "name": "Fetch", "description": "Fetch and parse a file from a URL with optional custom headers." }, + { + "name": "Get", + "description": "Get a workspace file object from a selected file or canonical workspace file ID." + }, { "name": "Write", "description": "Create a new workspace file. If a file with the same name already exists, a numeric suffix is added (e.g., " @@ -4066,7 +4169,7 @@ "description": "Append content to an existing workspace file. The file must already exist. Content is added to the end of the file." } ], - "operationCount": 4, + "operationCount": 5, "triggers": [], "triggerCount": 0, "authType": "none", diff --git a/apps/sim/blocks/blocks/azure_devops.test.ts b/apps/sim/blocks/blocks/azure_devops.test.ts new file mode 100644 index 00000000000..8180f6d60e2 --- /dev/null +++ b/apps/sim/blocks/blocks/azure_devops.test.ts @@ -0,0 +1,162 @@ +/** + * @vitest-environment node + */ +import { describe, expect, it } from 'vitest' +import { AzureDevOpsBlock } from './azure_devops' + +const expectedToolIds = [ + 'azure_devops_add_comment', + 'azure_devops_create_work_item', + 'azure_devops_get_build_log', + 'azure_devops_get_build_timeline', + 'azure_devops_get_comments', + 'azure_devops_get_pipeline', + 'azure_devops_get_pipeline_run', + 'azure_devops_get_work_item', + 'azure_devops_get_work_items_batch', + 'azure_devops_get_work_items_between_builds', + 'azure_devops_list_build_logs', + 'azure_devops_list_builds', + 'azure_devops_list_pipeline_runs', + 'azure_devops_list_pipelines', + 'azure_devops_query_work_items', + 'azure_devops_update_work_item', +] + +describe('AzureDevOpsBlock', () => { + const block = AzureDevOpsBlock + + it('exposes every Azure DevOps tool through the operation dropdown and tool access list', () => { + const operation = block.subBlocks.find((subBlock) => subBlock.id === 'operation') + expect(operation?.type).toBe('dropdown') + expect(block.tools.access.sort()).toEqual(expectedToolIds) + const operationOptions = + typeof operation?.options === 'function' ? operation.options() : operation?.options + expect(operationOptions?.map((option) => option.id).sort()).toEqual(expectedToolIds) + }) + + it('limits update work item state to Azure DevOps Basic process options', () => { + const state = block.subBlocks.find((subBlock) => subBlock.id === 'state') + expect(state?.type).toBe('dropdown') + expect(state?.options).toEqual([ + { label: 'To Do', id: 'To Do' }, + { label: 'Doing', id: 'Doing' }, + { label: 'Done', id: 'Done' }, + ]) + }) + + it('limits create work item types to the Azure DevOps Basic process options', () => { + const workItemType = block.subBlocks.find((subBlock) => subBlock.id === 'workItemType') + expect(workItemType?.type).toBe('dropdown') + expect(workItemType?.options).toEqual([ + { label: 'Issue', id: 'Issue' }, + { label: 'Task', id: 'Task' }, + { label: 'Epic', id: 'Epic' }, + ]) + expect(workItemType?.value?.()).toBe('Issue') + }) + + it('routes every operation to the matching tool id without serialization-time coercion', () => { + for (const toolId of expectedToolIds) { + expect(block.tools.config.tool?.({ operation: toolId })).toBe(toolId) + } + }) + + it('maps common params and coerces numeric fields at execution time', () => { + const pipelineRunParams = block.tools.config.params?.({ + accessToken: 'pat-token', + organization: 'mzxchandra', + project: 'sim-testing', + operation: 'azure_devops_get_pipeline_run', + pipelineId: '42', + runId: '99', + }) + + expect(pipelineRunParams).toMatchObject({ + accessToken: 'pat-token', + organization: 'mzxchandra', + project: 'sim-testing', + pipelineId: 42, + runId: 99, + }) + + const listBuildParams = block.tools.config.params?.({ + accessToken: 'pat-token', + organization: 'mzxchandra', + project: 'sim-testing', + operation: 'azure_devops_list_builds', + resultFilter: 'failed', + top: '10', + }) + + expect(listBuildParams).toMatchObject({ + accessToken: 'pat-token', + organization: 'mzxchandra', + project: 'sim-testing', + resultFilter: 'failed', + top: 10, + }) + + const getBuildLogParams = block.tools.config.params?.({ + accessToken: 'pat-token', + organization: 'mzxchandra', + project: 'sim-testing', + operation: 'azure_devops_get_build_log', + buildId: '101', + logId: '3', + }) + + expect(getBuildLogParams).toMatchObject({ + accessToken: 'pat-token', + organization: 'mzxchandra', + project: 'sim-testing', + buildId: 101, + logId: 3, + }) + + const createWorkItemParams = block.tools.config.params?.({ + accessToken: 'pat-token', + organization: 'mzxchandra', + project: 'sim-testing', + operation: 'azure_devops_create_work_item', + workItemType: 'Issue', + title: 'Pipeline failure', + priority: '2', + }) + + expect(createWorkItemParams).toMatchObject({ + accessToken: 'pat-token', + organization: 'mzxchandra', + project: 'sim-testing', + workItemType: 'Issue', + title: 'Pipeline failure', + priority: 2, + }) + + const updateWorkItemParams = block.tools.config.params?.({ + accessToken: 'pat-token', + organization: 'mzxchandra', + project: 'sim-testing', + operation: 'azure_devops_update_work_item', + workItemId: '101', + state: 'Doing', + effort: '8', + priority: '1', + }) + + expect(updateWorkItemParams).toMatchObject({ + accessToken: 'pat-token', + organization: 'mzxchandra', + project: 'sim-testing', + workItemId: 101, + state: 'Doing', + effort: 8, + priority: 1, + }) + }) + + it('declares downstream outputs for pipeline, build, work item, and comment operations', () => { + expect(block.outputs.content).toBeDefined() + expect(block.outputs.metadata).toBeDefined() + }) +}) diff --git a/apps/sim/blocks/blocks/azure_devops.ts b/apps/sim/blocks/blocks/azure_devops.ts new file mode 100644 index 00000000000..7af9bb2ffe8 --- /dev/null +++ b/apps/sim/blocks/blocks/azure_devops.ts @@ -0,0 +1,627 @@ +import { AzureDevOpsIcon } from '@/components/icons' +import type { BlockConfig } from '@/blocks/types' +import { AuthMode, IntegrationType } from '@/blocks/types' +import type { AzureDevOpsBasicWorkItemType, AzureDevOpsResponse } from '@/tools/azure_devops/types' +import { AZURE_DEVOPS_BASIC_WORK_ITEM_STATES } from '@/tools/azure_devops/utils' +import { getTrigger } from '@/triggers' + +/** Accepts ISO 8601 or YYYY-MM-DD; expands the bare date form to a UTC midnight ISO timestamp. */ +function normalizeDate(input: unknown): string | undefined { + if (typeof input !== 'string' || input.trim() === '') return undefined + const value = input.trim() + return /^\d{4}-\d{2}-\d{2}$/.test(value) ? `${value}T00:00:00Z` : value +} + +export const AzureDevOpsBlock: BlockConfig = { + type: 'azure_devops', + name: 'Azure DevOps', + description: 'Interact with Azure DevOps pipelines, builds, and work items', + longDescription: + 'Integrate Azure DevOps into your workflow. List and inspect pipelines and builds, query and manage work items, and add or read comments.', + docsLink: 'https://docs.sim.ai/tools/azure_devops', + category: 'tools', + integrationType: IntegrationType.DeveloperTools, + tags: ['ci-cd', 'project-management', 'version-control'], + bgColor: '#0078D4', + icon: AzureDevOpsIcon, + authMode: AuthMode.ApiKey, + triggerAllowed: true, + + subBlocks: [ + { + id: 'operation', + title: 'Operation', + type: 'dropdown', + options: [ + // Pipeline + { label: 'List Pipelines', id: 'azure_devops_list_pipelines' }, + { label: 'Get Pipeline', id: 'azure_devops_get_pipeline' }, + { label: 'List Pipeline Runs', id: 'azure_devops_list_pipeline_runs' }, + { label: 'Get Pipeline Run', id: 'azure_devops_get_pipeline_run' }, + // Builds + { label: 'List Builds', id: 'azure_devops_list_builds' }, + { label: 'List Build Logs', id: 'azure_devops_list_build_logs' }, + { label: 'Get Build Log', id: 'azure_devops_get_build_log' }, + { label: 'Get Build Timeline', id: 'azure_devops_get_build_timeline' }, + { + label: 'Get Work Items Between Builds', + id: 'azure_devops_get_work_items_between_builds', + }, + // Work Items + { label: 'Query Work Items', id: 'azure_devops_query_work_items' }, + { label: 'Get Work Item', id: 'azure_devops_get_work_item' }, + { label: 'Get Work Items Batch', id: 'azure_devops_get_work_items_batch' }, + { label: 'Create Work Item', id: 'azure_devops_create_work_item' }, + { label: 'Update Work Item', id: 'azure_devops_update_work_item' }, + { label: 'Add Comment', id: 'azure_devops_add_comment' }, + { label: 'Get Comments', id: 'azure_devops_get_comments' }, + ], + value: () => 'azure_devops_list_pipelines', + }, + + // ── Shared auth + org/project ──────────────────────────────────────────── + { + id: 'accessToken', + title: 'Personal Access Token', + type: 'short-input', + password: true, + required: true, + placeholder: 'Requires Build: Read and Work Items: Read & Write scopes', + }, + { + id: 'organization', + title: 'Organization', + type: 'short-input', + required: true, + placeholder: 'e.g. contoso', + }, + { + id: 'project', + title: 'Project', + type: 'short-input', + required: true, + placeholder: 'e.g. MyApp', + }, + + // ── Pipeline fields ────────────────────────────────────────────────────── + { + id: 'pipelineId', + title: 'Pipeline ID', + type: 'short-input', + required: true, + condition: { + field: 'operation', + value: [ + 'azure_devops_get_pipeline', + 'azure_devops_list_pipeline_runs', + 'azure_devops_get_pipeline_run', + ], + }, + }, + { + id: 'runId', + title: 'Run ID', + type: 'short-input', + required: true, + condition: { field: 'operation', value: 'azure_devops_get_pipeline_run' }, + }, + + // ── Build fields ───────────────────────────────────────────────────────── + { + id: 'resultFilter', + title: 'Filter by Result', + type: 'dropdown', + options: [ + { label: 'Any', id: '' }, + { label: 'Succeeded', id: 'succeeded' }, + { label: 'Failed', id: 'failed' }, + { label: 'Canceled', id: 'canceled' }, + { label: 'Partially Succeeded', id: 'partiallySucceeded' }, + ], + condition: { field: 'operation', value: 'azure_devops_list_builds' }, + mode: 'advanced', + }, + { + id: 'top', + title: 'Max Results', + type: 'short-input', + placeholder: '50', + condition: { field: 'operation', value: 'azure_devops_list_builds' }, + mode: 'advanced', + }, + { + id: 'buildId', + title: 'Build ID', + type: 'short-input', + required: true, + condition: { + field: 'operation', + value: [ + 'azure_devops_list_build_logs', + 'azure_devops_get_build_log', + 'azure_devops_get_build_timeline', + ], + }, + }, + { + id: 'logId', + title: 'Log ID', + type: 'short-input', + required: true, + condition: { field: 'operation', value: 'azure_devops_get_build_log' }, + }, + { + id: 'fromBuildId', + title: 'From Build ID', + type: 'short-input', + required: true, + condition: { field: 'operation', value: 'azure_devops_get_work_items_between_builds' }, + }, + { + id: 'toBuildId', + title: 'To Build ID', + type: 'short-input', + required: true, + condition: { field: 'operation', value: 'azure_devops_get_work_items_between_builds' }, + }, + + // ── Work Item fields ───────────────────────────────────────────────────── + { + id: 'wiqlQuery', + title: 'WIQL Query', + type: 'long-input', + required: true, + placeholder: + 'SELECT [System.Id], [System.Title], [System.State] FROM workitems WHERE [System.TeamProject] = @project ORDER BY [System.CreatedDate] DESC', + condition: { field: 'operation', value: 'azure_devops_query_work_items' }, + }, + { + id: 'workItemId', + title: 'Work Item ID', + type: 'short-input', + required: true, + condition: { + field: 'operation', + value: [ + 'azure_devops_get_work_item', + 'azure_devops_update_work_item', + 'azure_devops_add_comment', + 'azure_devops_get_comments', + ], + }, + }, + { + id: 'workItemIds', + title: 'Work Item IDs', + type: 'short-input', + required: true, + placeholder: 'Comma-separated IDs, e.g. 1,2,3', + condition: { field: 'operation', value: 'azure_devops_get_work_items_batch' }, + }, + { + id: 'workItemType', + title: 'Work Item Type', + type: 'dropdown', + required: true, + options: [ + { label: 'Issue', id: 'Issue' }, + { label: 'Task', id: 'Task' }, + { label: 'Epic', id: 'Epic' }, + ], + value: () => 'Issue', + condition: { field: 'operation', value: 'azure_devops_create_work_item' }, + }, + { + id: 'title', + title: 'Title', + type: 'short-input', + required: { field: 'operation', value: 'azure_devops_create_work_item' }, + condition: { + field: 'operation', + value: ['azure_devops_create_work_item', 'azure_devops_update_work_item'], + }, + }, + { + id: 'description', + title: 'Description', + type: 'long-input', + condition: { + field: 'operation', + value: ['azure_devops_create_work_item', 'azure_devops_update_work_item'], + }, + }, + { + id: 'assignedTo', + title: 'Assigned To', + type: 'short-input', + placeholder: 'Email or display name', + condition: { + field: 'operation', + value: ['azure_devops_create_work_item', 'azure_devops_update_work_item'], + }, + mode: 'advanced', + }, + { + id: 'priority', + title: 'Priority', + type: 'dropdown', + options: [ + { label: '1 - Critical', id: '1' }, + { label: '2 - High', id: '2' }, + { label: '3 - Medium', id: '3' }, + { label: '4 - Low', id: '4' }, + ], + condition: { + field: 'operation', + value: ['azure_devops_create_work_item', 'azure_devops_update_work_item'], + }, + mode: 'advanced', + }, + { + id: 'effort', + title: 'Effort', + type: 'short-input', + placeholder: 'Numeric effort (Issue only)', + condition: { + field: 'operation', + value: 'azure_devops_create_work_item', + and: { field: 'workItemType', value: 'Issue' }, + }, + mode: 'advanced', + }, + { + id: 'effort', + title: 'Effort', + type: 'short-input', + placeholder: 'Numeric effort (Issue only)', + condition: { field: 'operation', value: 'azure_devops_update_work_item' }, + mode: 'advanced', + }, + { + id: 'startDate', + title: 'Start Date', + type: 'short-input', + placeholder: 'YYYY-MM-DD (Epic only)', + condition: { + field: 'operation', + value: 'azure_devops_create_work_item', + and: { field: 'workItemType', value: 'Epic' }, + }, + mode: 'advanced', + }, + { + id: 'startDate', + title: 'Start Date', + type: 'short-input', + placeholder: 'YYYY-MM-DD (Epic only)', + condition: { field: 'operation', value: 'azure_devops_update_work_item' }, + mode: 'advanced', + }, + { + id: 'targetDate', + title: 'Target Date', + type: 'short-input', + placeholder: 'YYYY-MM-DD (Epic only)', + condition: { + field: 'operation', + value: 'azure_devops_create_work_item', + and: { field: 'workItemType', value: 'Epic' }, + }, + mode: 'advanced', + }, + { + id: 'targetDate', + title: 'Target Date', + type: 'short-input', + placeholder: 'YYYY-MM-DD (Epic only)', + condition: { field: 'operation', value: 'azure_devops_update_work_item' }, + mode: 'advanced', + }, + { + id: 'activity', + title: 'Activity', + type: 'dropdown', + options: [ + { label: 'Deployment', id: 'Deployment' }, + { label: 'Design', id: 'Design' }, + { label: 'Development', id: 'Development' }, + { label: 'Documentation', id: 'Documentation' }, + { label: 'Requirements', id: 'Requirements' }, + { label: 'Testing', id: 'Testing' }, + ], + condition: { + field: 'operation', + value: 'azure_devops_create_work_item', + and: { field: 'workItemType', value: 'Task' }, + }, + mode: 'advanced', + }, + { + id: 'activity', + title: 'Activity', + type: 'dropdown', + options: [ + { label: 'Deployment', id: 'Deployment' }, + { label: 'Design', id: 'Design' }, + { label: 'Development', id: 'Development' }, + { label: 'Documentation', id: 'Documentation' }, + { label: 'Requirements', id: 'Requirements' }, + { label: 'Testing', id: 'Testing' }, + ], + condition: { field: 'operation', value: 'azure_devops_update_work_item' }, + mode: 'advanced', + }, + { + id: 'remainingWork', + title: 'Remaining Work', + type: 'short-input', + placeholder: 'Hours (Task only)', + condition: { + field: 'operation', + value: 'azure_devops_create_work_item', + and: { field: 'workItemType', value: 'Task' }, + }, + mode: 'advanced', + }, + { + id: 'remainingWork', + title: 'Remaining Work', + type: 'short-input', + placeholder: 'Hours (Task only)', + condition: { field: 'operation', value: 'azure_devops_update_work_item' }, + mode: 'advanced', + }, + { + id: 'completedWork', + title: 'Completed Work', + type: 'short-input', + placeholder: 'Hours (Task only)', + condition: { + field: 'operation', + value: 'azure_devops_create_work_item', + and: { field: 'workItemType', value: 'Task' }, + }, + mode: 'advanced', + }, + { + id: 'completedWork', + title: 'Completed Work', + type: 'short-input', + placeholder: 'Hours (Task only)', + condition: { field: 'operation', value: 'azure_devops_update_work_item' }, + mode: 'advanced', + }, + { + id: 'areaPath', + title: 'Area Path', + type: 'short-input', + placeholder: 'e.g. MyProject\\Team', + condition: { + field: 'operation', + value: ['azure_devops_create_work_item', 'azure_devops_update_work_item'], + }, + mode: 'advanced', + }, + { + id: 'iterationPath', + title: 'Iteration Path', + type: 'short-input', + placeholder: 'e.g. MyProject\\Sprint 1', + condition: { field: 'operation', value: 'azure_devops_create_work_item' }, + mode: 'advanced', + }, + { + id: 'tags', + title: 'Tags', + type: 'short-input', + placeholder: 'Semicolon-separated, e.g. issue; p1; auth', + condition: { + field: 'operation', + value: ['azure_devops_create_work_item', 'azure_devops_update_work_item'], + }, + mode: 'advanced', + }, + { + id: 'state', + title: 'State', + type: 'dropdown', + options: AZURE_DEVOPS_BASIC_WORK_ITEM_STATES.map((state) => ({ + label: state, + id: state, + })), + condition: { field: 'operation', value: 'azure_devops_update_work_item' }, + }, + { + id: 'commentText', + title: 'Comment', + type: 'long-input', + required: true, + condition: { field: 'operation', value: 'azure_devops_add_comment' }, + }, + ...getTrigger('azure_devops_build_failed').subBlocks, + ...getTrigger('azure_devops_work_item_created').subBlocks, + ...getTrigger('azure_devops_webhook').subBlocks, + ], + + tools: { + access: [ + 'azure_devops_list_pipelines', + 'azure_devops_get_pipeline', + 'azure_devops_list_pipeline_runs', + 'azure_devops_get_pipeline_run', + 'azure_devops_list_builds', + 'azure_devops_list_build_logs', + 'azure_devops_get_build_log', + 'azure_devops_get_build_timeline', + 'azure_devops_get_work_items_between_builds', + 'azure_devops_query_work_items', + 'azure_devops_get_work_item', + 'azure_devops_get_work_items_batch', + 'azure_devops_create_work_item', + 'azure_devops_update_work_item', + 'azure_devops_add_comment', + 'azure_devops_get_comments', + ], + config: { + tool: (params) => params.operation as string, + params: (params) => { + const base = { + accessToken: params.accessToken as string, + organization: params.organization as string, + project: params.project as string, + } + switch (params.operation) { + case 'azure_devops_list_pipelines': + return base + case 'azure_devops_get_pipeline': + return { ...base, pipelineId: Number(params.pipelineId) } + case 'azure_devops_list_pipeline_runs': + return { ...base, pipelineId: Number(params.pipelineId) } + case 'azure_devops_get_pipeline_run': + return { ...base, pipelineId: Number(params.pipelineId), runId: Number(params.runId) } + case 'azure_devops_list_builds': + return { + ...base, + resultFilter: (params.resultFilter as string) || undefined, + top: params.top ? Number(params.top) : undefined, + } + case 'azure_devops_list_build_logs': + return { ...base, buildId: Number(params.buildId) } + case 'azure_devops_get_build_log': + return { ...base, buildId: Number(params.buildId), logId: Number(params.logId) } + case 'azure_devops_get_build_timeline': + return { ...base, buildId: Number(params.buildId) } + case 'azure_devops_get_work_items_between_builds': + return { + ...base, + fromBuildId: Number(params.fromBuildId), + toBuildId: Number(params.toBuildId), + } + case 'azure_devops_query_work_items': + return { ...base, wiqlQuery: params.wiqlQuery as string } + case 'azure_devops_get_work_item': + return { ...base, workItemId: Number(params.workItemId) } + case 'azure_devops_get_work_items_batch': + return { ...base, ids: params.workItemIds as string } + case 'azure_devops_create_work_item': + return { + ...base, + workItemType: params.workItemType as AzureDevOpsBasicWorkItemType, + title: params.title as string, + description: (params.description as string) || undefined, + assignedTo: (params.assignedTo as string) || undefined, + priority: params.priority ? Number(params.priority) : undefined, + effort: params.effort ? Number(params.effort) : undefined, + startDate: normalizeDate(params.startDate), + targetDate: normalizeDate(params.targetDate), + activity: (params.activity as string) || undefined, + remainingWork: params.remainingWork ? Number(params.remainingWork) : undefined, + completedWork: params.completedWork ? Number(params.completedWork) : undefined, + areaPath: (params.areaPath as string) || undefined, + iterationPath: (params.iterationPath as string) || undefined, + tags: (params.tags as string) || undefined, + } + case 'azure_devops_update_work_item': + return { + ...base, + workItemId: Number(params.workItemId), + title: (params.title as string) || undefined, + state: (params.state as string) || undefined, + assignedTo: (params.assignedTo as string) || undefined, + priority: params.priority ? Number(params.priority) : undefined, + effort: params.effort ? Number(params.effort) : undefined, + startDate: normalizeDate(params.startDate), + targetDate: normalizeDate(params.targetDate), + activity: (params.activity as string) || undefined, + remainingWork: params.remainingWork ? Number(params.remainingWork) : undefined, + completedWork: params.completedWork ? Number(params.completedWork) : undefined, + description: (params.description as string) || undefined, + areaPath: (params.areaPath as string) || undefined, + tags: (params.tags as string) || undefined, + } + case 'azure_devops_add_comment': + return { + ...base, + workItemId: Number(params.workItemId), + text: params.commentText as string, + } + case 'azure_devops_get_comments': + return { ...base, workItemId: Number(params.workItemId) } + default: + return base + } + }, + }, + }, + + inputs: { + operation: { type: 'string', description: 'Operation to perform' }, + accessToken: { type: 'string', description: 'Azure DevOps Personal Access Token' }, + organization: { type: 'string', description: 'Azure DevOps organization name' }, + project: { type: 'string', description: 'Azure DevOps project name' }, + pipelineId: { type: 'number', description: 'Pipeline ID' }, + runId: { type: 'number', description: 'Pipeline run ID' }, + resultFilter: { type: 'string', description: 'Build result filter' }, + top: { type: 'number', description: 'Maximum number of results' }, + buildId: { type: 'number', description: 'Build ID' }, + logId: { type: 'number', description: 'Build log ID' }, + fromBuildId: { type: 'number', description: 'Starting build ID for work item range' }, + toBuildId: { type: 'number', description: 'Ending build ID for work item range' }, + wiqlQuery: { type: 'string', description: 'WIQL query string' }, + workItemId: { type: 'number', description: 'Work item ID' }, + workItemIds: { type: 'string', description: 'Comma-separated work item IDs' }, + workItemType: { type: 'string', description: 'Basic work item type (Issue, Task, Epic)' }, + title: { type: 'string', description: 'Work item title' }, + description: { type: 'string', description: 'Work item description (HTML supported)' }, + assignedTo: { type: 'string', description: 'Assignee email or display name' }, + priority: { type: 'number', description: 'Work item priority (1–4)' }, + effort: { + type: 'number', + description: 'Work item effort (Microsoft.VSTS.Scheduling.Effort); Basic process: Issue only', + }, + startDate: { + type: 'string', + description: 'Start date (Microsoft.VSTS.Scheduling.StartDate); Basic process: Epic only', + }, + targetDate: { + type: 'string', + description: 'Target date (Microsoft.VSTS.Scheduling.TargetDate); Basic process: Epic only', + }, + activity: { + type: 'string', + description: 'Activity (Microsoft.VSTS.Common.Activity); Basic process: Task only', + }, + remainingWork: { + type: 'number', + description: + 'Remaining work hours (Microsoft.VSTS.Scheduling.RemainingWork); Basic process: Task only', + }, + completedWork: { + type: 'number', + description: + 'Completed work hours (Microsoft.VSTS.Scheduling.CompletedWork); Basic process: Task only', + }, + areaPath: { type: 'string', description: 'Area path' }, + iterationPath: { type: 'string', description: 'Iteration path' }, + tags: { type: 'string', description: 'Semicolon-separated tags' }, + state: { + type: 'string', + description: 'Basic-process work item state (To Do, Doing, Done)', + }, + commentText: { type: 'string', description: 'Comment text' }, + }, + + outputs: { + content: { type: 'string', description: 'Human-readable response from Azure DevOps' }, + metadata: { type: 'json', description: 'Structured Azure DevOps response data' }, + }, + + triggers: { + enabled: true, + available: [ + 'azure_devops_build_failed', + 'azure_devops_work_item_created', + 'azure_devops_webhook', + ], + }, +} diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index 2e008d00edb..64c0e44859e 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -17,6 +17,7 @@ import { AsanaBlock } from '@/blocks/blocks/asana' import { AshbyBlock } from '@/blocks/blocks/ashby' import { AthenaBlock } from '@/blocks/blocks/athena' import { AttioBlock } from '@/blocks/blocks/attio' +import { AzureDevOpsBlock } from '@/blocks/blocks/azure_devops' import { BoxBlock } from '@/blocks/blocks/box' import { BrandfetchBlock } from '@/blocks/blocks/brandfetch' import { BrightDataBlock } from '@/blocks/blocks/brightdata' @@ -258,6 +259,7 @@ export const registry: Record = { ashby: AshbyBlock, athena: AthenaBlock, attio: AttioBlock, + azure_devops: AzureDevOpsBlock, box: BoxBlock, brandfetch: BrandfetchBlock, brightdata: BrightDataBlock, diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index 6508cb8bbb5..ab234725964 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -3126,6 +3126,36 @@ export function AzureIcon(props: SVGProps) { ) } +export function AzureDevOpsIcon(props: SVGProps) { + const id = useId() + const gradientId = `azure_devops_gradient_${id}` + return ( + + + + + + + + + + + + + ) +} + export const GroqIcon = (props: SVGProps) => ( { + const triggerId = providerConfig.triggerId as string | undefined + const b = body as Record + + if (triggerId && triggerId !== 'azure_devops_webhook') { + const { isAzureDevOpsEventMatch } = await import('@/triggers/azure_devops/utils') + if (!isAzureDevOpsEventMatch(triggerId, b)) { + logger.debug( + `[${requestId}] Azure DevOps event mismatch for trigger ${triggerId}. Skipping execution.`, + { + webhookId: webhook.id, + workflowId: workflow.id, + triggerId, + eventType: b.eventType, + } + ) + return false + } + } + + return true + }, + + extractIdempotencyId(body: unknown): string | null { + const obj = body as Record | null + if (!obj) return null + const subscriptionId = + typeof obj.subscriptionId === 'string' && obj.subscriptionId ? obj.subscriptionId : null + const notificationId = + typeof obj.notificationId === 'number' || typeof obj.notificationId === 'string' + ? String(obj.notificationId) + : null + if (!subscriptionId || !notificationId) return null + return `azure_devops:${subscriptionId}:${notificationId}` + }, + + async formatInput({ body, webhook, requestId }: FormatInputContext): Promise { + const b = body as Record + const providerConfig = (webhook.providerConfig as Record) || {} + const triggerId = providerConfig.triggerId as string | undefined + const eventType = b.eventType as string | undefined + + if (triggerId === 'azure_devops_webhook') { + return { input: formatWebhookEnvelopeInput(b) } + } + + if (eventType === AZURE_DEVOPS_BUILD_FAILED_EVENT) { + return { input: formatBuildCompleteInput(b) } + } + + if (eventType === AZURE_DEVOPS_WORK_ITEM_CREATED_EVENT) { + return { input: formatWorkItemCreatedInput(b) } + } + + logger.warn(`[${requestId}] Azure DevOps: unknown eventType for specialized trigger`, { + triggerId, + eventType, + }) + return { + input: null, + skip: { + message: `Unsupported Azure DevOps event type "${eventType ?? 'unknown'}" for trigger ${triggerId ?? 'unknown'}`, + }, + } + }, +} diff --git a/apps/sim/lib/webhooks/providers/registry.ts b/apps/sim/lib/webhooks/providers/registry.ts index ce8e9c6af73..5c4d8eaea73 100644 --- a/apps/sim/lib/webhooks/providers/registry.ts +++ b/apps/sim/lib/webhooks/providers/registry.ts @@ -3,6 +3,7 @@ import { NextResponse } from 'next/server' import { airtableHandler } from '@/lib/webhooks/providers/airtable' import { ashbyHandler } from '@/lib/webhooks/providers/ashby' import { attioHandler } from '@/lib/webhooks/providers/attio' +import { azureDevOpsHandler } from '@/lib/webhooks/providers/azure-devops' import { calcomHandler } from '@/lib/webhooks/providers/calcom' import { calendlyHandler } from '@/lib/webhooks/providers/calendly' import { circlebackHandler } from '@/lib/webhooks/providers/circleback' @@ -52,6 +53,7 @@ const PROVIDER_HANDLERS: Record = { airtable: airtableHandler, ashby: ashbyHandler, attio: attioHandler, + azure_devops: azureDevOpsHandler, calendly: calendlyHandler, calcom: calcomHandler, circleback: circlebackHandler, diff --git a/apps/sim/tools/azure_devops/add_comment.ts b/apps/sim/tools/azure_devops/add_comment.ts new file mode 100644 index 00000000000..36630ffeeaf --- /dev/null +++ b/apps/sim/tools/azure_devops/add_comment.ts @@ -0,0 +1,122 @@ +import type { + AddCommentParams, + AddCommentResponse, + AzureDevOpsComment, +} from '@/tools/azure_devops/types' +import type { AzureDevOpsRawComment } from '@/tools/azure_devops/utils' +import { formatComment, mapComment } from '@/tools/azure_devops/utils' +import type { ToolConfig } from '@/tools/types' + +export const addCommentTool: ToolConfig = { + id: 'azure_devops_add_comment', + name: 'Azure DevOps Add Comment', + description: 'Add a comment to a work item in Azure DevOps.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + workItemId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'ID of the work item to comment on', + }, + text: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Comment text (HTML supported, e.g. "

My comment

")', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Work Items: Read & Write)', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/wit/workitems/${Number(params.workItemId)}/comments` + ) + url.searchParams.set('api-version', '7.0-preview.3') + return url.toString() + }, + method: 'POST', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + body: (params) => ({ text: params.text }), + }, + + transformResponse: async (response) => { + const raw: AzureDevOpsRawComment = await response.json() + const comment: AzureDevOpsComment = mapComment(raw) + + return { + success: true, + output: { + content: `Added comment #${comment.commentId}:\n\n${formatComment(comment)}`, + metadata: { comment }, + }, + } + }, + + outputs: { + content: { + type: 'string', + description: 'Human-readable confirmation of the added comment', + }, + metadata: { + type: 'object', + description: 'Added comment metadata', + properties: { + comment: { + type: 'object', + description: 'Full details of the created comment', + properties: { + workItemId: { type: 'number', description: 'Work item the comment belongs to' }, + commentId: { type: 'number', description: 'Comment ID' }, + version: { type: 'number', description: 'Comment version' }, + text: { type: 'string', description: 'Comment text' }, + renderedText: { + type: 'string', + description: 'Rendered HTML comment text when available', + optional: true, + }, + createdBy: { + type: 'string', + description: 'Display name of the comment author, or null', + nullable: true, + }, + createdDate: { type: 'string', description: 'ISO timestamp when comment was created' }, + modifiedBy: { + type: 'string', + description: 'Display name of the last modifier, or null', + nullable: true, + }, + modifiedDate: { + type: 'string', + description: 'ISO timestamp when comment was modified', + }, + isDeleted: { type: 'boolean', description: 'Whether the comment is deleted' }, + url: { type: 'string', description: 'API URL for the comment' }, + }, + }, + }, + }, + }, +} diff --git a/apps/sim/tools/azure_devops/azure-devops.test.ts b/apps/sim/tools/azure_devops/azure-devops.test.ts new file mode 100644 index 00000000000..104232b18a5 --- /dev/null +++ b/apps/sim/tools/azure_devops/azure-devops.test.ts @@ -0,0 +1,788 @@ +/** + * @vitest-environment node + */ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { isAzureDevOpsEventMatch } from '@/triggers/azure_devops/utils' +import { tools } from '../registry' +import type { ToolConfig } from '../types' +import { addCommentTool } from './add_comment' +import { createWorkItemTool } from './create_work_item' +import { getBuildLogTool } from './get_build_log' +import { getBuildTimelineTool } from './get_build_timeline' +import { getCommentsTool } from './get_comments' +import { getPipelineTool } from './get_pipeline' +import { getPipelineRunTool } from './get_pipeline_run' +import { getWorkItemTool } from './get_work_item' +import { getWorkItemsBatchTool } from './get_work_items_batch' +import { getWorkItemsBetweenBuildsTool } from './get_work_items_between_builds' +import { listBuildLogsTool } from './list_build_logs' +import { listBuildsTool } from './list_builds' +import { listPipelineRunsTool } from './list_pipeline_runs' +import { listPipelinesTool } from './list_pipelines' +import { queryWorkItemsTool } from './query_work_items' +import type { + AddCommentParams, + CreateWorkItemParams, + GetBuildLogParams, + GetCommentsParams, + GetPipelineParams, + GetPipelineRunParams, + GetWorkItemParams, + GetWorkItemsBatchParams, + GetWorkItemsBetweenBuildsParams, + ListBuildLogsParams, + ListBuildsParams, + ListPipelineRunsParams, + ListPipelinesParams, + QueryWorkItemsParams, + UpdateWorkItemParams, +} from './types' +import { updateWorkItemTool } from './update_work_item' + +const baseParams = { + organization: 'contoso', + project: 'Fabrikam', + accessToken: 'pat-token', +} + +const authHeader = `Basic ${Buffer.from(':pat-token').toString('base64')}` + +const allTools = [ + addCommentTool, + createWorkItemTool, + getBuildLogTool, + getCommentsTool, + getPipelineTool, + getPipelineRunTool, + getWorkItemTool, + getWorkItemsBatchTool, + getWorkItemsBetweenBuildsTool, + listBuildLogsTool, + listBuildsTool, + listPipelineRunsTool, + listPipelinesTool, + queryWorkItemsTool, + updateWorkItemTool, +] as const + +function buildUrl(tool: ToolConfig, params: P): string { + return typeof tool.request.url === 'function' ? tool.request.url(params) : tool.request.url +} + +function buildHeaders(tool: ToolConfig, params: P): Record { + return tool.request.headers(params) +} + +function buildBody(tool: ToolConfig, params: P): unknown { + return tool.request.body?.(params) +} + +function responseJson(body: unknown): Response { + return new Response(JSON.stringify(body)) +} + +const rawWorkItem = { + id: 101, + url: 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/workItems/101', + fields: { + 'System.Title': 'SimIntegrationTest Issue', + 'System.State': 'Doing', + 'System.WorkItemType': 'Issue', + 'System.AssignedTo': { displayName: 'Ada Lovelace' }, + 'System.AreaPath': 'Fabrikam\\Platform', + }, +} + +const rawComment = { + workItemId: 101, + commentId: 9, + version: 1, + text: 'SimIntegrationTest comment', + renderedText: '

SimIntegrationTest comment

', + createdBy: { displayName: 'Ada Lovelace' }, + createdDate: '2026-05-15T10:00:00Z', + modifiedBy: { displayName: 'Ada Lovelace' }, + modifiedDate: '2026-05-15T10:00:00Z', + isDeleted: false, + url: 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/workitems/101/comments/9', + id: 9, +} + +describe('Azure DevOps tool contracts', () => { + it('exports and registers the full planned tool surface', () => { + const expectedIds = [ + 'azure_devops_add_comment', + 'azure_devops_create_work_item', + 'azure_devops_get_build_log', + 'azure_devops_get_comments', + 'azure_devops_get_pipeline', + 'azure_devops_get_pipeline_run', + 'azure_devops_get_work_item', + 'azure_devops_get_work_items_batch', + 'azure_devops_get_work_items_between_builds', + 'azure_devops_list_build_logs', + 'azure_devops_list_builds', + 'azure_devops_list_pipeline_runs', + 'azure_devops_list_pipelines', + 'azure_devops_query_work_items', + 'azure_devops_update_work_item', + ] + + expect(allTools.map((tool) => tool.id).sort()).toEqual(expectedIds) + for (const id of expectedIds) { + expect(tools[id]?.id).toBe(id) + } + }) + + it('sets Basic PAT auth on every tool', () => { + for (const tool of allTools) { + expect( + buildHeaders(tool, { + ...baseParams, + pipelineId: 1, + runId: 2, + buildId: 3, + logId: 4, + fromBuildId: 5, + toBuildId: 6, + workItemId: 7, + ids: '7', + wiqlQuery: 'SELECT [System.Id] FROM workitems', + workItemType: 'Issue', + title: 'Issue title', + text: 'Comment text', + }).Authorization + ).toBe(authHeader) + } + }) +}) + +describe('Azure DevOps request builders', () => { + it('builds pipeline URLs and optional params', () => { + expect(buildUrl(listPipelinesTool, baseParams)).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/pipelines?api-version=7.2-preview.1' + ) + expect( + buildUrl(listPipelinesTool, { + ...baseParams, + orderBy: 'name', + top: 10, + continuationToken: 'next-page', + } satisfies ListPipelinesParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/pipelines?api-version=7.2-preview.1&orderBy=name&%24top=10&continuationToken=next-page' + ) + expect( + buildUrl(getPipelineTool, { + ...baseParams, + pipelineId: 42, + pipelineVersion: 3, + } satisfies GetPipelineParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/pipelines/42?api-version=7.2-preview.1&pipelineVersion=3' + ) + expect( + buildUrl(listPipelineRunsTool, { + ...baseParams, + pipelineId: 42, + } satisfies ListPipelineRunsParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/pipelines/42/runs?api-version=7.2-preview.1' + ) + expect( + buildUrl(getPipelineRunTool, { + ...baseParams, + pipelineId: 42, + runId: 99, + } satisfies GetPipelineRunParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/pipelines/42/runs/99?api-version=7.2-preview.1' + ) + }) + + it('builds build URLs and optional filters', () => { + expect( + buildUrl(listBuildsTool, { + ...baseParams, + definitionIds: '1,2', + top: 20, + statusFilter: 'completed', + resultFilter: 'failed', + branchName: 'refs/heads/main', + } satisfies ListBuildsParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/build/builds?api-version=7.2-preview.8&definitions=1%2C2&%24top=20&statusFilter=completed&resultFilter=failed&branchName=refs%2Fheads%2Fmain' + ) + expect( + buildUrl(listBuildLogsTool, { + ...baseParams, + buildId: 101, + } satisfies ListBuildLogsParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/build/builds/101/logs?api-version=7.2-preview.2' + ) + expect( + buildUrl(getBuildLogTool, { + ...baseParams, + buildId: 101, + logId: 3, + startLine: 5, + endLine: 15, + } satisfies GetBuildLogParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/build/builds/101/logs/3?api-version=7.2-preview.2&startLine=5&endLine=15' + ) + expect(buildHeaders(getBuildLogTool, { ...baseParams, buildId: 101, logId: 3 }).Accept).toBe( + 'text/plain' + ) + }) + + it('uses the documented work-items-between-builds endpoint shape', () => { + expect( + buildUrl(getWorkItemsBetweenBuildsTool, { + ...baseParams, + fromBuildId: 11, + toBuildId: 12, + } satisfies GetWorkItemsBetweenBuildsParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/build/workitems?fromBuildId=11&toBuildId=12&api-version=7.2-preview.2' + ) + }) + + it('builds work item URLs and bodies', () => { + expect(buildUrl(queryWorkItemsTool, baseParams)).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/wiql?api-version=7.2-preview.2' + ) + expect( + buildBody(queryWorkItemsTool, { + ...baseParams, + wiqlQuery: 'SELECT [System.Id] FROM workitems', + } satisfies QueryWorkItemsParams) + ).toEqual({ query: 'SELECT [System.Id] FROM workitems' }) + expect( + buildUrl(getWorkItemTool, { + ...baseParams, + workItemId: 101, + } satisfies GetWorkItemParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/workitems/101?%24expand=all&api-version=7.2-preview.3' + ) + expect( + buildUrl(getWorkItemsBatchTool, { + ...baseParams, + ids: '101,102', + } satisfies GetWorkItemsBatchParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/workitems?ids=101%2C102&%24expand=all&api-version=7.2-preview.3' + ) + }) + + it('builds JSON Patch work item write requests', () => { + const createParams = { + ...baseParams, + workItemType: 'Issue', + title: 'Pipeline failure', + description: '

Failure details

', + assignedTo: 'ada@example.com', + areaPath: 'Fabrikam\\Platform', + } satisfies CreateWorkItemParams + + expect(buildUrl(createWorkItemTool, createParams)).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/workitems/$Issue?api-version=7.2-preview.3' + ) + expect(buildHeaders(createWorkItemTool, createParams)['Content-Type']).toBe( + 'application/json-patch+json' + ) + expect(buildBody(createWorkItemTool, createParams)).toEqual([ + { op: 'add', path: '/fields/System.Title', value: 'Pipeline failure' }, + { op: 'add', path: '/fields/System.Description', value: '

Failure details

' }, + { op: 'add', path: '/fields/System.AssignedTo', value: 'ada@example.com' }, + { op: 'add', path: '/fields/System.AreaPath', value: 'Fabrikam\\Platform' }, + ]) + + const updateParams = { + ...baseParams, + workItemId: 101, + title: 'Updated pipeline failure', + state: 'Doing', + effort: 5, + } satisfies UpdateWorkItemParams + + expect(buildUrl(updateWorkItemTool, updateParams)).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/workitems/101?api-version=7.2-preview.3' + ) + expect(buildHeaders(updateWorkItemTool, updateParams)['Content-Type']).toBe( + 'application/json-patch+json' + ) + expect(buildBody(updateWorkItemTool, updateParams)).toEqual([ + { op: 'replace', path: '/fields/System.Title', value: 'Updated pipeline failure' }, + { op: 'replace', path: '/fields/System.State', value: 'Doing' }, + { op: 'replace', path: '/fields/Microsoft.VSTS.Scheduling.Effort', value: 5 }, + ]) + expect(() => buildBody(updateWorkItemTool, { ...baseParams, workItemId: 101 })).toThrow( + /requires at least one field/ + ) + + const createWithEffortParams = { + ...createParams, + effort: 3, + } satisfies CreateWorkItemParams + + expect(buildBody(createWorkItemTool, createWithEffortParams)).toContainEqual({ + op: 'add', + path: '/fields/Microsoft.VSTS.Scheduling.Effort', + value: 3, + }) + }) + + it('emits Epic-only scheduling patch ops on create', () => { + const epicParams = { + ...baseParams, + workItemType: 'Epic', + title: 'Q3 platform epic', + startDate: '2026-06-01T00:00:00Z', + targetDate: '2026-09-30T00:00:00Z', + } satisfies CreateWorkItemParams + + const body = buildBody(createWorkItemTool, epicParams) + expect(body).toContainEqual({ + op: 'add', + path: '/fields/Microsoft.VSTS.Scheduling.StartDate', + value: '2026-06-01T00:00:00Z', + }) + expect(body).toContainEqual({ + op: 'add', + path: '/fields/Microsoft.VSTS.Scheduling.TargetDate', + value: '2026-09-30T00:00:00Z', + }) + }) + + it('emits Task-only activity/work patch ops on create', () => { + const taskParams = { + ...baseParams, + workItemType: 'Task', + title: 'Wire up retries', + activity: 'Development', + remainingWork: 4, + completedWork: 1, + } satisfies CreateWorkItemParams + + const body = buildBody(createWorkItemTool, taskParams) + expect(body).toContainEqual({ + op: 'add', + path: '/fields/Microsoft.VSTS.Common.Activity', + value: 'Development', + }) + expect(body).toContainEqual({ + op: 'add', + path: '/fields/Microsoft.VSTS.Scheduling.RemainingWork', + value: 4, + }) + expect(body).toContainEqual({ + op: 'add', + path: '/fields/Microsoft.VSTS.Scheduling.CompletedWork', + value: 1, + }) + }) + + it('emits per-type replace ops on update when fields are provided', () => { + const updateAll = { + ...baseParams, + workItemId: 101, + startDate: '2026-06-01T00:00:00Z', + activity: 'Testing', + remainingWork: 2, + } satisfies UpdateWorkItemParams + + const body = buildBody(updateWorkItemTool, updateAll) + expect(body).toContainEqual({ + op: 'replace', + path: '/fields/Microsoft.VSTS.Scheduling.StartDate', + value: '2026-06-01T00:00:00Z', + }) + expect(body).toContainEqual({ + op: 'replace', + path: '/fields/Microsoft.VSTS.Common.Activity', + value: 'Testing', + }) + expect(body).toContainEqual({ + op: 'replace', + path: '/fields/Microsoft.VSTS.Scheduling.RemainingWork', + value: 2, + }) + }) + + it('builds comment URLs and bodies with comment API pinning', () => { + const addParams = { + ...baseParams, + workItemId: 101, + text: 'SimIntegrationTest markdown comment', + } satisfies AddCommentParams + + expect(buildUrl(addCommentTool, addParams)).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/workitems/101/comments?api-version=7.0-preview.3' + ) + expect(buildBody(addCommentTool, addParams)).toEqual({ + text: 'SimIntegrationTest markdown comment', + }) + + expect( + buildUrl(getCommentsTool, { + ...baseParams, + workItemId: 101, + top: 2, + continuationToken: 'next', + includeDeleted: true, + expand: 'renderedText', + order: 'desc', + } satisfies GetCommentsParams) + ).toBe( + 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/workitems/101/comments?api-version=7.2-preview.4&%24top=2&continuationToken=next&includeDeleted=true&%24expand=renderedText&order=desc' + ) + }) +}) + +describe('Azure DevOps response transforms', () => { + const originalFetch = globalThis.fetch + + afterEach(() => { + globalThis.fetch = originalFetch + }) + + it('transforms list pipelines responses and empty results', async () => { + await expect( + listPipelinesTool.transformResponse!(responseJson({ count: 0, value: [] })) + ).resolves.toEqual({ + success: true, + output: { content: 'No pipelines found.', metadata: { count: 0, pipelines: [] } }, + }) + + const result = await listPipelinesTool.transformResponse!( + responseJson({ + value: [{ id: 1, name: 'CI', revision: 2, url: 'https://example/p/1' }], + }) + ) + + expect(result.output.metadata).toEqual({ + count: 1, + pipelines: [{ id: 1, name: 'CI', folder: '\\', revision: 2, url: 'https://example/p/1' }], + }) + }) + + it('transforms pipeline detail and run responses with missing optional links', async () => { + const pipeline = await getPipelineTool.transformResponse!( + responseJson({ + id: 42, + name: 'CI', + revision: 3, + url: 'https://example/p/42', + configuration: { type: 'yaml', path: '/azure-pipelines.yml' }, + }) + ) + + expect(pipeline.output.metadata.pipeline.links.web).toBe('') + expect(pipeline.output.metadata.pipeline.configuration.repository).toBeUndefined() + + const runs = await listPipelineRunsTool.transformResponse!(responseJson({ value: [] })) + expect(runs.output).toEqual({ + content: 'No pipeline runs found.', + metadata: { count: 0, runs: [] }, + }) + + const run = await getPipelineRunTool.transformResponse!( + responseJson({ + id: 99, + name: '20260515.1', + state: 'completed', + result: 'failed', + createdDate: '2026-05-15T10:00:00Z', + finishedDate: '2026-05-15T10:05:00Z', + url: 'https://example/r/99', + pipeline: { id: 42, name: 'CI', revision: 3, url: 'https://example/p/42' }, + }) + ) + + expect(run.output.metadata.run.pipeline.folder).toBe('\\') + expect(run.output.metadata.run.result).toBe('failed') + }) + + it('transforms build and log responses', async () => { + const builds = await listBuildsTool.transformResponse!( + responseJson({ + value: [ + { + id: 201, + buildNumber: '20260515.1', + status: 'completed', + result: 'failed', + queueTime: '2026-05-15T10:00:00Z', + sourceBranch: 'refs/heads/main', + sourceVersion: 'abc123', + }, + ], + }) + ) + + expect(builds.output.metadata.builds[0].definition).toEqual({ id: 0, name: '' }) + + const logs = await listBuildLogsTool.transformResponse!( + responseJson({ + count: 1, + value: [ + { + id: 3, + type: 'Container', + url: 'https://example/log/3', + lineCount: 25, + createdOn: '2026-05-15T10:00:00Z', + }, + ], + }) + ) + + expect(logs.output.metadata.logs[0].lineCount).toBe(25) + + const log = await getBuildLogTool.transformResponse!( + new Response('line one\nline two\nline three\n') + ) + + expect(log.output.metadata.lineCount).toBe(3) + await expect(getBuildLogTool.transformResponse!(new Response(' '))).resolves.toEqual({ + success: true, + output: { content: 'Log is empty.', metadata: { lineCount: 0 } }, + }) + }) + + it('transforms work item references and hydrated work items', async () => { + const betweenBuilds = await getWorkItemsBetweenBuildsTool.transformResponse!( + responseJson({ value: [{ id: 101, url: 'https://example/workitems/101' }] }) + ) + + expect(betweenBuilds.output.metadata.workItems).toEqual([ + { id: '101', url: 'https://example/workitems/101' }, + ]) + + const getWorkItem = await getWorkItemTool.transformResponse!(responseJson(rawWorkItem)) + expect(getWorkItem.output.metadata.workItem).toEqual({ + id: 101, + title: 'SimIntegrationTest Issue', + state: 'Doing', + workItemType: 'Issue', + assignedTo: 'Ada Lovelace', + areaPath: 'Fabrikam\\Platform', + url: 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/workItems/101', + }) + + const batch = await getWorkItemsBatchTool.transformResponse!( + responseJson({ value: [rawWorkItem] }), + { ...baseParams, ids: '101' } satisfies GetWorkItemsBatchParams + ) + expect(batch.output.metadata.count).toBe(1) + expect(batch.output.metadata.totalRequested).toBe(1) + }) + + it('hydrates WIQL query results in chunks of 200 IDs', async () => { + const fetchMock = vi + .fn() + .mockImplementation(() => Promise.resolve(responseJson({ value: [rawWorkItem] }))) + globalThis.fetch = fetchMock as unknown as typeof fetch + + const workItems = Array.from({ length: 201 }, (_, index) => ({ + id: index + 1, + url: `https://example/workitems/${index + 1}`, + })) + + const result = await queryWorkItemsTool.transformResponse!(responseJson({ workItems }), { + ...baseParams, + wiqlQuery: 'SELECT [System.Id] FROM workitems', + } satisfies QueryWorkItemsParams) + + expect(fetchMock).toHaveBeenCalledTimes(2) + const firstChunk = new URL(String(fetchMock.mock.calls[0][0])) + const secondChunk = new URL(String(fetchMock.mock.calls[1][0])) + expect(firstChunk.searchParams.get('ids')?.split(',')).toHaveLength(200) + expect(secondChunk.searchParams.get('ids')?.split(',')).toHaveLength(1) + expect(result.output.metadata.totalMatched).toBe(201) + expect(result.output.metadata.workItems).toHaveLength(2) + }) + + it('throws when Get Work Items Batch is invoked with no valid IDs', () => { + expect(() => + buildUrl(getWorkItemsBatchTool, { + ...baseParams, + ids: ' , , ', + } satisfies GetWorkItemsBatchParams) + ).toThrow(/requires at least one work item ID/) + }) + + it('chunks Get Work Items Batch requests larger than 200 IDs', async () => { + const fetchMock = vi + .fn() + .mockImplementation(() => Promise.resolve(responseJson({ value: [rawWorkItem] }))) + globalThis.fetch = fetchMock as unknown as typeof fetch + + const ids = Array.from({ length: 350 }, (_, i) => String(i + 1)).join(',') + + const result = await getWorkItemsBatchTool.transformResponse!( + responseJson({ value: [rawWorkItem] }), + { ...baseParams, ids } satisfies GetWorkItemsBatchParams + ) + + expect(fetchMock).toHaveBeenCalledTimes(1) + const followupChunk = new URL(String(fetchMock.mock.calls[0][0])) + expect(followupChunk.searchParams.get('ids')?.split(',')).toHaveLength(150) + expect(result.output.metadata.totalRequested).toBe(350) + expect(result.output.metadata.workItems).toHaveLength(2) + }) + + it('throws when WIQL hydration fetch returns a non-OK status', async () => { + const fetchMock = vi + .fn() + .mockResolvedValue(new Response('forbidden', { status: 403, statusText: 'Forbidden' })) + globalThis.fetch = fetchMock as unknown as typeof fetch + + await expect( + queryWorkItemsTool.transformResponse!(responseJson({ workItems: [{ id: 1, url: 'x' }] }), { + ...baseParams, + wiqlQuery: 'SELECT [System.Id] FROM workitems', + } satisfies QueryWorkItemsParams) + ).rejects.toThrow(/Failed to hydrate work item details/) + }) + + it('does not hydrate WIQL empty results', async () => { + const fetchMock = vi.fn() + globalThis.fetch = fetchMock as unknown as typeof fetch + + const result = await queryWorkItemsTool.transformResponse!(responseJson({ workItems: [] }), { + ...baseParams, + wiqlQuery: 'SELECT [System.Id] FROM workitems WHERE [System.Id] = 0', + } satisfies QueryWorkItemsParams) + + expect(fetchMock).not.toHaveBeenCalled() + expect(result.output.metadata).toEqual({ count: 0, workItems: [] }) + }) + + it('transforms create and update work item responses', async () => { + const created = await createWorkItemTool.transformResponse!(responseJson(rawWorkItem)) + expect(created.output.content).toContain('Created work item #101') + + const updated = await updateWorkItemTool.transformResponse!(responseJson(rawWorkItem)) + expect(updated.output.content).toContain('Updated work item #101') + }) + + it('transforms comment responses and empty comment lists', async () => { + const added = await addCommentTool.transformResponse!(responseJson(rawComment)) + expect(added.output.metadata.comment).toEqual({ + workItemId: 101, + commentId: 9, + version: 1, + text: 'SimIntegrationTest comment', + renderedText: '

SimIntegrationTest comment

', + createdBy: 'Ada Lovelace', + createdDate: '2026-05-15T10:00:00Z', + modifiedBy: 'Ada Lovelace', + modifiedDate: '2026-05-15T10:00:00Z', + isDeleted: false, + url: 'https://dev.azure.com/contoso/Fabrikam/_apis/wit/workitems/101/comments/9', + }) + + const comments = await getCommentsTool.transformResponse!( + responseJson({ + count: 1, + totalCount: 2, + comments: [rawComment], + continuationToken: 'next', + nextPage: 'https://example/next', + }) + ) + expect(comments.output.metadata.count).toBe(1) + expect(comments.output.metadata.continuationToken).toBe('next') + + const empty = await getCommentsTool.transformResponse!(responseJson({ comments: [] })) + expect(empty.output).toEqual({ + content: 'No comments found for this work item.', + metadata: { count: 0, totalCount: 0, comments: [] }, + }) + }) +}) + +describe('Azure DevOps trigger event matching', () => { + const baseBuild = { eventType: 'build.complete' } + const baseWorkItem = { eventType: 'workitem.created' } + + it('matches build.complete results case-insensitively including stopped/Failed/Canceled', () => { + for (const result of [ + 'failed', + 'Failed', + 'FAILED', + 'canceled', + 'Canceled', + 'cancelled', + 'Cancelled', + 'stopped', + 'Stopped', + 'partiallySucceeded', + 'PartiallySucceeded', + ]) { + expect( + isAzureDevOpsEventMatch('azure_devops_build_failed', { + ...baseBuild, + resource: { result }, + }) + ).toBe(true) + } + }) + + it('does not match successful build.complete payloads', () => { + for (const result of ['succeeded', 'Succeeded', 'inProgress']) { + expect( + isAzureDevOpsEventMatch('azure_devops_build_failed', { + ...baseBuild, + resource: { result }, + }) + ).toBe(false) + } + }) + + it('ignores non-build event types when expecting build.complete', () => { + expect( + isAzureDevOpsEventMatch('azure_devops_build_failed', { + eventType: 'workitem.created', + resource: { result: 'failed' }, + }) + ).toBe(false) + }) + + it('build timeline includes partiallySucceeded and succeededWithIssues in failedRecords', async () => { + const records = [ + { id: 'a', name: 'Step A', type: 'Task', result: 'succeeded', log: { id: 1 } }, + { id: 'b', name: 'Step B', type: 'Task', result: 'failed', log: { id: 2 } }, + { id: 'c', name: 'Step C', type: 'Task', result: 'partiallySucceeded', log: { id: 3 } }, + { id: 'd', name: 'Step D', type: 'Task', result: 'succeededWithIssues', log: { id: 4 } }, + { id: 'e', name: 'Step E', type: 'Task', result: 'skipped', log: null }, + ] + const result = await getBuildTimelineTool.transformResponse!( + new Response(JSON.stringify({ records })) + ) + const failedIds = result.output.metadata.failedRecords.map((r) => r.id) + expect(failedIds).toEqual(['b', 'c', 'd']) + expect(result.output.metadata.failedCount).toBe(3) + }) + + it('matches workitem.created and passes through generic webhook', () => { + expect(isAzureDevOpsEventMatch('azure_devops_work_item_created', baseWorkItem)).toBe(true) + expect(isAzureDevOpsEventMatch('azure_devops_work_item_created', baseBuild)).toBe(false) + expect(isAzureDevOpsEventMatch('azure_devops_webhook', { eventType: 'anything' })).toBe(true) + }) + + it('extractIdempotencyId returns null when subscriptionId or notificationId is missing', async () => { + const { azureDevOpsHandler } = await import('@/lib/webhooks/providers/azure-devops') + expect(azureDevOpsHandler.extractIdempotencyId!({})).toBeNull() + expect(azureDevOpsHandler.extractIdempotencyId!({ subscriptionId: 'sub-1' })).toBeNull() + expect(azureDevOpsHandler.extractIdempotencyId!({ notificationId: 42 })).toBeNull() + expect( + azureDevOpsHandler.extractIdempotencyId!({ subscriptionId: 'sub-1', notificationId: 42 }) + ).toBe('azure_devops:sub-1:42') + expect(azureDevOpsHandler.extractIdempotencyId!(null)).toBeNull() + }) +}) diff --git a/apps/sim/tools/azure_devops/create_work_item.ts b/apps/sim/tools/azure_devops/create_work_item.ts new file mode 100644 index 00000000000..8ba561930ca --- /dev/null +++ b/apps/sim/tools/azure_devops/create_work_item.ts @@ -0,0 +1,247 @@ +import type { + AzureDevOpsWorkItem, + CreateWorkItemParams, + CreateWorkItemResponse, +} from '@/tools/azure_devops/types' +import type { AzureDevOpsJsonPatchOp, AzureDevOpsRawWorkItem } from '@/tools/azure_devops/utils' +import { + appendEffortPatchOp, + appendFieldPatchOp, + formatWorkItem, + mapWorkItem, +} from '@/tools/azure_devops/utils' +import type { ToolConfig } from '@/tools/types' + +export const createWorkItemTool: ToolConfig = { + id: 'azure_devops_create_work_item', + name: 'Azure DevOps Create Work Item', + description: + 'Create a new Basic-process work item (Issue, Task, or Epic) in Azure DevOps. Returns the created work item with its assigned ID.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + workItemType: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: + 'Basic-process work item type to create ("Issue", "Task", or "Epic"). Use Issue for bug or defect tracking.', + }, + title: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Title of the new work item', + }, + description: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'HTML description of the work item (optional)', + }, + assignedTo: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Email or display name of the user to assign the work item to (optional)', + }, + priority: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Priority of the work item (1 = Critical, 2 = High, 3 = Medium, 4 = Low)', + }, + effort: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Effort (Microsoft.VSTS.Scheduling.Effort). Basic process: Issue only.', + }, + startDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Start date (Microsoft.VSTS.Scheduling.StartDate), ISO 8601. Basic process: Epic only.', + }, + targetDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Target date (Microsoft.VSTS.Scheduling.TargetDate), ISO 8601. Basic process: Epic only.', + }, + activity: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Activity (Microsoft.VSTS.Common.Activity). One of Deployment, Design, Development, Documentation, Requirements, Testing. Basic process: Task only.', + }, + remainingWork: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: + 'Remaining work hours (Microsoft.VSTS.Scheduling.RemainingWork). Basic process: Task only.', + }, + completedWork: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: + 'Completed work hours (Microsoft.VSTS.Scheduling.CompletedWork). Basic process: Task only.', + }, + areaPath: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Area path for the work item, e.g. "MyProject\\\\Team" (optional)', + }, + iterationPath: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Iteration path for the work item, e.g. "MyProject\\\\Sprint 1" (optional)', + }, + tags: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Semicolon-separated tags, e.g. "issue; p1; auth" (optional)', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Work Items: Read & Write)', + }, + }, + + request: { + url: (params) => + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/wit/workitems/$${encodeURIComponent(params.workItemType)}?api-version=7.2-preview.3`, + method: 'POST', + headers: (params) => ({ + 'Content-Type': 'application/json-patch+json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + body: (params) => { + const ops: AzureDevOpsJsonPatchOp[] = [ + { op: 'add', path: '/fields/System.Title', value: params.title }, + ] + if (params.description) { + ops.push({ op: 'add', path: '/fields/System.Description', value: params.description }) + } + if (params.assignedTo) { + ops.push({ op: 'add', path: '/fields/System.AssignedTo', value: params.assignedTo }) + } + if (params.priority !== undefined) { + ops.push({ + op: 'add', + path: '/fields/Microsoft.VSTS.Common.Priority', + value: String(Number(params.priority)), + }) + } + appendEffortPatchOp(ops, params.effort, 'add') + appendFieldPatchOp( + ops, + 'Microsoft.VSTS.Scheduling.StartDate', + params.startDate, + 'add', + 'string' + ) + appendFieldPatchOp( + ops, + 'Microsoft.VSTS.Scheduling.TargetDate', + params.targetDate, + 'add', + 'string' + ) + appendFieldPatchOp(ops, 'Microsoft.VSTS.Common.Activity', params.activity, 'add', 'string') + appendFieldPatchOp( + ops, + 'Microsoft.VSTS.Scheduling.RemainingWork', + params.remainingWork, + 'add', + 'number' + ) + appendFieldPatchOp( + ops, + 'Microsoft.VSTS.Scheduling.CompletedWork', + params.completedWork, + 'add', + 'number' + ) + if (params.areaPath) { + ops.push({ op: 'add', path: '/fields/System.AreaPath', value: params.areaPath }) + } + if (params.iterationPath) { + ops.push({ op: 'add', path: '/fields/System.IterationPath', value: params.iterationPath }) + } + if (params.tags) { + ops.push({ op: 'add', path: '/fields/System.Tags', value: params.tags }) + } + return ops + }, + }, + + transformResponse: async (response) => { + const raw: AzureDevOpsRawWorkItem = await response.json() + const workItem: AzureDevOpsWorkItem = mapWorkItem(raw) + return { + success: true, + output: { + content: `Created work item #${workItem.id}:\n\n${formatWorkItem(workItem)}`, + metadata: { workItem }, + }, + } + }, + + outputs: { + content: { + type: 'string', + description: 'Human-readable summary of the created work item', + }, + metadata: { + type: 'object', + description: 'Created work item metadata', + properties: { + workItem: { + type: 'object', + description: 'Full details of the created work item', + properties: { + id: { type: 'number', description: 'Assigned work item ID' }, + title: { type: 'string', description: 'Work item title' }, + state: { + type: 'string', + description: 'Initial state for Basic process (e.g. To Do, Doing, Done)', + }, + workItemType: { + type: 'string', + description: 'Work item type returned by Azure DevOps (e.g. Issue, Task, Epic)', + }, + assignedTo: { + type: 'string', + description: 'Display name of assigned user, or null if unassigned', + }, + areaPath: { type: 'string', description: 'Area path of the work item' }, + url: { type: 'string', description: 'API URL for the created work item' }, + }, + }, + }, + }, + }, +} diff --git a/apps/sim/tools/azure_devops/get_build_log.ts b/apps/sim/tools/azure_devops/get_build_log.ts new file mode 100644 index 00000000000..300082db80f --- /dev/null +++ b/apps/sim/tools/azure_devops/get_build_log.ts @@ -0,0 +1,101 @@ +import type { GetBuildLogParams, GetBuildLogResponse } from '@/tools/azure_devops/types' +import type { ToolConfig } from '@/tools/types' + +export const getBuildLogTool: ToolConfig = { + id: 'azure_devops_get_build_log', + name: 'Azure DevOps Get Build Log', + description: + 'Fetch the text content of a specific build log in Azure DevOps. Use List Build Logs first to get the log ID. Optionally retrieve only a line range with startLine/endLine.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + buildId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'The build ID containing the log', + }, + logId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'The log entry ID to fetch (from List Build Logs)', + }, + startLine: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'First line to return (1-based, inclusive)', + }, + endLine: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Last line to return (1-based, inclusive)', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Build: Read)', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/build/builds/${params.buildId}/logs/${params.logId}` + ) + url.searchParams.set('api-version', '7.2-preview.2') + if (params.startLine !== undefined) + url.searchParams.set('startLine', Number(params.startLine).toString()) + if (params.endLine !== undefined) + url.searchParams.set('endLine', Number(params.endLine).toString()) + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + Accept: 'text/plain', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const text = await response.text() + const trimmed = text.trim() + const lineCount = trimmed.length === 0 ? 0 : trimmed.split('\n').length + + return { + success: true, + output: { + content: trimmed.length === 0 ? 'Log is empty.' : text, + metadata: { + lineCount, + }, + }, + } + }, + + outputs: { + content: { type: 'string', description: 'Raw log text' }, + metadata: { + type: 'object', + description: 'Log metadata', + properties: { + lineCount: { type: 'number', description: 'Number of lines in the returned log text' }, + }, + }, + }, +} diff --git a/apps/sim/tools/azure_devops/get_build_timeline.ts b/apps/sim/tools/azure_devops/get_build_timeline.ts new file mode 100644 index 00000000000..fbb10bdbaa7 --- /dev/null +++ b/apps/sim/tools/azure_devops/get_build_timeline.ts @@ -0,0 +1,164 @@ +import type { + AzureDevOpsBuildTimelineRecord, + GetBuildTimelineParams, + GetBuildTimelineResponse, +} from '@/tools/azure_devops/types' +import type { ToolConfig } from '@/tools/types' + +export const getBuildTimelineTool: ToolConfig = { + id: 'azure_devops_get_build_timeline', + name: 'Azure DevOps Get Build Timeline', + description: + 'Get the execution timeline for an Azure DevOps build — every stage, job, and task with its result and log ID. Use this to identify which steps failed before fetching their logs with Get Build Log.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + buildId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'ID of the build whose timeline to retrieve', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Build: Read)', + }, + }, + + request: { + url: (params) => + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/build/builds/${Number(params.buildId)}/timeline?api-version=7.2-preview.3`, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + const records: AzureDevOpsBuildTimelineRecord[] = (data.records ?? []).map( + (r: { + id: string + name: string + type: string + result: string | null + log?: { id?: number } | null + errorCount?: number + warningCount?: number + startTime?: string + finishTime?: string + }) => ({ + id: r.id, + name: r.name, + type: r.type, + result: r.result ?? null, + logId: r.log?.id ?? null, + errorCount: r.errorCount ?? 0, + warningCount: r.warningCount ?? 0, + startTime: r.startTime ?? '', + finishTime: r.finishTime ?? '', + }) + ) + + const failedRecords = records.filter((r) => { + const result = r.result?.toLowerCase() + return ( + result === 'failed' || result === 'partiallysucceeded' || result === 'succeededwithissues' + ) + }) + + const content = + failedRecords.length === 0 + ? `Build timeline: ${records.length} record(s), no failures detected.` + : `Build timeline: ${records.length} record(s), ${failedRecords.length} failed:\n\n` + + failedRecords + .map( + (r) => + `[${r.type}] ${r.name} — result: ${r.result}, logId: ${r.logId ?? 'none'}, errors: ${r.errorCount}` + ) + .join('\n') + + return { + success: true, + output: { + content, + metadata: { + totalCount: records.length, + failedCount: failedRecords.length, + records, + failedRecords, + }, + }, + } + }, + + outputs: { + content: { + type: 'string', + description: 'Summary of the build timeline, highlighting failed steps', + }, + metadata: { + type: 'object', + description: 'Build timeline metadata', + properties: { + totalCount: { type: 'number', description: 'Total number of timeline records' }, + failedCount: { type: 'number', description: 'Number of failed records' }, + records: { + type: 'array', + description: 'All timeline records (stages, jobs, tasks)', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'Record GUID' }, + name: { type: 'string', description: 'Step name (e.g. "Run tests")' }, + type: { type: 'string', description: 'Stage | Phase | Job | Task' }, + result: { + type: 'string', + description: 'succeeded | failed | skipped | canceled | null', + }, + logId: { type: 'number', description: 'Log ID to pass to Get Build Log, or null' }, + errorCount: { type: 'number', description: 'Number of errors' }, + warningCount: { type: 'number', description: 'Number of warnings' }, + startTime: { type: 'string', description: 'ISO 8601 start timestamp' }, + finishTime: { type: 'string', description: 'ISO 8601 finish timestamp' }, + }, + }, + }, + failedRecords: { + type: 'array', + description: + 'Subset of records where result is failed, partiallySucceeded, or succeededWithIssues — use logId to fetch logs', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'Record GUID' }, + name: { type: 'string', description: 'Step name' }, + type: { type: 'string', description: 'Stage | Phase | Job | Task' }, + result: { type: 'string', description: 'failed' }, + logId: { type: 'number', description: 'Log ID to pass to Get Build Log' }, + errorCount: { type: 'number', description: 'Number of errors' }, + warningCount: { type: 'number', description: 'Number of warnings' }, + startTime: { type: 'string', description: 'ISO 8601 start timestamp' }, + finishTime: { type: 'string', description: 'ISO 8601 finish timestamp' }, + }, + }, + }, + }, + }, + }, +} diff --git a/apps/sim/tools/azure_devops/get_comments.ts b/apps/sim/tools/azure_devops/get_comments.ts new file mode 100644 index 00000000000..0b41036ec46 --- /dev/null +++ b/apps/sim/tools/azure_devops/get_comments.ts @@ -0,0 +1,186 @@ +import type { + AzureDevOpsComment, + GetCommentsParams, + GetCommentsResponse, +} from '@/tools/azure_devops/types' +import type { AzureDevOpsRawComment } from '@/tools/azure_devops/utils' +import { formatComment, mapComment } from '@/tools/azure_devops/utils' +import type { ToolConfig } from '@/tools/types' + +export const getCommentsTool: ToolConfig = { + id: 'azure_devops_get_comments', + name: 'Azure DevOps Get Comments', + description: 'List comments for an Azure DevOps work item.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + workItemId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'ID of the work item whose comments should be listed', + }, + top: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of comments to return', + }, + continuationToken: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Continuation token for paginating comments', + }, + includeDeleted: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether deleted comments should be returned', + }, + expand: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Additional comment data to include: none, reactions, renderedText, renderedTextOnly, all', + }, + order: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Sort order for comments: asc or desc', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Work Items: Read)', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/wit/workitems/${Number(params.workItemId)}/comments` + ) + url.searchParams.set('api-version', '7.2-preview.4') + if (params.top) url.searchParams.set('$top', Number(params.top).toString()) + if (params.continuationToken) + url.searchParams.set('continuationToken', params.continuationToken) + if (params.includeDeleted !== undefined) + url.searchParams.set('includeDeleted', String(params.includeDeleted)) + if (params.expand) url.searchParams.set('$expand', params.expand) + if (params.order) url.searchParams.set('order', params.order) + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + const comments: AzureDevOpsComment[] = (data.comments ?? []).map((raw: AzureDevOpsRawComment) => + mapComment(raw) + ) + + const content = + comments.length === 0 + ? 'No comments found for this work item.' + : `Found ${data.count ?? comments.length} comment(s):\n\n${comments + .map(formatComment) + .join('\n\n')}` + + return { + success: true, + output: { + content, + metadata: { + count: data.count ?? comments.length, + totalCount: data.totalCount ?? comments.length, + comments, + continuationToken: data.continuationToken, + nextPage: data.nextPage, + url: data.url, + }, + }, + } + }, + + outputs: { + content: { + type: 'string', + description: 'Human-readable summary of work item comments', + }, + metadata: { + type: 'object', + description: 'Comments metadata', + properties: { + count: { type: 'number', description: 'Number of comments returned in this page' }, + totalCount: { type: 'number', description: 'Total number of comments on the work item' }, + continuationToken: { + type: 'string', + description: 'Continuation token for the next page', + optional: true, + }, + nextPage: { + type: 'string', + description: 'API URL for the next page', + optional: true, + }, + url: { + type: 'string', + description: 'API URL for this comments list', + optional: true, + }, + comments: { + type: 'array', + description: 'Array of work item comments', + items: { + type: 'object', + properties: { + workItemId: { type: 'number', description: 'Work item ID' }, + commentId: { type: 'number', description: 'Comment ID' }, + version: { type: 'number', description: 'Comment version' }, + text: { type: 'string', description: 'Comment text' }, + renderedText: { + type: 'string', + description: 'Rendered HTML comment text when available', + optional: true, + }, + createdBy: { + type: 'string', + description: 'Display name of the comment author', + nullable: true, + }, + createdDate: { type: 'string', description: 'ISO 8601 creation timestamp' }, + modifiedBy: { + type: 'string', + description: 'Display name of the last modifier', + nullable: true, + }, + modifiedDate: { type: 'string', description: 'ISO 8601 modified timestamp' }, + isDeleted: { type: 'boolean', description: 'Whether the comment is deleted' }, + url: { type: 'string', description: 'API URL for the comment' }, + }, + }, + }, + }, + }, + }, +} diff --git a/apps/sim/tools/azure_devops/get_pipeline.ts b/apps/sim/tools/azure_devops/get_pipeline.ts new file mode 100644 index 00000000000..c08af037ecd --- /dev/null +++ b/apps/sim/tools/azure_devops/get_pipeline.ts @@ -0,0 +1,167 @@ +import type { GetPipelineParams, GetPipelineResponse } from '@/tools/azure_devops/types' +import type { ToolConfig } from '@/tools/types' + +export const getPipelineTool: ToolConfig = { + id: 'azure_devops_get_pipeline', + name: 'Azure DevOps Get Pipeline', + description: + 'Get details for a specific pipeline in an Azure DevOps project, including configuration and repository info.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + pipelineId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'ID of the pipeline to retrieve', + }, + pipelineVersion: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Specific revision of the pipeline to retrieve (defaults to latest)', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Build: Read, Pipeline: Read)', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/pipelines/${params.pipelineId}` + ) + url.searchParams.set('api-version', '7.2-preview.1') + if (params.pipelineVersion) + url.searchParams.set('pipelineVersion', Number(params.pipelineVersion).toString()) + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + + const pipeline: AzureDevOpsPipelineDetailItem = { + id: data.id, + name: data.name, + folder: data.folder ?? '\\', + revision: data.revision, + url: data.url, + configuration: { + type: data.configuration?.type ?? 'unknown', + path: data.configuration?.path, + repository: data.configuration?.repository + ? { id: data.configuration.repository.id, type: data.configuration.repository.type } + : undefined, + }, + links: { + self: data._links?.self?.href ?? '', + web: data._links?.web?.href ?? '', + }, + } + + const pathLine = pipeline.configuration.path ? `\n Path: ${pipeline.configuration.path}` : '' + const repoLine = pipeline.configuration.repository + ? `\n Repository: ${pipeline.configuration.repository.id} (${pipeline.configuration.repository.type})` + : '' + + const content = + `Pipeline: ${pipeline.name} (ID: ${pipeline.id})\n` + + `Folder: ${pipeline.folder}\n` + + `Revision: ${pipeline.revision}\n` + + `Config type: ${pipeline.configuration.type}` + + pathLine + + repoLine + + `\nWeb URL: ${pipeline.links.web}` + + return { + success: true, + output: { + content, + metadata: { pipeline }, + }, + } + }, + + outputs: { + content: { type: 'string', description: 'Human-readable summary of the pipeline' }, + metadata: { + type: 'object', + description: 'Pipeline detail metadata', + properties: { + pipeline: { + type: 'object', + description: 'Full pipeline detail object', + properties: { + id: { type: 'number', description: 'Pipeline ID' }, + name: { type: 'string', description: 'Pipeline name' }, + folder: { type: 'string', description: 'Folder path' }, + revision: { type: 'number', description: 'Pipeline revision number' }, + url: { type: 'string', description: 'Pipeline API URL' }, + configuration: { + type: 'object', + description: 'Pipeline configuration', + properties: { + type: { type: 'string', description: 'Configuration type (e.g. "yaml")' }, + path: { type: 'string', description: 'YAML file path in the repository' }, + repository: { + type: 'object', + description: 'Source repository info', + properties: { + id: { type: 'string', description: 'Repository ID' }, + type: { + type: 'string', + description: 'Repository type (e.g. "azureReposGit")', + }, + }, + }, + }, + }, + links: { + type: 'object', + description: 'Hypermedia links', + properties: { + self: { type: 'string', description: 'API self-link' }, + web: { type: 'string', description: 'Browser URL for the pipeline' }, + }, + }, + }, + }, + }, + }, + }, +} + +interface AzureDevOpsPipelineDetailItem { + id: number + name: string + folder: string + revision: number + url: string + configuration: { + type: string + path?: string + repository?: { id: string; type: string } + } + links: { self: string; web: string } +} diff --git a/apps/sim/tools/azure_devops/get_pipeline_run.ts b/apps/sim/tools/azure_devops/get_pipeline_run.ts new file mode 100644 index 00000000000..e17959e3459 --- /dev/null +++ b/apps/sim/tools/azure_devops/get_pipeline_run.ts @@ -0,0 +1,157 @@ +import type { GetPipelineRunParams, GetPipelineRunResponse } from '@/tools/azure_devops/types' +import type { ToolConfig } from '@/tools/types' + +export const getPipelineRunTool: ToolConfig = { + id: 'azure_devops_get_pipeline_run', + name: 'Azure DevOps Get Pipeline Run', + description: + 'Get details for a specific pipeline run in an Azure DevOps project. Returns run state, result, timestamps, and the pipeline reference.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + pipelineId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'ID of the pipeline', + }, + runId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'ID of the run to retrieve', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Build: Read, Pipeline: Read)', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/pipelines/${params.pipelineId}/runs/${params.runId}` + ) + url.searchParams.set('api-version', '7.2-preview.1') + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + + const run: AzureDevOpsPipelineRunDetailItem = { + id: data.id, + name: data.name, + state: data.state, + result: data.result, + createdDate: data.createdDate, + finishedDate: data.finishedDate, + url: data.url, + webUrl: data._links?.web?.href ?? '', + pipeline: { + id: data.pipeline?.id, + name: data.pipeline?.name, + folder: data.pipeline?.folder ?? '\\', + revision: data.pipeline?.revision, + url: data.pipeline?.url ?? '', + }, + } + + const resultLine = run.result ? ` | Result: ${run.result}` : '' + const finishedLine = run.finishedDate ? ` | Finished: ${run.finishedDate}` : '' + + const content = + `Run: ${run.name} (ID: ${run.id})\n` + + `Pipeline: ${run.pipeline.name} (ID: ${run.pipeline.id})\n` + + `State: ${run.state}${resultLine}\n` + + `Created: ${run.createdDate}${finishedLine}\n` + + `Web URL: ${run.webUrl}` + + return { + success: true, + output: { + content, + metadata: { run }, + }, + } + }, + + outputs: { + content: { type: 'string', description: 'Human-readable summary of the pipeline run' }, + metadata: { + type: 'object', + description: 'Pipeline run metadata', + properties: { + run: { + type: 'object', + description: 'Full pipeline run detail object', + properties: { + id: { type: 'number', description: 'Run ID' }, + name: { type: 'string', description: 'Run name (e.g. "20210601.1")' }, + state: { type: 'string', description: 'Run state (e.g. "completed", "inProgress")' }, + result: { + type: 'string', + description: 'Run result (e.g. "succeeded", "failed") — absent if still running', + }, + createdDate: { type: 'string', description: 'ISO 8601 creation timestamp' }, + finishedDate: { + type: 'string', + description: 'ISO 8601 finish timestamp — absent if still running', + }, + url: { type: 'string', description: 'Run API URL' }, + webUrl: { type: 'string', description: 'Browser URL for the run' }, + pipeline: { + type: 'object', + description: 'Pipeline reference', + properties: { + id: { type: 'number', description: 'Pipeline ID' }, + name: { type: 'string', description: 'Pipeline name' }, + folder: { type: 'string', description: 'Pipeline folder' }, + revision: { type: 'number', description: 'Pipeline revision number' }, + url: { type: 'string', description: 'Pipeline API URL' }, + }, + }, + }, + }, + }, + }, + }, +} + +interface AzureDevOpsPipelineRunDetailItem { + id: number + name: string + state: string + result?: string + createdDate: string + finishedDate?: string + url: string + webUrl: string + pipeline: { + id: number + name: string + folder: string + revision: number + url: string + } +} diff --git a/apps/sim/tools/azure_devops/get_work_item.ts b/apps/sim/tools/azure_devops/get_work_item.ts new file mode 100644 index 00000000000..f1731cd444d --- /dev/null +++ b/apps/sim/tools/azure_devops/get_work_item.ts @@ -0,0 +1,103 @@ +import type { GetWorkItemParams, GetWorkItemResponse } from '@/tools/azure_devops/types' +import type { AzureDevOpsRawWorkItem } from '@/tools/azure_devops/utils' +import { formatWorkItem, mapWorkItem } from '@/tools/azure_devops/utils' +import type { ToolConfig } from '@/tools/types' + +export const getWorkItemTool: ToolConfig = { + id: 'azure_devops_get_work_item', + name: 'Azure DevOps Get Work Item', + description: + 'Fetch full details of a single work item by ID from Azure DevOps, including title, state, type, assignee, and area path.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + workItemId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'The work item ID to fetch', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Work Items: Read)', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/wit/workitems/${Number(params.workItemId)}` + ) + url.searchParams.set('$expand', 'all') + url.searchParams.set('api-version', '7.2-preview.3') + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const raw: AzureDevOpsRawWorkItem = await response.json() + const workItem = mapWorkItem(raw) + + return { + success: true, + output: { + content: formatWorkItem(workItem), + metadata: { workItem }, + }, + } + }, + + outputs: { + content: { + type: 'string', + description: 'Human-readable summary of the work item', + }, + metadata: { + type: 'object', + description: 'Work item metadata', + properties: { + workItem: { + type: 'object', + description: 'Full work item details', + properties: { + id: { type: 'number', description: 'Work item ID' }, + title: { type: 'string', description: 'Work item title' }, + state: { + type: 'string', + description: 'Current state for Basic process (e.g. To Do, Doing, Done)', + }, + workItemType: { + type: 'string', + description: 'Work item type returned by Azure DevOps (e.g. Issue, Task, Epic)', + }, + assignedTo: { + type: 'string', + description: 'Display name of assigned user, or null if unassigned', + }, + areaPath: { type: 'string', description: 'Area path of the work item' }, + url: { type: 'string', description: 'API URL for the work item' }, + }, + }, + }, + }, + }, +} diff --git a/apps/sim/tools/azure_devops/get_work_items_batch.ts b/apps/sim/tools/azure_devops/get_work_items_batch.ts new file mode 100644 index 00000000000..3b5200d2af3 --- /dev/null +++ b/apps/sim/tools/azure_devops/get_work_items_batch.ts @@ -0,0 +1,173 @@ +import type { + AzureDevOpsWorkItem, + GetWorkItemsBatchParams, + GetWorkItemsBatchResponse, +} from '@/tools/azure_devops/types' +import type { AzureDevOpsRawWorkItem } from '@/tools/azure_devops/utils' +import { formatWorkItem, mapWorkItem } from '@/tools/azure_devops/utils' +import type { ToolConfig } from '@/tools/types' + +export const getWorkItemsBatchTool: ToolConfig = + { + id: 'azure_devops_get_work_items_batch', + name: 'Azure DevOps Get Work Items Batch', + description: + 'Fetch full details for multiple work items by ID from Azure DevOps. Pass comma-separated IDs (e.g. "123,456,789"). Requests with more than 200 IDs are automatically split into chunks.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + ids: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: + 'Comma-separated work item IDs to fetch (e.g. "123,456,789"). Lists longer than 200 IDs are chunked automatically.', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Work Items: Read)', + }, + }, + + request: { + url: (params) => { + const allIds = params.ids + .split(',') + .map((id) => id.trim()) + .filter(Boolean) + if (allIds.length === 0) { + throw new Error('Get Work Items Batch requires at least one work item ID.') + } + const firstChunk = allIds.slice(0, 200) + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/wit/workitems` + ) + url.searchParams.set('ids', firstChunk.join(',')) + url.searchParams.set('$expand', 'all') + url.searchParams.set('api-version', '7.2-preview.3') + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response, params) => { + const firstData = await response.json() + const workItems: AzureDevOpsWorkItem[] = (firstData.value ?? []).map( + (raw: AzureDevOpsRawWorkItem) => mapWorkItem(raw) + ) + + const allIds = params!.ids + .split(',') + .map((id) => id.trim()) + .filter(Boolean) + + if (allIds.length > 200) { + const BATCH_SIZE = 200 + const organization = params!.organization.trim() + const project = params!.project.trim() + const authHeader = `Basic ${btoa(`:${params!.accessToken}`)}` + + for (let i = BATCH_SIZE; i < allIds.length; i += BATCH_SIZE) { + const chunk = allIds.slice(i, i + BATCH_SIZE) + const detailsUrl = new URL( + `https://dev.azure.com/${organization}/${project}/_apis/wit/workitems` + ) + detailsUrl.searchParams.set('ids', chunk.join(',')) + detailsUrl.searchParams.set('$expand', 'all') + detailsUrl.searchParams.set('api-version', '7.2-preview.3') + + const chunkResponse = await fetch(detailsUrl.toString(), { + method: 'GET', + headers: { 'Content-Type': 'application/json', Authorization: authHeader }, + }) + + if (!chunkResponse.ok) { + const errorBody = await chunkResponse.text().catch(() => '') + throw new Error( + `Failed to fetch work item batch chunk (${chunkResponse.status}): ${errorBody || chunkResponse.statusText}` + ) + } + + const chunkData = await chunkResponse.json() + for (const raw of chunkData.value ?? []) { + workItems.push(mapWorkItem(raw as AzureDevOpsRawWorkItem)) + } + } + } + + const content = + workItems.length === 0 + ? 'No work items found for the provided IDs.' + : `Found ${workItems.length} work item(s) (of ${allIds.length} requested):\n\n${workItems.map(formatWorkItem).join('\n\n')}` + + return { + success: true, + output: { + content, + metadata: { count: workItems.length, totalRequested: allIds.length, workItems }, + }, + } + }, + + outputs: { + content: { + type: 'string', + description: 'Human-readable summary of the fetched work items', + }, + metadata: { + type: 'object', + description: 'Work items metadata', + properties: { + count: { type: 'number', description: 'Number of work items returned' }, + totalRequested: { + type: 'number', + description: 'Total number of IDs requested (across all chunks)', + optional: true, + }, + workItems: { + type: 'array', + description: 'Array of work item details', + items: { + type: 'object', + properties: { + id: { type: 'number', description: 'Work item ID' }, + title: { type: 'string', description: 'Work item title' }, + state: { + type: 'string', + description: 'Current state for Basic process (e.g. To Do, Doing, Done)', + }, + workItemType: { + type: 'string', + description: 'Work item type returned by Azure DevOps (e.g. Issue, Task, Epic)', + }, + assignedTo: { + type: 'string', + description: 'Display name of assigned user, or null if unassigned', + }, + areaPath: { type: 'string', description: 'Area path of the work item' }, + url: { type: 'string', description: 'API URL for the work item' }, + }, + }, + }, + }, + }, + }, + } diff --git a/apps/sim/tools/azure_devops/get_work_items_between_builds.ts b/apps/sim/tools/azure_devops/get_work_items_between_builds.ts new file mode 100644 index 00000000000..17df94db64b --- /dev/null +++ b/apps/sim/tools/azure_devops/get_work_items_between_builds.ts @@ -0,0 +1,126 @@ +import type { + AzureDevOpsWorkItemRef, + GetWorkItemsBetweenBuildsParams, + GetWorkItemsBetweenBuildsResponse, +} from '@/tools/azure_devops/types' +import type { ToolConfig } from '@/tools/types' + +export const getWorkItemsBetweenBuildsTool: ToolConfig< + GetWorkItemsBetweenBuildsParams, + GetWorkItemsBetweenBuildsResponse +> = { + id: 'azure_devops_get_work_items_between_builds', + name: 'Azure DevOps Get Work Items Between Builds', + description: + 'Get work item references associated with commits between two builds in Azure DevOps. Returns work item IDs and URLs — use Get Work Items Batch for full field details.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + fromBuildId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'The older build ID (start of range)', + }, + toBuildId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'The newer build ID (end of range)', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Build: Read)', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/build/workitems` + ) + url.searchParams.set('fromBuildId', Number(params.fromBuildId).toString()) + url.searchParams.set('toBuildId', Number(params.toBuildId).toString()) + url.searchParams.set('api-version', '7.2-preview.2') + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + + const workItems: AzureDevOpsWorkItemRef[] = (data.value ?? []).map( + (w: AzureDevOpsRawWorkItemRef) => ({ + id: String(w.id), + url: w.url, + }) + ) + + const content = + workItems.length === 0 + ? 'No work items found between these builds.' + : `Found ${data.count ?? workItems.length} work item(s) between builds:\n\n${workItems + .map((w) => `- Work Item ID: ${w.id}\n URL: ${w.url}`) + .join('\n')}` + + return { + success: true, + output: { + content, + metadata: { + count: data.count ?? workItems.length, + workItems, + }, + }, + } + }, + + outputs: { + content: { + type: 'string', + description: 'Human-readable summary of work items between builds', + }, + metadata: { + type: 'object', + description: 'Work items metadata', + properties: { + count: { type: 'number', description: 'Total number of work item references returned' }, + workItems: { + type: 'array', + description: 'Array of work item references', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'Work item ID' }, + url: { type: 'string', description: 'API URL for the work item' }, + }, + }, + }, + }, + }, + }, +} + +interface AzureDevOpsRawWorkItemRef { + id: string | number + url: string +} diff --git a/apps/sim/tools/azure_devops/index.ts b/apps/sim/tools/azure_devops/index.ts new file mode 100644 index 00000000000..d3866848403 --- /dev/null +++ b/apps/sim/tools/azure_devops/index.ts @@ -0,0 +1,37 @@ +import { addCommentTool } from '@/tools/azure_devops/add_comment' +import { createWorkItemTool } from '@/tools/azure_devops/create_work_item' +import { getBuildLogTool } from '@/tools/azure_devops/get_build_log' +import { getBuildTimelineTool } from '@/tools/azure_devops/get_build_timeline' +import { getCommentsTool } from '@/tools/azure_devops/get_comments' +import { getPipelineTool } from '@/tools/azure_devops/get_pipeline' +import { getPipelineRunTool } from '@/tools/azure_devops/get_pipeline_run' +import { getWorkItemTool } from '@/tools/azure_devops/get_work_item' +import { getWorkItemsBatchTool } from '@/tools/azure_devops/get_work_items_batch' +import { getWorkItemsBetweenBuildsTool } from '@/tools/azure_devops/get_work_items_between_builds' +import { listBuildLogsTool } from '@/tools/azure_devops/list_build_logs' +import { listBuildsTool } from '@/tools/azure_devops/list_builds' +import { listPipelineRunsTool } from '@/tools/azure_devops/list_pipeline_runs' +import { listPipelinesTool } from '@/tools/azure_devops/list_pipelines' +import { queryWorkItemsTool } from '@/tools/azure_devops/query_work_items' +import { updateWorkItemTool } from '@/tools/azure_devops/update_work_item' + +export * from '@/tools/azure_devops/types' + +export { + listPipelinesTool, + getPipelineTool, + listPipelineRunsTool, + getPipelineRunTool, + listBuildsTool, + listBuildLogsTool, + getBuildLogTool, + getBuildTimelineTool, + getWorkItemsBetweenBuildsTool, + queryWorkItemsTool, + getWorkItemTool, + getWorkItemsBatchTool, + createWorkItemTool, + updateWorkItemTool, + addCommentTool, + getCommentsTool, +} diff --git a/apps/sim/tools/azure_devops/list_build_logs.ts b/apps/sim/tools/azure_devops/list_build_logs.ts new file mode 100644 index 00000000000..1f8183d02c1 --- /dev/null +++ b/apps/sim/tools/azure_devops/list_build_logs.ts @@ -0,0 +1,134 @@ +import type { ListBuildLogsParams, ListBuildLogsResponse } from '@/tools/azure_devops/types' +import type { ToolConfig } from '@/tools/types' + +export const listBuildLogsTool: ToolConfig = { + id: 'azure_devops_list_build_logs', + name: 'Azure DevOps List Build Logs', + description: + 'List all log entries for a specific build in Azure DevOps. Returns log IDs, types, and line counts — use the log ID with the Get Build Log tool to fetch actual log text.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + buildId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'The build ID whose logs to list', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Build: Read)', + }, + }, + + request: { + url: (params) => + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/build/builds/${params.buildId}/logs?api-version=7.2-preview.2`, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + + const logs: AzureDevOpsBuildLogItem[] = (data.value ?? []).map((l: AzureDevOpsRawBuildLog) => ({ + id: l.id, + type: l.type, + url: l.url, + lineCount: l.lineCount, + createdOn: l.createdOn, + lastChangedOn: l.lastChangedOn, + })) + + const content = + logs.length === 0 + ? 'No logs found.' + : `Found ${data.count ?? logs.length} log(s):\n\n${logs + .map( + (l) => + `- Log ID: ${l.id}\n` + + ` Type: ${l.type}\n` + + ` Lines: ${l.lineCount}` + + (l.lastChangedOn ? `\n Last changed: ${l.lastChangedOn}` : '') + ) + .join('\n')}` + + return { + success: true, + output: { + content, + metadata: { + count: data.count ?? logs.length, + logs, + }, + }, + } + }, + + outputs: { + content: { type: 'string', description: 'Human-readable summary of build logs' }, + metadata: { + type: 'object', + description: 'Build logs metadata', + properties: { + count: { type: 'number', description: 'Total number of log entries returned' }, + logs: { + type: 'array', + description: 'Array of log entry objects', + items: { + type: 'object', + properties: { + id: { + type: 'number', + description: 'Log entry ID — use with Get Build Log to fetch content', + }, + type: { + type: 'string', + description: 'Log type (e.g. "Container", "Task", "Section")', + }, + url: { type: 'string', description: 'API URL for the log entry' }, + lineCount: { type: 'number', description: 'Number of lines in the log' }, + createdOn: { type: 'string', description: 'ISO 8601 creation timestamp' }, + lastChangedOn: { type: 'string', description: 'ISO 8601 last-changed timestamp' }, + }, + }, + }, + }, + }, + }, +} + +interface AzureDevOpsBuildLogItem { + id: number + type: string + url: string + lineCount: number + createdOn?: string + lastChangedOn?: string +} + +interface AzureDevOpsRawBuildLog { + id: number + type: string + url: string + lineCount: number + createdOn?: string + lastChangedOn?: string +} diff --git a/apps/sim/tools/azure_devops/list_builds.ts b/apps/sim/tools/azure_devops/list_builds.ts new file mode 100644 index 00000000000..dfdc087ed21 --- /dev/null +++ b/apps/sim/tools/azure_devops/list_builds.ts @@ -0,0 +1,203 @@ +import type { ListBuildsParams, ListBuildsResponse } from '@/tools/azure_devops/types' +import type { ToolConfig } from '@/tools/types' + +export const listBuildsTool: ToolConfig = { + id: 'azure_devops_list_builds', + name: 'Azure DevOps List Builds', + description: + 'List builds in an Azure DevOps project. Optionally filter by pipeline definition, status, result, or branch.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + definitionIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated pipeline definition IDs to filter by (e.g. "1,2,3")', + }, + top: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of builds to return', + }, + statusFilter: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Filter by build status: inProgress, completed, cancelling, postponed, notStarted, none', + }, + resultFilter: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Filter by build result: succeeded, partiallySucceeded, failed, canceled', + }, + branchName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Filter by source branch name (e.g. "refs/heads/main")', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Build: Read)', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/build/builds` + ) + url.searchParams.set('api-version', '7.2-preview.8') + if (params.definitionIds) url.searchParams.set('definitions', params.definitionIds) + if (params.top) url.searchParams.set('$top', Number(params.top).toString()) + if (params.statusFilter) url.searchParams.set('statusFilter', params.statusFilter) + if (params.resultFilter) url.searchParams.set('resultFilter', params.resultFilter) + if (params.branchName) url.searchParams.set('branchName', params.branchName) + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + + const builds: AzureDevOpsBuildItem[] = (data.value ?? []).map((b: AzureDevOpsRawBuild) => ({ + id: b.id, + buildNumber: b.buildNumber, + status: b.status, + result: b.result, + queueTime: b.queueTime, + startTime: b.startTime, + finishTime: b.finishTime, + sourceBranch: b.sourceBranch, + sourceVersion: b.sourceVersion, + definition: { id: b.definition?.id ?? 0, name: b.definition?.name ?? '' }, + webUrl: b._links?.web?.href ?? '', + })) + + const content = + builds.length === 0 + ? 'No builds found.' + : `Found ${data.count ?? builds.length} build(s):\n\n${builds + .map( + (b) => + `- Build ${b.buildNumber} (ID: ${b.id})\n` + + ` Pipeline: ${b.definition.name}\n` + + ` Status: ${b.status}${b.result ? ` | Result: ${b.result}` : ''}\n` + + ` Branch: ${b.sourceBranch}\n` + + ` Queued: ${b.queueTime}${b.finishTime ? ` | Finished: ${b.finishTime}` : ''}` + ) + .join('\n')}` + + return { + success: true, + output: { + content, + metadata: { + count: data.count ?? builds.length, + builds, + }, + }, + } + }, + + outputs: { + content: { type: 'string', description: 'Human-readable summary of builds' }, + metadata: { + type: 'object', + description: 'Builds metadata', + properties: { + count: { type: 'number', description: 'Total number of builds returned' }, + builds: { + type: 'array', + description: 'Array of build objects', + items: { + type: 'object', + properties: { + id: { type: 'number', description: 'Build ID' }, + buildNumber: { type: 'string', description: 'Build number (e.g. "20210601.1")' }, + status: { + type: 'string', + description: 'Build status (e.g. "completed", "inProgress")', + }, + result: { + type: 'string', + description: 'Build result (e.g. "succeeded", "failed") — absent if still running', + }, + queueTime: { type: 'string', description: 'ISO 8601 queue timestamp' }, + startTime: { type: 'string', description: 'ISO 8601 start timestamp' }, + finishTime: { + type: 'string', + description: 'ISO 8601 finish timestamp — absent if still running', + }, + sourceBranch: { + type: 'string', + description: 'Source branch (e.g. "refs/heads/main")', + }, + sourceVersion: { type: 'string', description: 'Source commit SHA' }, + definition: { + type: 'object', + description: 'Pipeline definition reference', + properties: { + id: { type: 'number', description: 'Definition ID' }, + name: { type: 'string', description: 'Definition name' }, + }, + }, + webUrl: { type: 'string', description: 'Browser URL for the build' }, + }, + }, + }, + }, + }, + }, +} + +interface AzureDevOpsBuildItem { + id: number + buildNumber: string + status: string + result?: string + queueTime: string + startTime?: string + finishTime?: string + sourceBranch: string + sourceVersion: string + definition: { id: number; name: string } + webUrl: string +} + +interface AzureDevOpsRawBuild { + id: number + buildNumber: string + status: string + result?: string + queueTime: string + startTime?: string + finishTime?: string + sourceBranch: string + sourceVersion: string + definition?: { id: number; name?: string } + _links?: { web?: { href: string } } +} diff --git a/apps/sim/tools/azure_devops/list_pipeline_runs.ts b/apps/sim/tools/azure_devops/list_pipeline_runs.ts new file mode 100644 index 00000000000..ce84c5eb822 --- /dev/null +++ b/apps/sim/tools/azure_devops/list_pipeline_runs.ts @@ -0,0 +1,149 @@ +import type { ListPipelineRunsParams, ListPipelineRunsResponse } from '@/tools/azure_devops/types' +import type { ToolConfig } from '@/tools/types' + +export const listPipelineRunsTool: ToolConfig = { + id: 'azure_devops_list_pipeline_runs', + name: 'Azure DevOps List Pipeline Runs', + description: + 'List runs for a specific pipeline in an Azure DevOps project. Returns run ID, name, state, result, and timestamps.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + pipelineId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'ID of the pipeline whose runs to list', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Build: Read, Pipeline: Read)', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/pipelines/${params.pipelineId}/runs` + ) + url.searchParams.set('api-version', '7.2-preview.1') + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + + const runs: AzureDevOpsPipelineRunItem[] = (data.value ?? []).map((r: AzureDevOpsRawRun) => ({ + id: r.id, + name: r.name, + state: r.state, + result: r.result, + createdDate: r.createdDate, + finishedDate: r.finishedDate, + url: r.url, + webUrl: r._links?.web?.href ?? '', + })) + + const content = + runs.length === 0 + ? 'No pipeline runs found.' + : `Found ${data.count ?? runs.length} run(s):\n\n${runs + .map( + (r) => + `- Run ${r.name} (ID: ${r.id})\n` + + ` State: ${r.state}${r.result ? ` | Result: ${r.result}` : ''}\n` + + ` Created: ${r.createdDate}${r.finishedDate ? ` | Finished: ${r.finishedDate}` : ''}` + ) + .join('\n')}` + + return { + success: true, + output: { + content, + metadata: { + count: data.count ?? runs.length, + runs, + }, + }, + } + }, + + outputs: { + content: { type: 'string', description: 'Human-readable summary of pipeline runs' }, + metadata: { + type: 'object', + description: 'Pipeline runs metadata', + properties: { + count: { type: 'number', description: 'Total number of runs returned' }, + runs: { + type: 'array', + description: 'Array of pipeline run objects', + items: { + type: 'object', + properties: { + id: { type: 'number', description: 'Run ID' }, + name: { type: 'string', description: 'Run name (e.g. "20210601.1")' }, + state: { + type: 'string', + description: 'Run state (e.g. "completed", "inProgress")', + }, + result: { + type: 'string', + description: 'Run result (e.g. "succeeded", "failed") — absent if still running', + }, + createdDate: { type: 'string', description: 'ISO 8601 creation timestamp' }, + finishedDate: { + type: 'string', + description: 'ISO 8601 finish timestamp — absent if still running', + }, + url: { type: 'string', description: 'Run API URL' }, + webUrl: { type: 'string', description: 'Browser URL for the run' }, + }, + }, + }, + }, + }, + }, +} + +interface AzureDevOpsPipelineRunItem { + id: number + name: string + state: string + result?: string + createdDate: string + finishedDate?: string + url: string + webUrl: string +} + +interface AzureDevOpsRawRun { + id: number + name: string + state: string + result?: string + createdDate: string + finishedDate?: string + url: string + _links?: { web?: { href: string } } +} diff --git a/apps/sim/tools/azure_devops/list_pipelines.ts b/apps/sim/tools/azure_devops/list_pipelines.ts new file mode 100644 index 00000000000..913aebfda9f --- /dev/null +++ b/apps/sim/tools/azure_devops/list_pipelines.ts @@ -0,0 +1,133 @@ +import type { ListPipelinesParams, ListPipelinesResponse } from '@/tools/azure_devops/types' +import type { ToolConfig } from '@/tools/types' + +export const listPipelinesTool: ToolConfig = { + id: 'azure_devops_list_pipelines', + name: 'Azure DevOps List Pipelines', + description: + 'List all pipelines in an Azure DevOps project. Returns pipeline ID, name, folder, revision, and URL.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + orderBy: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Field to sort results by (e.g. "name")', + }, + top: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of pipelines to return', + }, + continuationToken: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Continuation token for paginating results', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Build: Read, Pipeline: Read)', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/pipelines` + ) + url.searchParams.set('api-version', '7.2-preview.1') + if (params.orderBy) url.searchParams.set('orderBy', params.orderBy) + if (params.top) url.searchParams.set('$top', Number(params.top).toString()) + if (params.continuationToken) + url.searchParams.set('continuationToken', params.continuationToken) + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + + const pipelines: AzureDevOpsPipelineItem[] = (data.value ?? []).map( + (p: AzureDevOpsPipelineItem) => ({ + id: p.id, + name: p.name, + folder: p.folder ?? '\\', + revision: p.revision, + url: p.url, + }) + ) + + const content = + pipelines.length === 0 + ? 'No pipelines found.' + : `Found ${data.count ?? pipelines.length} pipeline(s):\n\n${pipelines + .map((p) => `- ${p.name} (ID: ${p.id})\n Folder: ${p.folder}\n URL: ${p.url}`) + .join('\n')}` + + return { + success: true, + output: { + content, + metadata: { + count: data.count ?? pipelines.length, + pipelines, + }, + }, + } + }, + + outputs: { + content: { type: 'string', description: 'Human-readable summary of pipelines' }, + metadata: { + type: 'object', + description: 'Pipelines metadata', + properties: { + count: { type: 'number', description: 'Total number of pipelines returned' }, + pipelines: { + type: 'array', + description: 'Array of pipeline objects', + items: { + type: 'object', + properties: { + id: { type: 'number', description: 'Pipeline ID' }, + name: { type: 'string', description: 'Pipeline name' }, + folder: { type: 'string', description: 'Folder path (e.g. "\\\\")' }, + revision: { type: 'number', description: 'Pipeline revision number' }, + url: { type: 'string', description: 'Pipeline API URL' }, + }, + }, + }, + }, + }, + }, +} + +interface AzureDevOpsPipelineItem { + id: number + name: string + folder: string + revision: number + url: string +} diff --git a/apps/sim/tools/azure_devops/query_work_items.ts b/apps/sim/tools/azure_devops/query_work_items.ts new file mode 100644 index 00000000000..f57c6c901da --- /dev/null +++ b/apps/sim/tools/azure_devops/query_work_items.ts @@ -0,0 +1,164 @@ +import type { + AzureDevOpsWorkItem, + QueryWorkItemsParams, + QueryWorkItemsResponse, +} from '@/tools/azure_devops/types' +import type { AzureDevOpsRawWorkItem } from '@/tools/azure_devops/utils' +import { formatWorkItem, mapWorkItem } from '@/tools/azure_devops/utils' +import type { ToolConfig } from '@/tools/types' + +export const queryWorkItemsTool: ToolConfig = { + id: 'azure_devops_query_work_items', + name: 'Azure DevOps Query Work Items', + description: + 'Execute a WIQL query to search for work items in Azure DevOps and return full field details. Use TOP N in your query to limit results (Azure enforces a 200-item maximum per batch fetch).', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + wiqlQuery: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: + 'WIQL query string (e.g. "SELECT [System.Id] FROM workitems WHERE [System.State] = \'Doing\' ORDER BY [System.Id] ASC"). Use TOP N to limit results.', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Work Items: Read)', + }, + }, + + request: { + url: (params) => + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/wit/wiql?api-version=7.2-preview.2`, + method: 'POST', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + body: (params) => ({ query: params.wiqlQuery }), + }, + + transformResponse: async (response, params) => { + const wiqlData = await response.json() + const workItemRefs: Array<{ id: number; url: string }> = wiqlData.workItems ?? [] + + if (workItemRefs.length === 0) { + return { + success: true, + output: { + content: 'No work items matched the query.', + metadata: { count: 0, workItems: [] }, + }, + } + } + + const allIds = workItemRefs.map((wi) => wi.id) + const BATCH_SIZE = 200 + const organization = params!.organization.trim() + const project = params!.project.trim() + const authHeader = `Basic ${btoa(`:${params!.accessToken}`)}` + + const workItems: AzureDevOpsWorkItem[] = [] + for (let i = 0; i < allIds.length; i += BATCH_SIZE) { + const chunk = allIds.slice(i, i + BATCH_SIZE) + const detailsUrl = new URL( + `https://dev.azure.com/${organization}/${project}/_apis/wit/workitems` + ) + detailsUrl.searchParams.set('ids', chunk.join(',')) + detailsUrl.searchParams.set('$expand', 'all') + detailsUrl.searchParams.set('api-version', '7.2-preview.3') + + const detailsResponse = await fetch(detailsUrl.toString(), { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: authHeader, + }, + }) + + if (!detailsResponse.ok) { + const errorBody = await detailsResponse.text().catch(() => '') + throw new Error( + `Failed to hydrate work item details (${detailsResponse.status}): ${errorBody || detailsResponse.statusText}` + ) + } + + const detailsData = await detailsResponse.json() + for (const raw of detailsData.value ?? []) { + workItems.push(mapWorkItem(raw as AzureDevOpsRawWorkItem)) + } + } + + const content = + workItems.length === 0 + ? 'No work item details found.' + : `Found ${workItems.length} work item(s) (of ${allIds.length} matched):\n\n${workItems.map(formatWorkItem).join('\n\n')}` + + return { + success: true, + output: { + content, + metadata: { count: workItems.length, totalMatched: allIds.length, workItems }, + }, + } + }, + + outputs: { + content: { + type: 'string', + description: 'Human-readable summary of matching work items', + }, + metadata: { + type: 'object', + description: 'Work items metadata', + properties: { + count: { type: 'number', description: 'Number of work items returned (after hydration)' }, + totalMatched: { + type: 'number', + description: 'Total number of work items matched by the WIQL query before hydration', + optional: true, + }, + workItems: { + type: 'array', + description: 'Array of work item details', + items: { + type: 'object', + properties: { + id: { type: 'number', description: 'Work item ID' }, + title: { type: 'string', description: 'Work item title' }, + state: { + type: 'string', + description: 'Current state for Basic process (e.g. To Do, Doing, Done)', + }, + workItemType: { + type: 'string', + description: 'Work item type returned by Azure DevOps (e.g. Issue, Task, Epic)', + }, + assignedTo: { + type: 'string', + description: 'Display name of assigned user, or null if unassigned', + }, + areaPath: { type: 'string', description: 'Area path of the work item' }, + url: { type: 'string', description: 'API URL for the work item' }, + }, + }, + }, + }, + }, + }, +} diff --git a/apps/sim/tools/azure_devops/types.ts b/apps/sim/tools/azure_devops/types.ts new file mode 100644 index 00000000000..048409985ff --- /dev/null +++ b/apps/sim/tools/azure_devops/types.ts @@ -0,0 +1,458 @@ +import type { ToolResponse } from '@/tools/types' + +export interface AzureDevOpsBaseParams { + /** Azure DevOps organization name */ + organization: string + /** Azure DevOps project name */ + project: string + /** Personal Access Token */ + accessToken: string +} + +// ── List Pipelines ────────────────────────────────────────────────────────── + +export interface ListPipelinesParams extends AzureDevOpsBaseParams { + orderBy?: string + top?: number + continuationToken?: string +} + +export interface AzureDevOpsPipeline { + id: number + name: string + folder: string + revision: number + url: string +} + +export interface ListPipelinesResponse extends ToolResponse { + output: { + content: string + metadata: { + count: number + pipelines: AzureDevOpsPipeline[] + } + } +} + +// ── Get Pipeline ──────────────────────────────────────────────────────────── + +export interface GetPipelineParams extends AzureDevOpsBaseParams { + pipelineId: number + pipelineVersion?: number +} + +export interface AzureDevOpsPipelineConfiguration { + type: string + path?: string + repository?: { + id: string + type: string + } +} + +export interface AzureDevOpsPipelineDetail extends AzureDevOpsPipeline { + configuration: AzureDevOpsPipelineConfiguration + links: { + self: string + web: string + } +} + +export interface GetPipelineResponse extends ToolResponse { + output: { + content: string + metadata: { + pipeline: AzureDevOpsPipelineDetail + } + } +} + +// ── List Pipeline Runs ────────────────────────────────────────────────────── + +export interface ListPipelineRunsParams extends AzureDevOpsBaseParams { + pipelineId: number +} + +export interface AzureDevOpsPipelineRun { + id: number + name: string + state: string + result?: string + createdDate: string + finishedDate?: string + url: string + webUrl: string +} + +export interface ListPipelineRunsResponse extends ToolResponse { + output: { + content: string + metadata: { + count: number + runs: AzureDevOpsPipelineRun[] + } + } +} + +// ── Get Pipeline Run ──────────────────────────────────────────────────────── + +export interface GetPipelineRunParams extends AzureDevOpsBaseParams { + pipelineId: number + runId: number +} + +export interface AzureDevOpsPipelineRunDetail extends AzureDevOpsPipelineRun { + pipeline: { + id: number + name: string + folder: string + revision: number + url: string + } +} + +export interface GetPipelineRunResponse extends ToolResponse { + output: { + content: string + metadata: { + run: AzureDevOpsPipelineRunDetail + } + } +} + +// ── List Builds ───────────────────────────────────────────────────────────── + +export interface ListBuildsParams extends AzureDevOpsBaseParams { + definitionIds?: string + top?: number + statusFilter?: string + resultFilter?: string + branchName?: string +} + +export interface AzureDevOpsBuild { + id: number + buildNumber: string + status: string + result?: string + queueTime: string + startTime?: string + finishTime?: string + sourceBranch: string + sourceVersion: string + definition: { + id: number + name: string + } + webUrl: string +} + +export interface ListBuildsResponse extends ToolResponse { + output: { + content: string + metadata: { + count: number + builds: AzureDevOpsBuild[] + } + } +} + +// ── List Build Logs ───────────────────────────────────────────────────────── + +export interface ListBuildLogsParams extends AzureDevOpsBaseParams { + buildId: number +} + +export interface AzureDevOpsBuildLog { + id: number + type: string + url: string + lineCount: number + createdOn?: string + lastChangedOn?: string +} + +export interface ListBuildLogsResponse extends ToolResponse { + output: { + content: string + metadata: { + count: number + logs: AzureDevOpsBuildLog[] + } + } +} + +// ── Get Build Log ──────────────────────────────────────────────────────────── + +export interface GetBuildLogParams extends AzureDevOpsBaseParams { + buildId: number + logId: number + startLine?: number + endLine?: number +} + +export interface GetBuildLogResponse extends ToolResponse { + output: { + content: string + metadata: { + lineCount: number + } + } +} + +// ── Get Build Timeline ──────────────────────────────────────────────────────── + +export interface GetBuildTimelineParams extends AzureDevOpsBaseParams { + buildId: number +} + +export interface AzureDevOpsBuildTimelineRecord { + id: string + name: string + type: string + result: string | null + logId: number | null + errorCount: number + warningCount: number + startTime: string + finishTime: string +} + +export interface GetBuildTimelineResponse extends ToolResponse { + output: { + content: string + metadata: { + totalCount: number + failedCount: number + records: AzureDevOpsBuildTimelineRecord[] + failedRecords: AzureDevOpsBuildTimelineRecord[] + } + } +} + +// ── Get Work Items Between Builds ──────────────────────────────────────────── + +export interface GetWorkItemsBetweenBuildsParams extends AzureDevOpsBaseParams { + fromBuildId: number + toBuildId: number +} + +export interface AzureDevOpsWorkItemRef { + id: string + url: string +} + +export interface GetWorkItemsBetweenBuildsResponse extends ToolResponse { + output: { + content: string + metadata: { + count: number + workItems: AzureDevOpsWorkItemRef[] + } + } +} + +// ── Query Work Items ───────────────────────────────────────────────────────── + +export interface QueryWorkItemsParams extends AzureDevOpsBaseParams { + wiqlQuery: string +} + +export interface AzureDevOpsWorkItem { + id: number + title: string + state: string + workItemType: string + assignedTo: string | null + areaPath: string + url: string +} + +export interface QueryWorkItemsResponse extends ToolResponse { + output: { + content: string + metadata: { + count: number + totalMatched?: number + workItems: AzureDevOpsWorkItem[] + } + } +} + +// ── Get Work Item ───────────────────────────────────────────────────────────── + +export interface GetWorkItemParams extends AzureDevOpsBaseParams { + workItemId: number +} + +export interface GetWorkItemResponse extends ToolResponse { + output: { + content: string + metadata: { + workItem: AzureDevOpsWorkItem + } + } +} + +// ── Get Work Items Batch ─────────────────────────────────────────────────────── + +export interface GetWorkItemsBatchParams extends AzureDevOpsBaseParams { + ids: string +} + +export interface GetWorkItemsBatchResponse extends ToolResponse { + output: { + content: string + metadata: { + count: number + totalRequested?: number + workItems: AzureDevOpsWorkItem[] + } + } +} + +// ── Create Work Item ─────────────────────────────────────────────────────────── + +export type AzureDevOpsBasicWorkItemType = 'Issue' | 'Task' | 'Epic' + +export interface CreateWorkItemParams extends AzureDevOpsBaseParams { + workItemType: AzureDevOpsBasicWorkItemType + title: string + description?: string + assignedTo?: string + priority?: number + /** Microsoft.VSTS.Scheduling.Effort — Issue only in the Basic process. */ + effort?: number + /** Microsoft.VSTS.Scheduling.StartDate — Epic only in the Basic process. ISO 8601. */ + startDate?: string + /** Microsoft.VSTS.Scheduling.TargetDate — Epic only in the Basic process. ISO 8601. */ + targetDate?: string + /** Microsoft.VSTS.Common.Activity — Task only in the Basic process. */ + activity?: string + /** Microsoft.VSTS.Scheduling.RemainingWork — Task only in the Basic process. */ + remainingWork?: number + /** Microsoft.VSTS.Scheduling.CompletedWork — Task only in the Basic process. */ + completedWork?: number + areaPath?: string + iterationPath?: string + tags?: string +} + +export interface CreateWorkItemResponse extends ToolResponse { + output: { + content: string + metadata: { + workItem: AzureDevOpsWorkItem + } + } +} + +// ── Update Work Item ─────────────────────────────────────────────────────────── + +export interface UpdateWorkItemParams extends AzureDevOpsBaseParams { + workItemId: number + title?: string + description?: string + assignedTo?: string + priority?: number + /** Microsoft.VSTS.Scheduling.Effort — Issue only in the Basic process. */ + effort?: number + /** Microsoft.VSTS.Scheduling.StartDate — Epic only in the Basic process. ISO 8601. */ + startDate?: string + /** Microsoft.VSTS.Scheduling.TargetDate — Epic only in the Basic process. ISO 8601. */ + targetDate?: string + /** Microsoft.VSTS.Common.Activity — Task only in the Basic process. */ + activity?: string + /** Microsoft.VSTS.Scheduling.RemainingWork — Task only in the Basic process. */ + remainingWork?: number + /** Microsoft.VSTS.Scheduling.CompletedWork — Task only in the Basic process. */ + completedWork?: number + areaPath?: string + state?: string + tags?: string +} + +export interface UpdateWorkItemResponse extends ToolResponse { + output: { + content: string + metadata: { + workItem: AzureDevOpsWorkItem + } + } +} + +// ── Add Comment ──────────────────────────────────────────────────────────────── + +export interface AddCommentParams extends AzureDevOpsBaseParams { + workItemId: number + text: string +} + +export interface AzureDevOpsComment { + workItemId: number + commentId: number + version: number + text: string + renderedText?: string + createdBy: string | null + createdDate: string + modifiedBy: string | null + modifiedDate: string + isDeleted: boolean + url: string +} + +export interface AddCommentResponse extends ToolResponse { + output: { + content: string + metadata: { + comment: AzureDevOpsComment + } + } +} + +// ── Response Union ──────────────────────────────────────────────────────────── + +export type AzureDevOpsResponse = + | ListPipelinesResponse + | GetPipelineResponse + | ListPipelineRunsResponse + | GetPipelineRunResponse + | ListBuildsResponse + | ListBuildLogsResponse + | GetBuildLogResponse + | GetBuildTimelineResponse + | GetWorkItemsBetweenBuildsResponse + | QueryWorkItemsResponse + | GetWorkItemResponse + | GetWorkItemsBatchResponse + | CreateWorkItemResponse + | UpdateWorkItemResponse + | AddCommentResponse + | GetCommentsResponse + +// ── Get Comments ────────────────────────────────────────────────────────────── + +export interface GetCommentsParams extends AzureDevOpsBaseParams { + workItemId: number + top?: number + continuationToken?: string + includeDeleted?: boolean + expand?: string + order?: string +} + +export interface GetCommentsResponse extends ToolResponse { + output: { + content: string + metadata: { + count: number + totalCount: number + comments: AzureDevOpsComment[] + continuationToken?: string + nextPage?: string + url?: string + } + } +} diff --git a/apps/sim/tools/azure_devops/update_work_item.ts b/apps/sim/tools/azure_devops/update_work_item.ts new file mode 100644 index 00000000000..e5e83c70a26 --- /dev/null +++ b/apps/sim/tools/azure_devops/update_work_item.ts @@ -0,0 +1,268 @@ +import type { + AzureDevOpsWorkItem, + UpdateWorkItemParams, + UpdateWorkItemResponse, +} from '@/tools/azure_devops/types' +import type { AzureDevOpsJsonPatchOp, AzureDevOpsRawWorkItem } from '@/tools/azure_devops/utils' +import { + appendEffortPatchOp, + appendFieldPatchOp, + formatWorkItem, + mapWorkItem, +} from '@/tools/azure_devops/utils' +import type { ToolConfig } from '@/tools/types' + +export const updateWorkItemTool: ToolConfig = { + id: 'azure_devops_update_work_item', + name: 'Azure DevOps Update Work Item', + description: + 'Update one or more fields on an existing work item in Azure DevOps. Provide only the fields you want to change.', + version: '1.0.0', + + params: { + organization: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps organization name', + }, + project: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Azure DevOps project name', + }, + workItemId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'ID of the work item to update', + }, + title: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'New title for the work item (optional)', + }, + description: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'New HTML description for the work item (optional)', + }, + assignedTo: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Email or display name to reassign the work item to (optional)', + }, + areaPath: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'New area path for the work item (optional)', + }, + priority: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: + 'Priority of the work item (1 = Critical, 2 = High, 3 = Medium, 4 = Low) (optional)', + }, + state: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'New state for Basic-process work items: "To Do", "Doing", or "Done" (optional)', + }, + effort: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Effort (Microsoft.VSTS.Scheduling.Effort). Basic process: Issue only.', + }, + startDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Start date (Microsoft.VSTS.Scheduling.StartDate), ISO 8601. Basic process: Epic only.', + }, + targetDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Target date (Microsoft.VSTS.Scheduling.TargetDate), ISO 8601. Basic process: Epic only.', + }, + activity: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Activity (Microsoft.VSTS.Common.Activity). One of Deployment, Design, Development, Documentation, Requirements, Testing. Basic process: Task only.', + }, + remainingWork: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: + 'Remaining work hours (Microsoft.VSTS.Scheduling.RemainingWork). Basic process: Task only.', + }, + completedWork: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: + 'Completed work hours (Microsoft.VSTS.Scheduling.CompletedWork). Basic process: Task only.', + }, + tags: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Semicolon-separated tags to set on the work item (optional)', + }, + accessToken: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Azure DevOps Personal Access Token (scopes: Work Items: Read & Write)', + }, + }, + + request: { + url: (params) => + `https://dev.azure.com/${params.organization.trim()}/${params.project.trim()}/_apis/wit/workitems/${Number(params.workItemId)}?api-version=7.2-preview.3`, + method: 'PATCH', + headers: (params) => ({ + 'Content-Type': 'application/json-patch+json', + Authorization: `Basic ${btoa(`:${params.accessToken}`)}`, + }), + body: (params) => { + const ops: AzureDevOpsJsonPatchOp[] = [] + if ( + !params.title && + !params.description && + !params.assignedTo && + !params.areaPath && + params.priority === undefined && + !params.state && + params.effort === undefined && + !params.startDate && + !params.targetDate && + !params.activity && + params.remainingWork === undefined && + params.completedWork === undefined && + !params.tags + ) { + throw new Error('Update Work Item requires at least one field to update.') + } + if (params.title) { + ops.push({ op: 'replace', path: '/fields/System.Title', value: params.title }) + } + if (params.description) { + ops.push({ op: 'replace', path: '/fields/System.Description', value: params.description }) + } + if (params.assignedTo) { + ops.push({ op: 'replace', path: '/fields/System.AssignedTo', value: params.assignedTo }) + } + if (params.areaPath) { + ops.push({ op: 'replace', path: '/fields/System.AreaPath', value: params.areaPath }) + } + if (params.priority !== undefined) { + ops.push({ + op: 'replace', + path: '/fields/Microsoft.VSTS.Common.Priority', + value: String(Number(params.priority)), + }) + } + if (params.state) { + ops.push({ op: 'replace', path: '/fields/System.State', value: params.state }) + } + appendEffortPatchOp(ops, params.effort, 'replace') + appendFieldPatchOp( + ops, + 'Microsoft.VSTS.Scheduling.StartDate', + params.startDate, + 'replace', + 'string' + ) + appendFieldPatchOp( + ops, + 'Microsoft.VSTS.Scheduling.TargetDate', + params.targetDate, + 'replace', + 'string' + ) + appendFieldPatchOp( + ops, + 'Microsoft.VSTS.Common.Activity', + params.activity, + 'replace', + 'string' + ) + appendFieldPatchOp( + ops, + 'Microsoft.VSTS.Scheduling.RemainingWork', + params.remainingWork, + 'replace', + 'number' + ) + appendFieldPatchOp( + ops, + 'Microsoft.VSTS.Scheduling.CompletedWork', + params.completedWork, + 'replace', + 'number' + ) + if (params.tags) { + ops.push({ op: 'replace', path: '/fields/System.Tags', value: params.tags }) + } + return ops + }, + }, + + transformResponse: async (response) => { + const raw: AzureDevOpsRawWorkItem = await response.json() + const workItem: AzureDevOpsWorkItem = mapWorkItem(raw) + return { + success: true, + output: { + content: `Updated work item #${workItem.id}:\n\n${formatWorkItem(workItem)}`, + metadata: { workItem }, + }, + } + }, + + outputs: { + content: { + type: 'string', + description: 'Human-readable summary of the updated work item', + }, + metadata: { + type: 'object', + description: 'Updated work item metadata', + properties: { + workItem: { + type: 'object', + description: 'Full details of the updated work item', + properties: { + id: { type: 'number', description: 'Work item ID' }, + title: { type: 'string', description: 'Work item title' }, + state: { type: 'string', description: 'Current state after update' }, + workItemType: { + type: 'string', + description: 'Work item type returned by Azure DevOps (e.g. Issue, Task, Epic)', + }, + assignedTo: { + type: 'string', + description: 'Display name of assigned user, or null if unassigned', + }, + areaPath: { type: 'string', description: 'Area path of the work item' }, + url: { type: 'string', description: 'API URL for the work item' }, + }, + }, + }, + }, + }, +} diff --git a/apps/sim/tools/azure_devops/utils.ts b/apps/sim/tools/azure_devops/utils.ts new file mode 100644 index 00000000000..b0955498554 --- /dev/null +++ b/apps/sim/tools/azure_devops/utils.ts @@ -0,0 +1,120 @@ +import type { AzureDevOpsComment, AzureDevOpsWorkItem } from '@/tools/azure_devops/types' + +/** States for Azure DevOps Basic process work items (Issue, Task, Epic). */ +export const AZURE_DEVOPS_BASIC_WORK_ITEM_STATES = ['To Do', 'Doing', 'Done'] as const + +/** Work item types for Azure DevOps Basic process. */ +export const AZURE_DEVOPS_BASIC_WORK_ITEM_TYPES = ['Issue', 'Task', 'Epic'] as const + +export type AzureDevOpsJsonPatchOp = { + op: string + path: string + value: string | number +} + +/** + * Appends a JSON-Patch op for a single work item field when the value is non-empty. + * Skips silently on undefined/empty-string. Numbers are validated; strings are + * passed through. + */ +export function appendFieldPatchOp( + ops: AzureDevOpsJsonPatchOp[], + refName: string, + value: string | number | undefined, + patchOp: 'add' | 'replace', + kind: 'number' | 'string' +): void { + if (value === undefined || value === '') return + if (kind === 'number') { + const numeric = Number(value) + if (Number.isNaN(numeric)) return + ops.push({ op: patchOp, path: `/fields/${refName}`, value: numeric }) + return + } + ops.push({ op: patchOp, path: `/fields/${refName}`, value: String(value) }) +} + +/** + * Appends a Microsoft.VSTS.Scheduling.Effort patch when effort is a valid number. + * Field availability depends on work item type and process template (Issue in Basic). + */ +export function appendEffortPatchOp( + ops: AzureDevOpsJsonPatchOp[], + effort: number | string | undefined, + patchOp: 'add' | 'replace' +): void { + appendFieldPatchOp(ops, 'Microsoft.VSTS.Scheduling.Effort', effort, patchOp, 'number') +} + +export function mapWorkItem(raw: AzureDevOpsRawWorkItem): AzureDevOpsWorkItem { + const fields = raw.fields ?? {} + return { + id: raw.id, + title: (fields['System.Title'] as string | undefined) ?? '', + state: (fields['System.State'] as string | undefined) ?? '', + workItemType: (fields['System.WorkItemType'] as string | undefined) ?? '', + assignedTo: + (fields['System.AssignedTo'] as { displayName?: string } | undefined)?.displayName ?? null, + areaPath: (fields['System.AreaPath'] as string | undefined) ?? '', + url: raw.url, + } +} + +export function formatWorkItem(w: AzureDevOpsWorkItem): string { + return [ + `ID: ${w.id} [${w.workItemType}] ${w.title}`, + ` State: ${w.state}`, + ` Assigned To: ${w.assignedTo ?? 'Unassigned'}`, + ` Area: ${w.areaPath}`, + ].join('\n') +} + +export interface AzureDevOpsRawWorkItem { + id: number + url: string + fields: Record +} + +export function mapComment(raw: AzureDevOpsRawComment): AzureDevOpsComment { + return { + workItemId: raw.workItemId, + commentId: raw.commentId ?? raw.id, + version: raw.version, + text: raw.text, + renderedText: raw.renderedText, + createdBy: raw.createdBy?.displayName ?? null, + createdDate: raw.createdDate, + modifiedBy: raw.modifiedBy?.displayName ?? null, + modifiedDate: raw.modifiedDate, + isDeleted: raw.isDeleted ?? false, + url: raw.url, + } +} + +export function formatComment(comment: AzureDevOpsComment): string { + return [ + `Comment #${comment.commentId} on work item #${comment.workItemId}`, + ` Author: ${comment.createdBy ?? 'Unknown'}`, + ` Created: ${comment.createdDate}`, + ` Text: ${comment.text}`, + ].join('\n') +} + +interface AzureDevOpsIdentityRef { + displayName?: string +} + +export interface AzureDevOpsRawComment { + id: number + commentId?: number + workItemId: number + version: number + text: string + renderedText?: string + createdBy?: AzureDevOpsIdentityRef + createdDate: string + modifiedBy?: AzureDevOpsIdentityRef + modifiedDate: string + isDeleted?: boolean + url: string +} diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index b65d6bda699..4ad97b0cdfa 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -241,6 +241,24 @@ import { attioUpdateTaskTool, attioUpdateWebhookTool, } from '@/tools/attio' +import { + addCommentTool as azureDevopsAddCommentTool, + createWorkItemTool as azureDevopsCreateWorkItemTool, + getBuildLogTool as azureDevopsGetBuildLogTool, + getBuildTimelineTool as azureDevopsGetBuildTimelineTool, + getCommentsTool as azureDevopsGetCommentsTool, + getPipelineRunTool as azureDevopsGetPipelineRunTool, + getPipelineTool as azureDevopsGetPipelineTool, + getWorkItemsBatchTool as azureDevopsGetWorkItemsBatchTool, + getWorkItemsBetweenBuildsTool as azureDevopsGetWorkItemsBetweenBuildsTool, + getWorkItemTool as azureDevopsGetWorkItemTool, + listBuildLogsTool as azureDevopsListBuildLogsTool, + listBuildsTool as azureDevopsListBuildsTool, + listPipelineRunsTool as azureDevopsListPipelineRunsTool, + listPipelinesTool as azureDevopsListPipelinesTool, + queryWorkItemsTool as azureDevopsQueryWorkItemsTool, + updateWorkItemTool as azureDevopsUpdateWorkItemTool, +} from '@/tools/azure_devops' import { boxCopyFileTool, boxCreateFolderTool, @@ -3215,6 +3233,22 @@ export const tools: Record = { brightdata_serp_search: brightDataSerpSearchTool, brightdata_snapshot_status: brightDataSnapshotStatusTool, brightdata_sync_scrape: brightDataSyncScrapeTool, + azure_devops_list_pipelines: azureDevopsListPipelinesTool, + azure_devops_get_pipeline: azureDevopsGetPipelineTool, + azure_devops_list_pipeline_runs: azureDevopsListPipelineRunsTool, + azure_devops_get_pipeline_run: azureDevopsGetPipelineRunTool, + azure_devops_list_builds: azureDevopsListBuildsTool, + azure_devops_list_build_logs: azureDevopsListBuildLogsTool, + azure_devops_get_build_log: azureDevopsGetBuildLogTool, + azure_devops_get_build_timeline: azureDevopsGetBuildTimelineTool, + azure_devops_get_work_items_between_builds: azureDevopsGetWorkItemsBetweenBuildsTool, + azure_devops_query_work_items: azureDevopsQueryWorkItemsTool, + azure_devops_get_work_item: azureDevopsGetWorkItemTool, + azure_devops_get_work_items_batch: azureDevopsGetWorkItemsBatchTool, + azure_devops_create_work_item: azureDevopsCreateWorkItemTool, + azure_devops_update_work_item: azureDevopsUpdateWorkItemTool, + azure_devops_add_comment: azureDevopsAddCommentTool, + azure_devops_get_comments: azureDevopsGetCommentsTool, box_copy_file: boxCopyFileTool, box_create_folder: boxCreateFolderTool, box_delete_file: boxDeleteFileTool, diff --git a/apps/sim/triggers/azure_devops/build_failed.ts b/apps/sim/triggers/azure_devops/build_failed.ts new file mode 100644 index 00000000000..f43619215f8 --- /dev/null +++ b/apps/sim/triggers/azure_devops/build_failed.ts @@ -0,0 +1,34 @@ +import { AzureDevOpsIcon } from '@/components/icons' +import { buildTriggerSubBlocks } from '@/triggers' +import { + azureDevOpsTriggerOptions, + buildBuildFailedOutputs, + buildFailedSetupInstructions, +} from '@/triggers/azure_devops/utils' +import type { TriggerConfig } from '@/triggers/types' + +export const azureDevOpsBuildFailedTrigger: TriggerConfig = { + id: 'azure_devops_build_failed', + name: 'Azure DevOps Build Failed', + provider: 'azure_devops', + description: + 'Trigger workflow when an Azure DevOps build fails, is canceled, or partially succeeds', + version: '1.0.0', + icon: AzureDevOpsIcon, + + subBlocks: buildTriggerSubBlocks({ + triggerId: 'azure_devops_build_failed', + triggerOptions: azureDevOpsTriggerOptions, + includeDropdown: true, + setupInstructions: buildFailedSetupInstructions, + }), + + outputs: buildBuildFailedOutputs(), + + webhook: { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }, +} diff --git a/apps/sim/triggers/azure_devops/index.ts b/apps/sim/triggers/azure_devops/index.ts new file mode 100644 index 00000000000..5ef419ea36d --- /dev/null +++ b/apps/sim/triggers/azure_devops/index.ts @@ -0,0 +1,3 @@ +export { azureDevOpsBuildFailedTrigger } from './build_failed' +export { azureDevOpsWebhookTrigger } from './webhook' +export { azureDevOpsWorkItemCreatedTrigger } from './work_item_created' diff --git a/apps/sim/triggers/azure_devops/utils.ts b/apps/sim/triggers/azure_devops/utils.ts new file mode 100644 index 00000000000..5300126dd57 --- /dev/null +++ b/apps/sim/triggers/azure_devops/utils.ts @@ -0,0 +1,283 @@ +import type { TriggerOutput } from '@/triggers/types' + +export const azureDevOpsTriggerOptions = [ + { label: 'Build Failed', id: 'azure_devops_build_failed' }, + { label: 'Work Item Created', id: 'azure_devops_work_item_created' }, + { label: 'All Service Hook Events', id: 'azure_devops_webhook' }, +] + +export const AZURE_DEVOPS_BUILD_FAILED_EVENT = 'build.complete' +export const AZURE_DEVOPS_WORK_ITEM_CREATED_EVENT = 'workitem.created' + +function instructions(steps: string[]): string { + return steps.map((s, i) => `
${i + 1}. ${s}
`).join('') +} + +export const buildFailedSetupInstructions = instructions([ + 'Open your Azure DevOps project and go to Project settings → Service hooks.', + 'Click + Create subscription, choose Web Hooks, then Next.', + 'For Trigger on this type of event, select Build completed.', + 'Under Filters, set Build result to Failed (optionally add Canceled / Partially succeeded).', + 'Click Next, paste the Webhook URL above into the URL field.', + 'Leave other fields as defaults. Click Test to verify, then Finish.', +]) + +export const workItemCreatedSetupInstructions = instructions([ + 'Open your Azure DevOps project and go to Project settings → Service hooks.', + 'Click + Create subscription, choose Web Hooks, then Next.', + 'For Trigger on this type of event, select Work item created.', + 'Click Next, paste the Webhook URL above into the URL field.', + 'Leave other fields as defaults. Click Test to verify, then Finish.', +]) + +export const webhookSetupInstructions = instructions([ + 'Open your Azure DevOps project and go to Project settings → Service hooks.', + 'Click + Create subscription, choose Web Hooks, then Next.', + 'Select whichever event types you want this URL to receive (build, work item, release, etc.).', + 'Click Next, paste the Webhook URL above into the URL field.', + 'Leave other fields as defaults. Click Test to verify, then Finish.', + 'Sim does not filter deliveries for this trigger — configure event types in Azure DevOps.', +]) + +/** + * Returns whether an Azure DevOps service hook payload matches the configured trigger. + */ +export function isAzureDevOpsEventMatch(triggerId: string, body: Record): boolean { + if (triggerId === 'azure_devops_webhook') { + return true + } + + const eventType = body.eventType as string | undefined + + if (triggerId === 'azure_devops_build_failed') { + if (eventType !== AZURE_DEVOPS_BUILD_FAILED_EVENT) { + return false + } + const resource = body.resource as Record | undefined + const result = (resource?.result as string | undefined)?.toLowerCase() + return ( + result === 'failed' || + result === 'canceled' || + result === 'cancelled' || + result === 'stopped' || + result === 'partiallysucceeded' + ) + } + + if (triggerId === 'azure_devops_work_item_created') { + return eventType === AZURE_DEVOPS_WORK_ITEM_CREATED_EVENT + } + + return false +} + +export function buildBuildFailedOutputs(): Record { + return { + buildId: { + type: 'number', + description: 'Build ID', + }, + buildNumber: { + type: 'string', + description: 'Build number string (e.g. 20240101.1)', + }, + result: { + type: 'string', + description: 'Build result: failed | canceled | partiallySucceeded', + }, + pipelineId: { + type: 'number', + description: 'Pipeline definition ID', + }, + pipelineName: { + type: 'string', + description: 'Pipeline definition name', + }, + projectName: { + type: 'string', + description: 'Azure DevOps project name', + }, + branch: { + type: 'string', + description: 'Source branch name (refs/heads/ prefix stripped)', + }, + commitSha: { + type: 'string', + description: 'Source commit SHA', + }, + triggeredBy: { + type: 'string', + description: 'Display name of the person who triggered the build', + }, + triggeredByEmail: { + type: 'string', + description: 'Email/unique name of the person who triggered the build, or null if not set', + }, + startTime: { + type: 'string', + description: 'Build start time (ISO 8601)', + }, + finishTime: { + type: 'string', + description: 'Build finish time (ISO 8601)', + }, + buildUrl: { + type: 'string', + description: 'API URL for the build resource', + }, + } +} + +export function buildWorkItemCreatedOutputs(): Record { + return { + workItemId: { + type: 'number', + description: 'Work item ID', + }, + workItemType: { + type: 'string', + description: 'Work item type for Basic process (e.g. Issue, Task, Epic)', + }, + title: { + type: 'string', + description: 'Work item title', + }, + state: { + type: 'string', + description: 'Work item state for Basic process (e.g. To Do, Doing, Done)', + }, + createdBy: { + type: 'string', + description: 'Display name of the creator, or null if not set', + }, + assignedTo: { + type: 'string', + description: 'Assignee display name, or null if unassigned', + }, + priority: { + type: 'number', + description: 'Priority (1–4), or 0 if not set', + }, + areaPath: { + type: 'string', + description: 'Area path', + }, + iterationPath: { + type: 'string', + description: 'Iteration path', + }, + description: { + type: 'string', + description: 'Work item description (HTML), or null if not set', + }, + projectName: { + type: 'string', + description: 'Azure DevOps project name', + }, + workItemUrl: { + type: 'string', + description: 'API URL for the work item resource', + }, + } +} + +export function buildWebhookOutputs(): Record { + return { + eventType: { + type: 'string', + description: 'Service hook event type (e.g. build.complete, workitem.created)', + }, + notificationId: { + type: 'number', + description: 'Notification ID', + }, + subscriptionId: { + type: 'string', + description: 'Service hook subscription ID', + }, + publisherId: { + type: 'string', + description: 'Publisher ID (e.g. tfs)', + }, + createdDate: { + type: 'string', + description: 'Event creation time (ISO 8601)', + }, + resource: { + type: 'json', + description: 'Event resource payload', + }, + resourceContainers: { + type: 'json', + description: 'Resource container references (project, collection, etc.)', + }, + message: { + type: 'json', + description: 'Short message object', + }, + detailedMessage: { + type: 'json', + description: 'Detailed message object', + }, + } +} + +export function formatBuildCompleteInput(body: Record): Record { + const resource = (body.resource ?? {}) as Record + const definition = (resource.definition ?? {}) as Record + const project = (resource.project ?? {}) as Record + const requestedFor = (resource.requestedFor ?? {}) as Record + const sourceBranch = (resource.sourceBranch as string) ?? '' + + return { + buildId: Number(resource.id ?? 0), + buildNumber: (resource.buildNumber as string) ?? '', + result: (resource.result as string) ?? '', + pipelineId: Number(definition.id ?? 0), + pipelineName: (definition.name as string) ?? '', + projectName: (project.name as string) ?? '', + branch: sourceBranch.replace(/^refs\/heads\//, ''), + commitSha: (resource.sourceVersion as string) ?? '', + triggeredBy: (requestedFor.displayName as string) ?? null, + triggeredByEmail: (requestedFor.uniqueName as string) ?? null, + startTime: (resource.startTime as string) ?? '', + finishTime: (resource.finishTime as string) ?? '', + buildUrl: (resource.url as string) ?? '', + } +} + +export function formatWorkItemCreatedInput(body: Record): Record { + const resource = (body.resource ?? {}) as Record + const fields = (resource.fields ?? {}) as Record + + return { + workItemId: Number(resource.id ?? 0), + workItemType: (fields['System.WorkItemType'] as string) ?? '', + title: (fields['System.Title'] as string) ?? '', + state: (fields['System.State'] as string) ?? '', + createdBy: + (fields['System.CreatedBy'] as { displayName?: string } | undefined)?.displayName ?? null, + assignedTo: + (fields['System.AssignedTo'] as { displayName?: string } | undefined)?.displayName ?? null, + priority: Number(fields['Microsoft.VSTS.Common.Priority'] ?? 0), + areaPath: (fields['System.AreaPath'] as string) ?? '', + iterationPath: (fields['System.IterationPath'] as string) ?? '', + description: (fields['System.Description'] as string) ?? null, + projectName: (fields['System.TeamProject'] as string) ?? '', + workItemUrl: (resource.url as string) ?? '', + } +} + +export function formatWebhookEnvelopeInput(body: Record): Record { + return { + eventType: (body.eventType as string) ?? '', + notificationId: Number(body.notificationId ?? 0), + subscriptionId: (body.subscriptionId as string) ?? '', + publisherId: (body.publisherId as string) ?? '', + createdDate: (body.createdDate as string) ?? '', + resource: body.resource ?? null, + resourceContainers: body.resourceContainers ?? null, + message: body.message ?? null, + detailedMessage: body.detailedMessage ?? null, + } +} diff --git a/apps/sim/triggers/azure_devops/webhook.ts b/apps/sim/triggers/azure_devops/webhook.ts new file mode 100644 index 00000000000..fda04424090 --- /dev/null +++ b/apps/sim/triggers/azure_devops/webhook.ts @@ -0,0 +1,37 @@ +import { AzureDevOpsIcon } from '@/components/icons' +import { buildTriggerSubBlocks } from '@/triggers' +import { + azureDevOpsTriggerOptions, + buildWebhookOutputs, + webhookSetupInstructions, +} from '@/triggers/azure_devops/utils' +import type { TriggerConfig } from '@/triggers/types' + +/** + * Azure DevOps generic webhook trigger. + * Event filtering is determined by which events you enable on the service hook subscription. + */ +export const azureDevOpsWebhookTrigger: TriggerConfig = { + id: 'azure_devops_webhook', + name: 'Azure DevOps Webhook (All Service Hook Events)', + provider: 'azure_devops', + description: + 'Trigger on whichever service hook event types you configure in Azure DevOps. Sim does not filter deliveries for this trigger.', + version: '1.0.0', + icon: AzureDevOpsIcon, + + subBlocks: buildTriggerSubBlocks({ + triggerId: 'azure_devops_webhook', + triggerOptions: azureDevOpsTriggerOptions, + setupInstructions: webhookSetupInstructions, + }), + + outputs: buildWebhookOutputs(), + + webhook: { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }, +} diff --git a/apps/sim/triggers/azure_devops/work_item_created.ts b/apps/sim/triggers/azure_devops/work_item_created.ts new file mode 100644 index 00000000000..289ddf46768 --- /dev/null +++ b/apps/sim/triggers/azure_devops/work_item_created.ts @@ -0,0 +1,32 @@ +import { AzureDevOpsIcon } from '@/components/icons' +import { buildTriggerSubBlocks } from '@/triggers' +import { + azureDevOpsTriggerOptions, + buildWorkItemCreatedOutputs, + workItemCreatedSetupInstructions, +} from '@/triggers/azure_devops/utils' +import type { TriggerConfig } from '@/triggers/types' + +export const azureDevOpsWorkItemCreatedTrigger: TriggerConfig = { + id: 'azure_devops_work_item_created', + name: 'Azure DevOps Work Item Created', + provider: 'azure_devops', + description: 'Trigger workflow when a work item is created in Azure DevOps', + version: '1.0.0', + icon: AzureDevOpsIcon, + + subBlocks: buildTriggerSubBlocks({ + triggerId: 'azure_devops_work_item_created', + triggerOptions: azureDevOpsTriggerOptions, + setupInstructions: workItemCreatedSetupInstructions, + }), + + outputs: buildWorkItemCreatedOutputs(), + + webhook: { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }, +} diff --git a/apps/sim/triggers/registry.ts b/apps/sim/triggers/registry.ts index b1d747f529f..bb4d252d751 100644 --- a/apps/sim/triggers/registry.ts +++ b/apps/sim/triggers/registry.ts @@ -31,6 +31,11 @@ import { attioWebhookTrigger, attioWorkspaceMemberCreatedTrigger, } from '@/triggers/attio' +import { + azureDevOpsBuildFailedTrigger, + azureDevOpsWebhookTrigger, + azureDevOpsWorkItemCreatedTrigger, +} from '@/triggers/azure_devops' import { calcomBookingCancelledTrigger, calcomBookingCreatedTrigger, @@ -340,6 +345,9 @@ export const TRIGGER_REGISTRY: TriggerRegistry = { ashby_candidate_delete: ashbyCandidateDeleteTrigger, ashby_job_create: ashbyJobCreateTrigger, ashby_offer_create: ashbyOfferCreateTrigger, + azure_devops_build_failed: azureDevOpsBuildFailedTrigger, + azure_devops_webhook: azureDevOpsWebhookTrigger, + azure_devops_work_item_created: azureDevOpsWorkItemCreatedTrigger, attio_webhook: attioWebhookTrigger, attio_record_created: attioRecordCreatedTrigger, attio_record_updated: attioRecordUpdatedTrigger, From 6c755cbb597c3d8247b28c392a1e8c738f56e16f Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 19 May 2026 14:12:28 -0700 Subject: [PATCH 08/13] feat(integrations): add Gong incident.io Railway and New Relic (#4663) * feat(integrations): add Gong incident.io Railway and New Relic * fix(railway): preserve explicit empty variable values * fix(incidentio): fail on invalid workflow JSON * fix(new-relic): validate custom attributes JSON * fix(integrations): address incident workflow review fixes * chore(docs): apply lint formatting * chore: refresh integration docs and validation fixes * more * fix(integrations): address PR review comments * fix(gong): align list calls block validation --- apps/docs/components/icons.tsx | 23 + apps/docs/components/ui/icon-mapping.ts | 4 + apps/docs/content/docs/en/tools/gong.mdx | 37 +- .../docs/content/docs/en/tools/incidentio.mdx | 206 ++++-- apps/docs/content/docs/en/tools/meta.json | 2 + apps/docs/content/docs/en/tools/new_relic.mdx | 143 ++++ apps/docs/content/docs/en/tools/railway.mdx | 343 ++++++++++ .../integrations/data/icon-mapping.ts | 4 + .../integrations/data/integrations.json | 122 +++- apps/sim/blocks/blocks/gong.ts | 139 +++- apps/sim/blocks/blocks/incidentio.ts | 501 ++++++++++---- apps/sim/blocks/blocks/new_relic.ts | 355 ++++++++++ apps/sim/blocks/blocks/railway.ts | 642 ++++++++++++++++++ apps/sim/blocks/registry.ts | 4 + apps/sim/components/icons.tsx | 23 + apps/sim/tools/gong/aggregate_activity.ts | 16 +- apps/sim/tools/gong/answered_scorecards.ts | 25 +- apps/sim/tools/gong/create_call.ts | 157 +++++ apps/sim/tools/gong/get_call.ts | 5 +- apps/sim/tools/gong/get_call_transcript.ts | 16 +- apps/sim/tools/gong/get_coaching.ts | 11 +- apps/sim/tools/gong/get_extensive_calls.ts | 23 +- apps/sim/tools/gong/get_folder_content.ts | 5 +- apps/sim/tools/gong/get_user.ts | 5 +- apps/sim/tools/gong/index.ts | 4 + apps/sim/tools/gong/interaction_stats.ts | 16 +- apps/sim/tools/gong/list_calls.ts | 31 +- apps/sim/tools/gong/list_flows.ts | 9 +- apps/sim/tools/gong/list_library_folders.ts | 5 +- apps/sim/tools/gong/list_scorecards.ts | 3 +- apps/sim/tools/gong/list_trackers.ts | 5 +- apps/sim/tools/gong/list_users.ts | 11 +- apps/sim/tools/gong/list_workspaces.ts | 3 +- apps/sim/tools/gong/lookup_email.ts | 5 +- apps/sim/tools/gong/lookup_phone.ts | 5 +- apps/sim/tools/gong/types.ts | 29 + apps/sim/tools/gong/utils.ts | 68 ++ apps/sim/tools/incidentio/actions_list.ts | 13 +- apps/sim/tools/incidentio/actions_show.ts | 2 +- .../tools/incidentio/custom_fields_delete.ts | 2 +- .../tools/incidentio/custom_fields_show.ts | 2 +- .../tools/incidentio/custom_fields_update.ts | 2 +- .../incidentio/escalation_paths_create.ts | 4 +- .../incidentio/escalation_paths_delete.ts | 2 +- .../tools/incidentio/escalation_paths_list.ts | 96 +++ .../tools/incidentio/escalation_paths_show.ts | 4 +- .../incidentio/escalation_paths_update.ts | 19 +- apps/sim/tools/incidentio/escalations_list.ts | 34 +- apps/sim/tools/incidentio/escalations_show.ts | 2 +- apps/sim/tools/incidentio/follow_ups_list.ts | 13 +- apps/sim/tools/incidentio/follow_ups_show.ts | 2 +- .../tools/incidentio/incident_roles_delete.ts | 2 +- .../tools/incidentio/incident_roles_show.ts | 2 +- .../tools/incidentio/incident_roles_update.ts | 2 +- .../incidentio/incident_timestamps_show.ts | 2 +- .../tools/incidentio/incident_updates_list.ts | 11 +- apps/sim/tools/incidentio/incidents_list.ts | 22 +- apps/sim/tools/incidentio/incidents_show.ts | 2 +- apps/sim/tools/incidentio/incidents_update.ts | 2 +- apps/sim/tools/incidentio/index.ts | 4 + .../tools/incidentio/schedule_entries_list.ts | 66 +- .../incidentio/schedule_overrides_create.ts | 8 + apps/sim/tools/incidentio/schedules_delete.ts | 2 +- apps/sim/tools/incidentio/schedules_show.ts | 2 +- apps/sim/tools/incidentio/schedules_update.ts | 2 +- apps/sim/tools/incidentio/types.ts | 124 +++- apps/sim/tools/incidentio/users_list.ts | 22 +- apps/sim/tools/incidentio/users_show.ts | 2 +- apps/sim/tools/incidentio/utils.ts | 73 ++ apps/sim/tools/incidentio/workflows_create.ts | 70 +- apps/sim/tools/incidentio/workflows_delete.ts | 2 +- apps/sim/tools/incidentio/workflows_list.ts | 76 +-- apps/sim/tools/incidentio/workflows_show.ts | 51 +- apps/sim/tools/incidentio/workflows_update.ts | 130 ++-- .../new_relic/create_deployment_event.ts | 384 +++++++++++ apps/sim/tools/new_relic/get_entity.ts | 93 +++ apps/sim/tools/new_relic/index.ts | 5 + apps/sim/tools/new_relic/nrql_query.ts | 111 +++ apps/sim/tools/new_relic/search_entities.ts | 131 ++++ apps/sim/tools/new_relic/types.ts | 100 +++ apps/sim/tools/new_relic/utils.ts | 42 ++ apps/sim/tools/railway/create_environment.ts | 131 ++++ apps/sim/tools/railway/create_project.ts | 131 ++++ apps/sim/tools/railway/delete_environment.ts | 82 +++ apps/sim/tools/railway/delete_project.ts | 82 +++ apps/sim/tools/railway/deploy_service.ts | 118 ++++ apps/sim/tools/railway/get_project.ts | 166 +++++ apps/sim/tools/railway/index.ts | 31 + apps/sim/tools/railway/list_deployments.ts | 171 +++++ .../sim/tools/railway/list_project_members.ts | 123 ++++ apps/sim/tools/railway/list_projects.ts | 156 +++++ apps/sim/tools/railway/list_variables.ts | 102 +++ apps/sim/tools/railway/transfer_project.ts | 91 +++ apps/sim/tools/railway/types.ts | 245 +++++++ apps/sim/tools/railway/update_project.ts | 127 ++++ apps/sim/tools/railway/upsert_variable.ts | 123 ++++ apps/sim/tools/railway/utils.ts | 58 ++ apps/sim/tools/registry.ts | 80 ++- 98 files changed, 6147 insertions(+), 617 deletions(-) create mode 100644 apps/docs/content/docs/en/tools/new_relic.mdx create mode 100644 apps/docs/content/docs/en/tools/railway.mdx create mode 100644 apps/sim/blocks/blocks/new_relic.ts create mode 100644 apps/sim/blocks/blocks/railway.ts create mode 100644 apps/sim/tools/gong/create_call.ts create mode 100644 apps/sim/tools/gong/utils.ts create mode 100644 apps/sim/tools/incidentio/escalation_paths_list.ts create mode 100644 apps/sim/tools/incidentio/utils.ts create mode 100644 apps/sim/tools/new_relic/create_deployment_event.ts create mode 100644 apps/sim/tools/new_relic/get_entity.ts create mode 100644 apps/sim/tools/new_relic/index.ts create mode 100644 apps/sim/tools/new_relic/nrql_query.ts create mode 100644 apps/sim/tools/new_relic/search_entities.ts create mode 100644 apps/sim/tools/new_relic/types.ts create mode 100644 apps/sim/tools/new_relic/utils.ts create mode 100644 apps/sim/tools/railway/create_environment.ts create mode 100644 apps/sim/tools/railway/create_project.ts create mode 100644 apps/sim/tools/railway/delete_environment.ts create mode 100644 apps/sim/tools/railway/delete_project.ts create mode 100644 apps/sim/tools/railway/deploy_service.ts create mode 100644 apps/sim/tools/railway/get_project.ts create mode 100644 apps/sim/tools/railway/index.ts create mode 100644 apps/sim/tools/railway/list_deployments.ts create mode 100644 apps/sim/tools/railway/list_project_members.ts create mode 100644 apps/sim/tools/railway/list_projects.ts create mode 100644 apps/sim/tools/railway/list_variables.ts create mode 100644 apps/sim/tools/railway/transfer_project.ts create mode 100644 apps/sim/tools/railway/types.ts create mode 100644 apps/sim/tools/railway/update_project.ts create mode 100644 apps/sim/tools/railway/upsert_variable.ts create mode 100644 apps/sim/tools/railway/utils.ts diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index ab234725964..cd326d6220a 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -6958,6 +6958,14 @@ export function HexIcon(props: SVGProps) { ) } +export function RailwayIcon(props: SVGProps) { + return ( + + + + ) +} + export function BigQueryIcon(props: SVGProps) { return ( @@ -6981,6 +6989,21 @@ export function SnowflakeIcon(props: SVGProps) { ) } +export function NewRelicIcon(props: SVGProps) { + return ( + + + + + ) +} + export function WizaIcon(props: SVGProps) { return ( diff --git a/apps/docs/components/ui/icon-mapping.ts b/apps/docs/components/ui/icon-mapping.ts index c1bbebc149d..c10f5fa9ce6 100644 --- a/apps/docs/components/ui/icon-mapping.ts +++ b/apps/docs/components/ui/icon-mapping.ts @@ -128,6 +128,7 @@ import { MongoDBIcon, MySQLIcon, Neo4jIcon, + NewRelicIcon, NotionIcon, ObsidianIcon, OktaIcon, @@ -149,6 +150,7 @@ import { PulseIcon, QdrantIcon, QuiverIcon, + RailwayIcon, RDSIcon, RedditIcon, RedisIcon, @@ -348,6 +350,7 @@ export const blockTypeToIconMap: Record = { mongodb: MongoDBIcon, mysql: MySQLIcon, neo4j: Neo4jIcon, + new_relic: NewRelicIcon, notion: NotionIcon, notion_v2: NotionIcon, obsidian: ObsidianIcon, @@ -371,6 +374,7 @@ export const blockTypeToIconMap: Record = { pulse_v2: PulseIcon, qdrant: QdrantIcon, quiver: QuiverIcon, + railway: RailwayIcon, rds: RDSIcon, reddit: RedditIcon, redis: RedisIcon, diff --git a/apps/docs/content/docs/en/tools/gong.mdx b/apps/docs/content/docs/en/tools/gong.mdx index 954883120ad..f01b1ae395a 100644 --- a/apps/docs/content/docs/en/tools/gong.mdx +++ b/apps/docs/content/docs/en/tools/gong.mdx @@ -48,7 +48,7 @@ Retrieve call data by date range from Gong. | `accessKey` | string | Yes | Gong API Access Key | | `accessKeySecret` | string | Yes | Gong API Access Key Secret | | `fromDateTime` | string | Yes | Start date/time in ISO-8601 format \(e.g., 2024-01-01T00:00:00Z\) | -| `toDateTime` | string | No | End date/time in ISO-8601 format \(e.g., 2024-01-31T23:59:59Z\). If omitted, lists calls up to the most recent. | +| `toDateTime` | string | No | End date/time in ISO-8601 format \(e.g., 2024-01-31T23:59:59Z\). Defaults to the current execution time when omitted. | | `cursor` | string | No | Pagination cursor from a previous response | | `workspaceId` | string | No | Gong workspace ID to filter calls | @@ -56,6 +56,7 @@ Retrieve call data by date range from Gong. | Parameter | Type | Description | | --------- | ---- | ----------- | +| `requestId` | string | A Gong request reference ID for troubleshooting purposes | | `calls` | array | List of calls matching the date range | | ↳ `id` | string | Gong's unique numeric identifier for the call | | ↳ `title` | string | Call title | @@ -79,6 +80,39 @@ Retrieve call data by date range from Gong. | ↳ `calendarEventId` | string | Calendar event identifier | | `cursor` | string | Pagination cursor for the next page | | `totalRecords` | number | Total number of records matching the filter | +| `currentPageSize` | number | Number of records in the current page | +| `currentPageNumber` | number | Current page number | + +### `gong_create_call` + +Upload call metadata to Gong and let Gong pull the media from a URL. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accessKey` | string | Yes | Gong API Access Key | +| `accessKeySecret` | string | Yes | Gong API Access Key Secret | +| `clientUniqueId` | string | Yes | Unique call ID from the source telephony or recording system | +| `actualStart` | string | Yes | Actual call start time in ISO-8601 format | +| `primaryUser` | string | Yes | Gong user ID for the call's host or owner | +| `parties` | json | Yes | Array of call parties, with at least the primary user included | +| `direction` | string | Yes | Call direction: Inbound, Outbound, Conference, or Unknown | +| `downloadMediaUrl` | string | Yes | URL where Gong can download the call media file | +| `title` | string | No | Human-readable call title | +| `workspaceId` | string | No | Optional Gong workspace ID | +| `disposition` | string | No | Optional call disposition | +| `purpose` | string | No | Optional call purpose | +| `context` | json | No | Optional CRM context array for the call | +| `callProviderCode` | string | No | Optional conferencing or telephony provider code | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `callId` | string | Gong's unique numeric identifier for the created call | +| `requestId` | string | Gong request reference ID for troubleshooting | +| `url` | string | URL to the created call in the Gong web app | ### `gong_get_call` @@ -275,6 +309,7 @@ List all users in your Gong account. | Parameter | Type | Description | | --------- | ---- | ----------- | +| `requestId` | string | A Gong request reference ID for troubleshooting purposes | | `users` | array | List of Gong users | | ↳ `id` | string | Unique numeric user ID \(up to 20 digits\) | | ↳ `emailAddress` | string | User email address | diff --git a/apps/docs/content/docs/en/tools/incidentio.mdx b/apps/docs/content/docs/en/tools/incidentio.mdx index 3476d3535e7..5d10442a33b 100644 --- a/apps/docs/content/docs/en/tools/incidentio.mdx +++ b/apps/docs/content/docs/en/tools/incidentio.mdx @@ -51,6 +51,8 @@ List incidents from incident.io. Returns a list of incidents with their details | `apiKey` | string | Yes | incident.io API Key | | `page_size` | number | No | Number of incidents to return per page \(e.g., 10, 25, 50\). Default: 25 | | `after` | string | No | Pagination cursor to fetch the next page of results \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | +| `sort_by` | string | No | Sort order for incidents: created_at_newest_first or created_at_oldest_first | +| `filter_mode` | string | No | How to combine filters: all or any | #### Output @@ -234,6 +236,7 @@ List actions from incident.io. Optionally filter by incident ID. | --------- | ---- | -------- | ----------- | | `apiKey` | string | Yes | incident.io API Key | | `incident_id` | string | No | Filter actions by incident ID \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | +| `incident_mode` | string | No | Filter actions by incident mode \(standard, retrospective, test, tutorial, or stream\) | #### Output @@ -308,6 +311,7 @@ List follow-ups from incident.io. Optionally filter by incident ID. | --------- | ---- | -------- | ----------- | | `apiKey` | string | Yes | incident.io API Key | | `incident_id` | string | No | Filter follow-ups by incident ID \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | +| `incident_mode` | string | No | Filter follow-ups by incident mode \(standard, retrospective, test, tutorial, or stream\) | #### Output @@ -395,6 +399,8 @@ List all users in your Incident.io workspace. Returns user details including id, | `apiKey` | string | Yes | Incident.io API Key | | `page_size` | number | No | Number of results to return per page \(e.g., 10, 25, 50\). Default: 25 | | `after` | string | No | Pagination cursor to fetch the next page of results | +| `email` | string | No | Filter users by email address | +| `slack_user_id` | string | No | Filter users by Slack user ID | #### Output @@ -440,23 +446,78 @@ List all workflows in your incident.io workspace. | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `apiKey` | string | Yes | incident.io API Key | -| `page_size` | number | No | Number of workflows to return per page \(e.g., 10, 25, 50\) | -| `after` | string | No | Pagination cursor to fetch the next page of results \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | | `workflows` | array | List of workflows | -| ↳ `id` | string | Unique identifier for the workflow | -| ↳ `name` | string | Name of the workflow | -| ↳ `state` | string | State of the workflow \(active, draft, or disabled\) | -| ↳ `folder` | string | Folder the workflow belongs to | -| ↳ `created_at` | string | When the workflow was created | -| ↳ `updated_at` | string | When the workflow was last updated | -| `pagination_meta` | object | Pagination metadata | -| ↳ `after` | string | Cursor for next page | -| ↳ `page_size` | number | Number of results per page | +| ↳ `id` | string | Workflow ID | +| ↳ `name` | string | Workflow name | +| ↳ `trigger` | string | Workflow trigger | +| ↳ `once_for` | array | Fields that make the workflow run once | +| ↳ `version` | number | Workflow version | +| ↳ `expressions` | array | Workflow expressions | +| ↳ `condition_groups` | array | Workflow condition groups | +| ↳ `steps` | array | Workflow steps | +| ↳ `include_private_incidents` | boolean | Whether the workflow includes private incidents | +| ↳ `include_private_escalations` | boolean | Whether the workflow includes private escalations | +| ↳ `runs_on_incident_modes` | array | Incident modes the workflow runs on | +| ↳ `continue_on_step_error` | boolean | Whether execution continues after a step error | +| ↳ `runs_on_incidents` | string | Incident lifecycle filter | +| ↳ `state` | string | Workflow state \(active, draft, disabled\) | +| ↳ `delay` | object | Workflow delay configuration | +| ↳ `folder` | string | Workflow folder | +| ↳ `runs_from` | string | When the workflow runs from | +| ↳ `shortform` | string | Workflow shortform identifier | + +### `incidentio_workflows_create` + +Create a new workflow in incident.io. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | incident.io API Key | +| `name` | string | Yes | Name of the workflow \(e.g., "Notify on Critical Incidents"\) | +| `folder` | string | No | Folder to organize the workflow in | +| `state` | string | No | State of the workflow \(active, draft, or disabled\) | +| `trigger` | string | No | Trigger type for the workflow \(e.g., "incident.updated", "incident.created"\) | +| `steps` | string | No | Array of workflow steps as JSON string. Example: \[\{"label": "Notify team", "name": "slack.post_message"\}\] | +| `condition_groups` | string | No | Array of condition groups as JSON string to control when the workflow runs. Example: \[\{"conditions": \[\{"operation": "one_of", "param_bindings": \[\], "subject": "incident.severity"\}\]\}\] | +| `runs_on_incidents` | string | No | When to run the workflow: "newly_created" \(only new incidents\), "newly_created_and_active" \(new and active incidents\), "active" \(only active incidents\), or "all" \(all incidents\) | +| `runs_on_incident_modes` | string | No | Array of incident modes to run on as JSON string. Example: \["standard", "retrospective"\] | +| `include_private_incidents` | boolean | No | Whether to include private incidents | +| `continue_on_step_error` | boolean | No | Whether to continue executing subsequent steps if a step fails | +| `once_for` | string | No | Array of fields to ensure the workflow runs only once per unique combination of these fields, as JSON string. Example: \["incident.id"\] | +| `expressions` | string | No | Array of workflow expressions as JSON string for advanced workflow logic. Example: \[\{"label": "My expression", "operations": \[\]\}\] | +| `delay` | string | No | Delay configuration as JSON string. Example: \{"for_seconds": 60, "conditions_apply_over_delay": false\} | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `workflow` | object | The created workflow | +| ↳ `id` | string | Workflow ID | +| ↳ `name` | string | Workflow name | +| ↳ `trigger` | string | Workflow trigger | +| ↳ `once_for` | array | Fields that make the workflow run once | +| ↳ `version` | number | Workflow version | +| ↳ `expressions` | array | Workflow expressions | +| ↳ `condition_groups` | array | Workflow condition groups | +| ↳ `steps` | array | Workflow steps | +| ↳ `include_private_incidents` | boolean | Whether the workflow includes private incidents | +| ↳ `include_private_escalations` | boolean | Whether the workflow includes private escalations | +| ↳ `runs_on_incident_modes` | array | Incident modes the workflow runs on | +| ↳ `continue_on_step_error` | boolean | Whether execution continues after a step error | +| ↳ `runs_on_incidents` | string | Incident lifecycle filter | +| ↳ `state` | string | Workflow state \(active, draft, disabled\) | +| ↳ `delay` | object | Workflow delay configuration | +| ↳ `folder` | string | Workflow folder | +| ↳ `runs_from` | string | When the workflow runs from | +| ↳ `shortform` | string | Workflow shortform identifier | +| `management_meta` | json | Workflow management metadata | ### `incidentio_workflows_show` @@ -468,18 +529,32 @@ Get details of a specific workflow in incident.io. | --------- | ---- | -------- | ----------- | | `apiKey` | string | Yes | incident.io API Key | | `id` | string | Yes | The ID of the workflow to retrieve \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | +| `skip_step_upgrades` | boolean | No | Skip workflow step upgrades when existing workflow step parameters changed | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | | `workflow` | object | The workflow details | -| ↳ `id` | string | Unique identifier for the workflow | -| ↳ `name` | string | Name of the workflow | -| ↳ `state` | string | State of the workflow \(active, draft, or disabled\) | -| ↳ `folder` | string | Folder the workflow belongs to | -| ↳ `created_at` | string | When the workflow was created | -| ↳ `updated_at` | string | When the workflow was last updated | +| ↳ `id` | string | Workflow ID | +| ↳ `name` | string | Workflow name | +| ↳ `trigger` | string | Workflow trigger | +| ↳ `once_for` | array | Fields that make the workflow run once | +| ↳ `version` | number | Workflow version | +| ↳ `expressions` | array | Workflow expressions | +| ↳ `condition_groups` | array | Workflow condition groups | +| ↳ `steps` | array | Workflow steps | +| ↳ `include_private_incidents` | boolean | Whether the workflow includes private incidents | +| ↳ `include_private_escalations` | boolean | Whether the workflow includes private escalations | +| ↳ `runs_on_incident_modes` | array | Incident modes the workflow runs on | +| ↳ `continue_on_step_error` | boolean | Whether execution continues after a step error | +| ↳ `runs_on_incidents` | string | Incident lifecycle filter | +| ↳ `state` | string | Workflow state \(active, draft, disabled\) | +| ↳ `delay` | object | Workflow delay configuration | +| ↳ `folder` | string | Workflow folder | +| ↳ `runs_from` | string | When the workflow runs from | +| ↳ `shortform` | string | Workflow shortform identifier | +| `management_meta` | json | Workflow management metadata | ### `incidentio_workflows_update` @@ -491,21 +566,43 @@ Update an existing workflow in incident.io. | --------- | ---- | -------- | ----------- | | `apiKey` | string | Yes | incident.io API Key | | `id` | string | Yes | The ID of the workflow to update \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | -| `name` | string | No | New name for the workflow \(e.g., "Notify on Critical Incidents"\) | +| `name` | string | Yes | New name for the workflow \(e.g., "Notify on Critical Incidents"\) | +| `steps` | string | Yes | Complete array of workflow steps as a JSON string | +| `condition_groups` | string | Yes | Complete array of workflow condition groups as a JSON string | +| `runs_on_incidents` | string | Yes | When to run the workflow: newly_created, newly_created_and_active, active, or all | +| `runs_on_incident_modes` | string | Yes | Complete array of incident modes to run on as a JSON string | +| `include_private_incidents` | boolean | Yes | Whether to include private incidents | +| `continue_on_step_error` | boolean | Yes | Whether to continue executing subsequent steps if a step fails | +| `once_for` | string | Yes | Complete array of fields that make the workflow run once as a JSON string | +| `expressions` | string | Yes | Complete array of workflow expressions as a JSON string | | `state` | string | No | New state for the workflow \(active, draft, or disabled\) | | `folder` | string | No | New folder for the workflow | +| `delay` | string | No | Delay configuration as a JSON string | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | | `workflow` | object | The updated workflow | -| ↳ `id` | string | Unique identifier for the workflow | -| ↳ `name` | string | Name of the workflow | -| ↳ `state` | string | State of the workflow \(active, draft, or disabled\) | -| ↳ `folder` | string | Folder the workflow belongs to | -| ↳ `created_at` | string | When the workflow was created | -| ↳ `updated_at` | string | When the workflow was last updated | +| ↳ `id` | string | Workflow ID | +| ↳ `name` | string | Workflow name | +| ↳ `trigger` | string | Workflow trigger | +| ↳ `once_for` | array | Fields that make the workflow run once | +| ↳ `version` | number | Workflow version | +| ↳ `expressions` | array | Workflow expressions | +| ↳ `condition_groups` | array | Workflow condition groups | +| ↳ `steps` | array | Workflow steps | +| ↳ `include_private_incidents` | boolean | Whether the workflow includes private incidents | +| ↳ `include_private_escalations` | boolean | Whether the workflow includes private escalations | +| ↳ `runs_on_incident_modes` | array | Incident modes the workflow runs on | +| ↳ `continue_on_step_error` | boolean | Whether execution continues after a step error | +| ↳ `runs_on_incidents` | string | Incident lifecycle filter | +| ↳ `state` | string | Workflow state \(active, draft, disabled\) | +| ↳ `delay` | object | Workflow delay configuration | +| ↳ `folder` | string | Workflow folder | +| ↳ `runs_from` | string | When the workflow runs from | +| ↳ `shortform` | string | Workflow shortform identifier | +| `management_meta` | json | Workflow management metadata | ### `incidentio_workflows_delete` @@ -647,6 +744,8 @@ List all escalation policies in incident.io | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `apiKey` | string | Yes | incident.io API Key | +| `page_size` | number | No | Number of escalations to return per page | +| `after` | string | No | Pagination cursor to fetch the next page of results | #### Output @@ -657,6 +756,9 @@ List all escalation policies in incident.io | ↳ `name` | string | The escalation policy name | | ↳ `created_at` | string | When the escalation policy was created | | ↳ `updated_at` | string | When the escalation policy was last updated | +| `pagination_meta` | object | Pagination metadata | +| ↳ `after` | string | Cursor for next page | +| ↳ `page_size` | number | Number of results per page | ### `incidentio_escalations_create` @@ -1096,29 +1198,18 @@ List all entries for a specific schedule in incident.io | `schedule_id` | string | Yes | The ID of the schedule to get entries for \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | | `entry_window_start` | string | No | Start date/time to filter entries in ISO 8601 format \(e.g., "2024-01-15T09:00:00Z"\) | | `entry_window_end` | string | No | End date/time to filter entries in ISO 8601 format \(e.g., "2024-01-22T09:00:00Z"\) | -| `page_size` | number | No | Number of results to return per page \(e.g., 10, 25, 50\) | -| `after` | string | No | Cursor for pagination \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `schedule_entries` | array | List of schedule entries | -| ↳ `id` | string | The entry ID | -| ↳ `schedule_id` | string | The schedule ID | -| ↳ `user` | object | User assigned to this entry | -| ↳ `id` | string | User ID | -| ↳ `name` | string | User name | -| ↳ `email` | string | User email | -| ↳ `start_at` | string | When the entry starts | -| ↳ `end_at` | string | When the entry ends | -| ↳ `layer_id` | string | The schedule layer ID | -| ↳ `created_at` | string | When the entry was created | -| ↳ `updated_at` | string | When the entry was last updated | +| `schedule_entries` | object | Schedule entries grouped by final, overrides, and scheduled entries | +| ↳ `final` | array | Final computed schedule entries | +| ↳ `overrides` | array | Override schedule entries | +| ↳ `scheduled` | array | Scheduled entries before overrides are applied | | `pagination_meta` | object | Pagination information | | ↳ `after` | string | Cursor for next page | | ↳ `after_url` | string | URL for next page | -| ↳ `page_size` | number | Number of results per page | ### `incidentio_schedule_overrides_create` @@ -1130,6 +1221,7 @@ Create a new schedule override in incident.io | --------- | ---- | -------- | ----------- | | `apiKey` | string | Yes | incident.io API Key | | `rotation_id` | string | Yes | The ID of the rotation to override \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | +| `layer_id` | string | Yes | The ID of the layer this override applies to | | `schedule_id` | string | Yes | The ID of the schedule \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | | `user_id` | string | No | The ID of the user to assign \(provide one of: user_id, user_email, or user_slack_id\) | | `user_email` | string | No | The email of the user to assign \(provide one of: user_id, user_email, or user_slack_id\) | @@ -1143,6 +1235,7 @@ Create a new schedule override in incident.io | --------- | ---- | ----------- | | `override` | object | The created schedule override | | ↳ `id` | string | The override ID | +| ↳ `layer_id` | string | The schedule layer ID | | ↳ `rotation_id` | string | The rotation ID | | ↳ `schedule_id` | string | The schedule ID | | ↳ `user` | object | User assigned to this override | @@ -1154,6 +1247,31 @@ Create a new schedule override in incident.io | ↳ `created_at` | string | When the override was created | | ↳ `updated_at` | string | When the override was last updated | +### `incidentio_escalation_paths_list` + +List escalation paths in incident.io + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | incident.io API Key | +| `page_size` | number | No | Number of escalation paths to return per page | +| `after` | string | No | Pagination cursor to fetch the next page of results | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `escalation_paths` | array | List of escalation paths | +| ↳ `id` | string | The escalation path ID | +| ↳ `name` | string | The escalation path name | +| ↳ `path` | array | Array of escalation levels | +| ↳ `working_hours` | array | Working hours configuration | +| `pagination_meta` | object | Pagination metadata | +| ↳ `after` | string | Cursor for next page | +| ↳ `page_size` | number | Number of results per page | + ### `incidentio_escalation_paths_create` Create a new escalation path in incident.io @@ -1186,8 +1304,6 @@ Create a new escalation path in incident.io | ↳ `weekday` | string | Day of week | | ↳ `start_time` | string | Start time | | ↳ `end_time` | string | End time | -| ↳ `created_at` | string | When the path was created | -| ↳ `updated_at` | string | When the path was last updated | ### `incidentio_escalation_paths_show` @@ -1219,8 +1335,6 @@ Get details of a specific escalation path in incident.io | ↳ `weekday` | string | Day of week | | ↳ `start_time` | string | Start time | | ↳ `end_time` | string | End time | -| ↳ `created_at` | string | When the path was created | -| ↳ `updated_at` | string | When the path was last updated | ### `incidentio_escalation_paths_update` @@ -1232,8 +1346,8 @@ Update an existing escalation path in incident.io | --------- | ---- | -------- | ----------- | | `apiKey` | string | Yes | incident.io API Key | | `id` | string | Yes | The ID of the escalation path to update \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) | -| `name` | string | No | New name for the escalation path \(e.g., "Critical Incident Path"\) | -| `path` | json | No | New escalation path configuration. Array of escalation levels with targets and time_to_ack_seconds | +| `name` | string | Yes | New name for the escalation path \(e.g., "Critical Incident Path"\) | +| `path` | json | Yes | New escalation path configuration. Array of escalation levels with targets and time_to_ack_seconds | | `working_hours` | json | No | New working hours configuration. Array of \{weekday, start_time, end_time\} | #### Output @@ -1255,8 +1369,6 @@ Update an existing escalation path in incident.io | ↳ `weekday` | string | Day of week | | ↳ `start_time` | string | Start time | | ↳ `end_time` | string | End time | -| ↳ `created_at` | string | When the path was created | -| ↳ `updated_at` | string | When the path was last updated | ### `incidentio_escalation_paths_delete` diff --git a/apps/docs/content/docs/en/tools/meta.json b/apps/docs/content/docs/en/tools/meta.json index 5e8a637079b..075f99a2954 100644 --- a/apps/docs/content/docs/en/tools/meta.json +++ b/apps/docs/content/docs/en/tools/meta.json @@ -124,6 +124,7 @@ "mongodb", "mysql", "neo4j", + "new_relic", "notion", "obsidian", "okta", @@ -145,6 +146,7 @@ "pulse", "qdrant", "quiver", + "railway", "rds", "reddit", "redis", diff --git a/apps/docs/content/docs/en/tools/new_relic.mdx b/apps/docs/content/docs/en/tools/new_relic.mdx new file mode 100644 index 00000000000..7beb793335a --- /dev/null +++ b/apps/docs/content/docs/en/tools/new_relic.mdx @@ -0,0 +1,143 @@ +--- +title: New Relic +description: Query observability data and record deployments in New Relic +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + + + +{/* MANUAL-CONTENT-START:intro */} +[New Relic](https://newrelic.com/) is an observability platform for monitoring application performance, infrastructure, logs, traces, and business-impacting changes across your systems. It centralizes telemetry in NRDB and exposes that data through NerdGraph, New Relic's GraphQL API. + +With New Relic, you can: + +- **Query telemetry with NRQL**: Run NRQL against account data to inspect service health, usage, errors, latency, and custom events. +- **Find monitored entities**: Search services, applications, hosts, and other monitored resources by name, type, tags, alert state, or reporting status. +- **Fetch entity details**: Resolve an entity GUID into basic entity metadata for downstream workflow steps. +- **Record deployment changes**: Create deployment change tracking events with version, changelog, commit, build links, group IDs, and user context. + +Sim's New Relic integration lets agents pull production observability signals into workflows and annotate releases or operational changes directly from automation. Use it to summarize live service health, route incident workflows from entity searches, or mark deployments so New Relic charts can correlate performance changes with release activity. +{/* MANUAL-CONTENT-END */} + + +## Usage Instructions + +Integrate New Relic into workflows. Run NRQL queries, search monitored entities, fetch entity details, and record deployment change events. + + + +## Tools + +### `new_relic_nrql_query` + +Run a NRQL query against a New Relic account using NerdGraph. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | New Relic user API key for NerdGraph | +| `region` | string | No | New Relic data center region: us or eu | +| `accountId` | number | Yes | New Relic account ID to query | +| `nrql` | string | Yes | NRQL query to execute | +| `timeout` | number | No | Optional query timeout in seconds | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `results` | array | NRQL result rows. Row fields depend on the query projection. | +| `resultCount` | number | Number of NRQL result rows returned | + +### `new_relic_search_entities` + +Search New Relic entities by name, GUID, domain type, tags, or reporting state. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | New Relic user API key for NerdGraph | +| `region` | string | No | New Relic data center region: us or eu | +| `query` | string | Yes | Entity search query, for example: name like "api" or domainType = "APM-APPLICATION" | +| `cursor` | string | No | Pagination cursor from a previous entity search | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `count` | number | Total number of entities matching the query | +| `query` | string | Entity search query New Relic executed | +| `entities` | array | Matching New Relic entities | +| ↳ `guid` | string | Entity GUID | +| ↳ `name` | string | Entity name | +| ↳ `entityType` | string | Entity type | +| `nextCursor` | string | Cursor for the next page of results | + +### `new_relic_get_entity` + +Fetch a New Relic entity by GUID. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | New Relic user API key for NerdGraph | +| `region` | string | No | New Relic data center region: us or eu | +| `guid` | string | Yes | Entity GUID | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `entity` | object | New Relic entity details | +| ↳ `guid` | string | Entity GUID | +| ↳ `name` | string | Entity name | +| ↳ `entityType` | string | Entity type | + +### `new_relic_create_deployment_event` + +Record a deployment change event in New Relic change tracking. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | New Relic user API key for NerdGraph | +| `region` | string | No | New Relic data center region: us or eu | +| `entityGuid` | string | Yes | GUID of the entity associated with the deployment | +| `version` | string | Yes | Deployment version, release name, or commit SHA | +| `shortDescription` | string | No | Short description of the deployment | +| `description` | string | No | Longer deployment description | +| `changelog` | string | No | Deployment changelog text or URL | +| `commit` | string | No | Commit SHA or identifier associated with the deployment | +| `deepLink` | string | No | URL to the deployment, build, or release details | +| `user` | string | No | User or automation that performed the deployment | +| `groupId` | string | No | Optional group ID to correlate related changes | +| `customAttributes` | json | No | Custom change event metadata as key-value pairs with string, number, or boolean values | +| `deploymentType` | string | No | Deployment type: basic, blue green, canary, rolling, or shadow | +| `timestamp` | number | No | Event timestamp in milliseconds since Unix epoch | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `event` | object | Created New Relic change tracking event | +| ↳ `changeTrackingId` | string | New Relic change tracking ID | +| ↳ `customAttributes` | json | Custom attributes on the change tracking event | +| ↳ `category` | string | Change category | +| ↳ `categoryAndType` | string | Combined category and type | +| ↳ `type` | string | Change type | +| ↳ `shortDescription` | string | Short change description | +| ↳ `description` | string | Change description | +| ↳ `timestamp` | number | Change timestamp in milliseconds | +| ↳ `user` | string | User associated with the change | +| ↳ `groupId` | string | Change group ID | +| ↳ `entity` | object | Entity associated with the change | +| ↳ `guid` | string | Entity GUID | +| ↳ `name` | string | Entity name | +| `messages` | array | Messages returned by New Relic for the created change event | diff --git a/apps/docs/content/docs/en/tools/railway.mdx b/apps/docs/content/docs/en/tools/railway.mdx new file mode 100644 index 00000000000..ab26d387838 --- /dev/null +++ b/apps/docs/content/docs/en/tools/railway.mdx @@ -0,0 +1,343 @@ +--- +title: Railway +description: Manage Railway projects, deployments, and variables +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + + + +{/* MANUAL-CONTENT-START:intro */} +[Railway](https://railway.com/) is a cloud application platform for deploying, operating, and scaling services, databases, jobs, and production environments from a single project workspace. Teams use Railway to connect source repositories, manage environments, configure variables, trigger deployments, and monitor delivery across staging and production. + +With Railway, you can: + +- **Manage projects and environments**: Organize deployed services and inspect the environments attached to each project +- **Automate deployments**: Trigger new service deployments and inspect recent deployment status from workflows +- **Control runtime configuration**: Read and update environment variables for services or shared project environments +- **Connect infrastructure workflows**: Use project, service, and environment IDs from one step to drive release automation in later steps + +In Sim, the Railway integration lets your agents work with Railway's public GraphQL API directly from workflows. You can list projects, fetch project services and environments, inspect deployments, deploy a service, and manage environment variables as part of CI/CD, operations, and release processes. +{/* MANUAL-CONTENT-END */} + + +## Usage Instructions + +Integrate Railway into workflows to list projects, inspect services and environments, monitor deployments, trigger service deployments, and manage environment variables. + + + +## Tools + +### `railway_list_projects` + +List Railway projects visible to the provided token + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `workspaceId` | string | No | Workspace ID to list projects from | +| `first` | number | No | Maximum number of projects to return | +| `after` | string | No | Cursor for pagination | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `projects` | array | Railway projects | +| ↳ `id` | string | Project ID | +| ↳ `name` | string | Project name | +| ↳ `description` | string | Project description | +| ↳ `createdAt` | string | Project creation timestamp | +| ↳ `updatedAt` | string | Project update timestamp | +| `pageInfo` | object | Pagination information | +| ↳ `hasNextPage` | boolean | Whether more projects are available | +| ↳ `endCursor` | string | Cursor for the next page | +| `count` | number | Number of projects returned | + +### `railway_get_project` + +Get a Railway project with its services and environments + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `projectId` | string | Yes | Railway project ID | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `project` | object | Project with services and environments | +| ↳ `id` | string | Project ID | +| ↳ `name` | string | Project name | +| ↳ `description` | string | Project description | +| ↳ `createdAt` | string | Project creation timestamp | +| ↳ `services` | array | Project services | +| ↳ `id` | string | Service ID | +| ↳ `name` | string | Service name | +| ↳ `icon` | string | Service icon | +| ↳ `environments` | array | Project environments | +| ↳ `id` | string | Environment ID | +| ↳ `name` | string | Environment name | + +### `railway_create_project` + +Create a Railway project + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `name` | string | Yes | Project name | +| `description` | string | No | Project description | +| `workspaceId` | string | No | Workspace ID to create the project in | +| `isPublic` | boolean | No | Whether the project should be publicly visible | +| `defaultEnvironmentName` | string | No | Name for the default environment | +| `prDeploys` | boolean | No | Whether to enable pull request deploys | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `project` | object | Created project | +| ↳ `id` | string | Project ID | +| ↳ `name` | string | Project name | + +### `railway_update_project` + +Update a Railway project name or description + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `projectId` | string | Yes | Railway project ID | +| `name` | string | No | Updated project name | +| `description` | string | No | Updated project description | +| `isPublic` | boolean | No | Whether the project should be publicly visible | +| `prDeploys` | boolean | No | Whether to enable pull request deploy environments | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `project` | object | Updated project | +| ↳ `id` | string | Project ID | +| ↳ `name` | string | Project name | +| ↳ `description` | string | Project description | + +### `railway_delete_project` + +Delete a Railway project + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `projectId` | string | Yes | Railway project ID | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `success` | boolean | Whether the project was deleted | + +### `railway_transfer_project` + +Transfer a Railway project to another workspace + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `projectId` | string | Yes | Railway project ID | +| `workspaceId` | string | Yes | Destination workspace ID | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `success` | boolean | Whether the project was transferred | + +### `railway_list_project_members` + +List members for a Railway project + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `projectId` | string | Yes | Railway project ID | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `members` | array | Project members | +| ↳ `id` | string | Project membership ID | +| ↳ `role` | string | Project role | +| ↳ `user` | object | Railway user | +| ↳ `id` | string | User ID | +| ↳ `name` | string | User name | +| ↳ `email` | string | User email | +| `count` | number | Number of members returned | + +### `railway_create_environment` + +Create a Railway project environment + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `projectId` | string | Yes | Railway project ID | +| `name` | string | Yes | Environment name | +| `sourceEnvironmentId` | string | No | Environment ID to clone from | +| `ephemeral` | boolean | No | Whether the environment is ephemeral | +| `skipInitialDeploys` | boolean | No | Whether to skip initial deploys for the environment | +| `stageInitialChanges` | boolean | No | Whether to stage initial changes instead of applying them immediately | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `environment` | object | Created environment | +| ↳ `id` | string | Environment ID | +| ↳ `name` | string | Environment name | + +### `railway_delete_environment` + +Delete a Railway project environment + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `environmentId` | string | Yes | Railway environment ID | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `success` | boolean | Whether the environment was deleted | + +### `railway_list_deployments` + +List deployments for a Railway service in an environment + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `projectId` | string | Yes | Railway project ID | +| `serviceId` | string | Yes | Railway service ID | +| `environmentId` | string | Yes | Railway environment ID | +| `first` | number | No | Maximum number of deployments to return | +| `after` | string | No | Cursor for pagination | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `deployments` | array | Service deployments | +| ↳ `id` | string | Deployment ID | +| ↳ `status` | string | Deployment status | +| ↳ `createdAt` | string | Deployment creation timestamp | +| ↳ `url` | string | Deployment URL | +| ↳ `staticUrl` | string | Static deployment URL | +| `count` | number | Number of deployments returned | +| `pageInfo` | object | Pagination information | +| ↳ `hasNextPage` | boolean | Whether more deployments are available | +| ↳ `endCursor` | string | Cursor for the next page | + +### `railway_deploy_service` + +Trigger a deployment for a Railway service in an environment + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `serviceId` | string | Yes | Railway service ID | +| `environmentId` | string | Yes | Railway environment ID | +| `commitSha` | string | No | Specific Git commit SHA to deploy | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `deploymentId` | string | Created deployment ID | + +### `railway_list_variables` + +List Railway environment variables for a service or shared environment + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `projectId` | string | Yes | Railway project ID | +| `environmentId` | string | Yes | Railway environment ID | +| `serviceId` | string | No | Railway service ID. Omit for shared environment variables. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `variables` | object | Variable names and values | +| `count` | number | Number of variables returned | + +### `railway_upsert_variable` + +Create or update a Railway environment variable + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Railway API token | +| `tokenType` | string | No | Railway token type: account, workspace, project, or oauth | +| `projectId` | string | Yes | Railway project ID | +| `environmentId` | string | Yes | Railway environment ID | +| `serviceId` | string | No | Railway service ID. Omit to create or update a shared variable. | +| `name` | string | Yes | Variable name | +| `value` | string | Yes | Variable value | +| `skipDeploys` | boolean | No | Whether to skip automatic redeploys after changing the variable | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `success` | boolean | Whether the variable was created or updated | + + diff --git a/apps/sim/app/(landing)/integrations/data/icon-mapping.ts b/apps/sim/app/(landing)/integrations/data/icon-mapping.ts index 9a1c6030bc9..e4f561ea33d 100644 --- a/apps/sim/app/(landing)/integrations/data/icon-mapping.ts +++ b/apps/sim/app/(landing)/integrations/data/icon-mapping.ts @@ -128,6 +128,7 @@ import { MongoDBIcon, MySQLIcon, Neo4jIcon, + NewRelicIcon, NotionIcon, ObsidianIcon, OktaIcon, @@ -149,6 +150,7 @@ import { PulseIcon, QdrantIcon, QuiverIcon, + RailwayIcon, RDSIcon, RedditIcon, RedisIcon, @@ -333,6 +335,7 @@ export const blockTypeToIconMap: Record = { mongodb: MongoDBIcon, mysql: MySQLIcon, neo4j: Neo4jIcon, + new_relic: NewRelicIcon, notion_v2: NotionIcon, obsidian: ObsidianIcon, okta: OktaIcon, @@ -354,6 +357,7 @@ export const blockTypeToIconMap: Record = { pulse_v2: PulseIcon, qdrant: QdrantIcon, quiver: QuiverIcon, + railway: RailwayIcon, rds: RDSIcon, reddit: RedditIcon, redis: RedisIcon, diff --git a/apps/sim/app/(landing)/integrations/data/integrations.json b/apps/sim/app/(landing)/integrations/data/integrations.json index cca205b9006..17f99bcb507 100644 --- a/apps/sim/app/(landing)/integrations/data/integrations.json +++ b/apps/sim/app/(landing)/integrations/data/integrations.json @@ -4984,6 +4984,10 @@ "name": "List Calls", "description": "Retrieve call data by date range from Gong." }, + { + "name": "Create Call", + "description": "Upload call metadata to Gong and let Gong pull the media from a URL." + }, { "name": "Get Call", "description": "Retrieve detailed data for a specific call from Gong." @@ -5053,7 +5057,7 @@ "description": "Find all references to a phone number in Gong (calls, email messages, meetings, CRM data, and associated contacts)." } ], - "operationCount": 18, + "operationCount": 19, "triggers": [ { "id": "gong_webhook", @@ -6840,6 +6844,10 @@ "name": "List Workflows", "description": "List all workflows in your incident.io workspace." }, + { + "name": "Create Workflow", + "description": "Create a new workflow in incident.io." + }, { "name": "Show Workflow", "description": "Get details of a specific workflow in incident.io." @@ -6956,6 +6964,10 @@ "name": "Create Schedule Override", "description": "Create a new schedule override in incident.io" }, + { + "name": "List Escalation Paths", + "description": "List escalation paths in incident.io" + }, { "name": "Create Escalation Path", "description": "Create a new escalation path in incident.io" @@ -6973,7 +6985,7 @@ "description": "Delete an escalation path in incident.io" } ], - "operationCount": 44, + "operationCount": 46, "triggers": [], "triggerCount": 0, "authType": "api-key", @@ -9481,6 +9493,41 @@ "integrationTypes": ["databases", "analytics"], "tags": ["data-warehouse", "data-analytics"] }, + { + "type": "new_relic", + "slug": "new-relic", + "name": "New Relic", + "description": "Query observability data and record deployments in New Relic", + "longDescription": "Integrate New Relic into workflows. Run NRQL queries, search monitored entities, fetch entity details, and record deployment change events.", + "bgColor": "#000000", + "iconName": "NewRelicIcon", + "docsUrl": "https://docs.sim.ai/tools/new_relic", + "operations": [ + { + "name": "Run NRQL Query", + "description": "Run a NRQL query against a New Relic account using NerdGraph." + }, + { + "name": "Search Entities", + "description": "Search New Relic entities by name, GUID, domain type, tags, or reporting state." + }, + { + "name": "Get Entity", + "description": "Fetch a New Relic entity by GUID." + }, + { + "name": "Create Deployment Event", + "description": "Record a deployment change event in New Relic change tracking." + } + ], + "operationCount": 4, + "triggers": [], + "triggerCount": 0, + "authType": "api-key", + "category": "tools", + "integrationTypes": ["analytics", "developer-tools"], + "tags": ["monitoring", "data-analytics", "incident-management"] + }, { "type": "notion_v2", "slug": "notion", @@ -10692,6 +10739,77 @@ "integrationTypes": ["design", "ai"], "tags": ["image-generation"] }, + { + "type": "railway", + "slug": "railway", + "name": "Railway", + "description": "Manage Railway projects, deployments, and variables", + "longDescription": "Integrate Railway into workflows to list projects, inspect services and environments, monitor deployments, trigger service deployments, and manage environment variables.", + "bgColor": "#FFFFFF", + "iconName": "RailwayIcon", + "docsUrl": "https://docs.sim.ai/tools/railway", + "operations": [ + { + "name": "List Projects", + "description": "List Railway projects visible to the provided token" + }, + { + "name": "Get Project", + "description": "Get a Railway project with its services and environments" + }, + { + "name": "Create Project", + "description": "Create a Railway project" + }, + { + "name": "Update Project", + "description": "Update a Railway project name or description" + }, + { + "name": "Delete Project", + "description": "Delete a Railway project" + }, + { + "name": "Transfer Project", + "description": "Transfer a Railway project to another workspace" + }, + { + "name": "List Project Members", + "description": "List members for a Railway project" + }, + { + "name": "Create Environment", + "description": "Create a Railway project environment" + }, + { + "name": "Delete Environment", + "description": "Delete a Railway project environment" + }, + { + "name": "List Deployments", + "description": "List deployments for a Railway service in an environment" + }, + { + "name": "Deploy Service", + "description": "Trigger a deployment for a Railway service in an environment" + }, + { + "name": "List Variables", + "description": "List Railway environment variables for a service or shared environment" + }, + { + "name": "Upsert Variable", + "description": "Create or update a Railway environment variable" + } + ], + "operationCount": 13, + "triggers": [], + "triggerCount": 0, + "authType": "api-key", + "category": "tools", + "integrationTypes": ["developer-tools"], + "tags": ["cloud", "ci-cd"] + }, { "type": "reddit", "slug": "reddit", diff --git a/apps/sim/blocks/blocks/gong.ts b/apps/sim/blocks/blocks/gong.ts index ec02672ab6c..a7756b1be00 100644 --- a/apps/sim/blocks/blocks/gong.ts +++ b/apps/sim/blocks/blocks/gong.ts @@ -26,6 +26,7 @@ export const GongBlock: BlockConfig = { type: 'dropdown', options: [ { label: 'List Calls', id: 'list_calls' }, + { label: 'Create Call', id: 'create_call' }, { label: 'Get Call', id: 'get_call' }, { label: 'Get Call Transcript', id: 'get_call_transcript' }, { label: 'Get Extensive Calls', id: 'get_extensive_calls' }, @@ -47,6 +48,127 @@ export const GongBlock: BlockConfig = { value: () => 'list_calls', }, + // Create Call inputs + { + id: 'clientUniqueId', + title: 'Client Unique ID', + type: 'short-input', + placeholder: 'Unique call ID from your source system', + condition: { field: 'operation', value: 'create_call' }, + required: { field: 'operation', value: 'create_call' }, + }, + { + id: 'actualStart', + title: 'Actual Start', + type: 'short-input', + placeholder: '2018-02-17T02:30:00-08:00', + condition: { field: 'operation', value: 'create_call' }, + required: { field: 'operation', value: 'create_call' }, + wandConfig: { + enabled: true, + prompt: `Generate an ISO 8601 timestamp based on the user's description. +The timestamp should be in the format: YYYY-MM-DDTHH:MM:SSZ (UTC timezone) or include a timezone offset. + +Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes, no extra text.`, + placeholder: 'Describe the call start time...', + generationType: 'timestamp', + }, + }, + { + id: 'primaryUser', + title: 'Primary User ID', + type: 'short-input', + placeholder: 'Gong user ID for the call host', + condition: { field: 'operation', value: 'create_call' }, + required: { field: 'operation', value: 'create_call' }, + }, + { + id: 'parties', + title: 'Parties', + type: 'long-input', + placeholder: '[{"userId":"65192578128262669"}]', + condition: { field: 'operation', value: 'create_call' }, + required: { field: 'operation', value: 'create_call' }, + wandConfig: { + enabled: true, + prompt: `Generate a JSON array of Gong call parties. +Include the primary Gong user as an object with userId when provided. Parties can include name, phoneNumber, emailAddress, userId, mediaChannelId, and context. + +Return ONLY the JSON array - no explanations, no quotes, no extra text.`, + placeholder: 'Describe the call participants...', + }, + }, + { + id: 'direction', + title: 'Direction', + type: 'dropdown', + options: [ + { label: 'Inbound', id: 'Inbound' }, + { label: 'Outbound', id: 'Outbound' }, + { label: 'Conference', id: 'Conference' }, + { label: 'Unknown', id: 'Unknown' }, + ], + value: () => 'Inbound', + condition: { field: 'operation', value: 'create_call' }, + required: { field: 'operation', value: 'create_call' }, + }, + { + id: 'downloadMediaUrl', + title: 'Download Media URL', + type: 'short-input', + placeholder: 'https://example.com/call-recording.mp3', + condition: { field: 'operation', value: 'create_call' }, + required: { field: 'operation', value: 'create_call' }, + }, + { + id: 'title', + title: 'Title', + type: 'short-input', + placeholder: 'Discovery call with ACME', + condition: { field: 'operation', value: 'create_call' }, + }, + { + id: 'disposition', + title: 'Disposition', + type: 'short-input', + placeholder: 'Connected', + condition: { field: 'operation', value: 'create_call' }, + mode: 'advanced', + }, + { + id: 'purpose', + title: 'Purpose', + type: 'short-input', + placeholder: 'Demo Call', + condition: { field: 'operation', value: 'create_call' }, + mode: 'advanced', + }, + { + id: 'context', + title: 'Context', + type: 'long-input', + placeholder: + '[{"system":"Salesforce","objects":[{"objectType":"Opportunity","objectId":"006..."}]}]', + condition: { field: 'operation', value: 'create_call' }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: `Generate a JSON array of Gong CRM context objects for the call. +Use objects with system and objects fields when external CRM records are provided. + +Return ONLY the JSON array - no explanations, no quotes, no extra text.`, + placeholder: 'Describe CRM records to associate...', + }, + }, + { + id: 'callProviderCode', + title: 'Call Provider Code', + type: 'short-input', + placeholder: 'zoom', + condition: { field: 'operation', value: 'create_call' }, + mode: 'advanced', + }, + // List Calls inputs { id: 'fromDateTime', @@ -82,7 +204,6 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes field: 'operation', value: ['list_calls'], }, - mode: 'advanced', wandConfig: { enabled: true, prompt: `Generate an ISO 8601 timestamp based on the user's description. @@ -349,6 +470,7 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n field: 'operation', value: [ 'list_calls', + 'create_call', 'get_call_transcript', 'get_extensive_calls', 'list_library_folders', @@ -492,6 +614,7 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes tools: { access: [ 'gong_list_calls', + 'gong_create_call', 'gong_get_call', 'gong_get_call_transcript', 'gong_get_extensive_calls', @@ -534,6 +657,17 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes operation: { type: 'string', description: 'Operation to perform' }, accessKey: { type: 'string', description: 'Gong API Access Key' }, accessKeySecret: { type: 'string', description: 'Gong API Access Key Secret' }, + clientUniqueId: { type: 'string', description: 'Unique source-system call ID' }, + actualStart: { type: 'string', description: 'Actual call start date/time' }, + primaryUser: { type: 'string', description: 'Gong user ID for the call host' }, + parties: { type: 'json', description: 'Call party array' }, + direction: { type: 'string', description: 'Call direction' }, + downloadMediaUrl: { type: 'string', description: 'URL where Gong can download call media' }, + title: { type: 'string', description: 'Call title' }, + disposition: { type: 'string', description: 'Call disposition' }, + purpose: { type: 'string', description: 'Call purpose' }, + context: { type: 'json', description: 'Call CRM context array' }, + callProviderCode: { type: 'string', description: 'Provider conferencing or telephony code' }, fromDateTime: { type: 'string', description: 'Start date/time in ISO-8601 format (list calls)', @@ -569,7 +703,8 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes outputs: { response: { type: 'json', - description: 'Gong API response data', + description: + 'Gong API response data. Shape depends on the selected operation and can include callId, requestId, url, calls, callTranscripts, users, usersActivity, peopleInteractionStats, answeredScorecards, folders, scorecards, trackers, workspaces, flows, coachingData, emails, meetings, customerData, and pagination cursor fields.', }, }, triggers: { diff --git a/apps/sim/blocks/blocks/incidentio.ts b/apps/sim/blocks/blocks/incidentio.ts index ad8c19949d6..f7bcca49dac 100644 --- a/apps/sim/blocks/blocks/incidentio.ts +++ b/apps/sim/blocks/blocks/incidentio.ts @@ -38,6 +38,7 @@ export const IncidentioBlock: BlockConfig = { { label: 'Show User', id: 'incidentio_users_show' }, // Workflows { label: 'List Workflows', id: 'incidentio_workflows_list' }, + { label: 'Create Workflow', id: 'incidentio_workflows_create' }, { label: 'Show Workflow', id: 'incidentio_workflows_show' }, { label: 'Update Workflow', id: 'incidentio_workflows_update' }, { label: 'Delete Workflow', id: 'incidentio_workflows_delete' }, @@ -77,6 +78,7 @@ export const IncidentioBlock: BlockConfig = { // Schedule Overrides { label: 'Create Schedule Override', id: 'incidentio_schedule_overrides_create' }, // Escalation Paths + { label: 'List Escalation Paths', id: 'incidentio_escalation_paths_list' }, { label: 'Create Escalation Path', id: 'incidentio_escalation_paths_create' }, { label: 'Show Escalation Path', id: 'incidentio_escalation_paths_show' }, { label: 'Update Escalation Path', id: 'incidentio_escalation_paths_update' }, @@ -95,12 +97,13 @@ export const IncidentioBlock: BlockConfig = { value: [ 'incidentio_incidents_list', 'incidentio_users_list', - 'incidentio_workflows_list', 'incidentio_schedules_list', + 'incidentio_escalations_list', 'incidentio_incident_updates_list', - 'incidentio_schedule_entries_list', + 'incidentio_escalation_paths_list', ], }, + mode: 'advanced', }, // Pagination 'after' field for list operations { @@ -113,32 +116,39 @@ export const IncidentioBlock: BlockConfig = { value: [ 'incidentio_incidents_list', 'incidentio_users_list', - 'incidentio_workflows_list', 'incidentio_schedules_list', + 'incidentio_escalations_list', 'incidentio_incident_updates_list', - 'incidentio_schedule_entries_list', + 'incidentio_escalation_paths_list', ], }, + mode: 'advanced', }, - // Incidents Create operation inputs { - id: 'name', - title: 'Incident Name', - type: 'short-input', - placeholder: 'Enter incident name...', - condition: { field: 'operation', value: 'incidentio_incidents_create' }, - wandConfig: { - enabled: true, - prompt: `Generate a concise, descriptive incident name based on the user's description. -The incident name should: -- Be clear and descriptive -- Indicate the nature of the issue -- Be suitable for incident tracking and communication - -Return ONLY the incident name - no explanations.`, - placeholder: 'Describe the incident (e.g., "database outage", "API latency issues")...', - }, + id: 'sort_by', + title: 'Sort By', + type: 'dropdown', + options: [ + { label: 'Created At: Newest First', id: 'created_at_newest_first' }, + { label: 'Created At: Oldest First', id: 'created_at_oldest_first' }, + ], + value: () => 'created_at_newest_first', + condition: { field: 'operation', value: 'incidentio_incidents_list' }, + mode: 'advanced', }, + { + id: 'filter_mode', + title: 'Filter Mode', + type: 'dropdown', + options: [ + { label: 'All', id: 'all' }, + { label: 'Any', id: 'any' }, + ], + value: () => 'all', + condition: { field: 'operation', value: 'incidentio_incidents_list' }, + mode: 'advanced', + }, + // Incidents Create operation inputs { id: 'summary', title: 'Summary', @@ -165,15 +175,11 @@ Return ONLY the summary text - no explanations.`, title: 'Severity ID', type: 'short-input', placeholder: 'Enter severity ID...', - condition: { field: 'operation', value: 'incidentio_incidents_create' }, - required: true, - }, - { - id: 'severity_id', - title: 'Severity ID', - type: 'short-input', - placeholder: 'Enter severity ID...', - condition: { field: 'operation', value: 'incidentio_incidents_update' }, + condition: { + field: 'operation', + value: ['incidentio_incidents_create', 'incidentio_incidents_update'], + }, + required: { field: 'operation', value: 'incidentio_incidents_create' }, }, { id: 'incident_type_id', @@ -215,14 +221,6 @@ Return ONLY the summary text - no explanations.`, condition: { field: 'operation', value: 'incidentio_incidents_create' }, required: true, }, - { - id: 'idempotency_key', - title: 'Idempotency Key', - type: 'short-input', - placeholder: 'Enter unique key (e.g., UUID)', - condition: { field: 'operation', value: 'incidentio_incidents_create' }, - required: true, - }, // Show/Update Incident inputs { id: 'id', @@ -266,26 +264,44 @@ Return ONLY the summary text - no explanations.`, condition: { field: 'operation', value: [ + 'incidentio_incidents_create', + 'incidentio_incidents_update', + 'incidentio_workflows_create', + 'incidentio_workflows_update', 'incidentio_schedules_create', + 'incidentio_schedules_update', 'incidentio_custom_fields_create', 'incidentio_custom_fields_update', 'incidentio_incident_roles_create', 'incidentio_incident_roles_update', 'incidentio_escalation_paths_create', + 'incidentio_escalation_paths_update', ], }, - required: true, - }, - { - id: 'name', - title: 'Name', - type: 'short-input', - placeholder: 'Enter name (optional for update)...', - condition: { + required: { field: 'operation', - value: 'incidentio_escalation_paths_update', + value: [ + 'incidentio_workflows_create', + 'incidentio_workflows_update', + 'incidentio_schedules_create', + 'incidentio_custom_fields_create', + 'incidentio_incident_roles_create', + 'incidentio_incident_roles_update', + 'incidentio_escalation_paths_create', + 'incidentio_escalation_paths_update', + ], + }, + wandConfig: { + enabled: true, + prompt: `Generate a concise resource name based on the user's description. +The name should: +- Be clear and descriptive +- Indicate the resource purpose +- Be suitable for incident.io records + +Return ONLY the name - no explanations.`, + placeholder: 'Describe the name you want to use...', }, - required: false, }, // Escalations inputs { @@ -293,8 +309,14 @@ Return ONLY the summary text - no explanations.`, title: 'Idempotency Key', type: 'short-input', placeholder: 'Enter unique key (e.g., UUID)...', - condition: { field: 'operation', value: 'incidentio_escalations_create' }, - required: true, + condition: { + field: 'operation', + value: ['incidentio_incidents_create', 'incidentio_escalations_create'], + }, + required: { + field: 'operation', + value: ['incidentio_incidents_create', 'incidentio_escalations_create'], + }, }, { id: 'title', @@ -330,30 +352,37 @@ Return ONLY the title - no explanations.`, placeholder: 'Enter user IDs, comma-separated (required if no path ID)...', condition: { field: 'operation', value: 'incidentio_escalations_create' }, }, + // Actions List inputs { - id: 'name', - title: 'Name', + id: 'incident_id', + title: 'Incident ID', type: 'short-input', - placeholder: 'Enter name...', + placeholder: 'Filter by incident ID...', condition: { field: 'operation', value: [ - 'incidentio_incidents_update', - 'incidentio_workflows_update', - 'incidentio_schedules_update', + 'incidentio_actions_list', + 'incidentio_follow_ups_list', + 'incidentio_incident_updates_list', ], }, }, - // Actions List inputs { - id: 'incident_id', - title: 'Incident ID', - type: 'short-input', - placeholder: 'Filter by incident ID...', + id: 'incident_mode', + title: 'Incident Mode', + type: 'dropdown', + options: [ + { label: 'Standard', id: 'standard' }, + { label: 'Retrospective', id: 'retrospective' }, + { label: 'Test', id: 'test' }, + { label: 'Tutorial', id: 'tutorial' }, + { label: 'Stream', id: 'stream' }, + ], condition: { field: 'operation', value: ['incidentio_actions_list', 'incidentio_follow_ups_list'], }, + mode: 'advanced', }, // Workflows inputs { @@ -361,7 +390,18 @@ Return ONLY the title - no explanations.`, title: 'Folder', type: 'short-input', placeholder: 'Enter folder name...', - condition: { field: 'operation', value: 'incidentio_workflows_update' }, + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + }, + { + id: 'skip_step_upgrades', + title: 'Skip Step Upgrades', + type: 'switch', + value: () => 'false', + condition: { field: 'operation', value: 'incidentio_workflows_show' }, + mode: 'advanced', }, { id: 'state', @@ -373,7 +413,172 @@ Return ONLY the title - no explanations.`, { label: 'Disabled', id: 'disabled' }, ], value: () => 'active', - condition: { field: 'operation', value: 'incidentio_workflows_update' }, + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + }, + { + id: 'trigger', + title: 'Trigger', + type: 'short-input', + placeholder: 'incident.updated', + condition: { field: 'operation', value: 'incidentio_workflows_create' }, + mode: 'advanced', + }, + { + id: 'runs_on_incidents', + title: 'Runs On Incidents', + type: 'dropdown', + options: [ + { label: 'Newly Created', id: 'newly_created' }, + { label: 'Newly Created and Active', id: 'newly_created_and_active' }, + { label: 'Active', id: 'active' }, + { label: 'All', id: 'all' }, + ], + value: () => 'newly_created', + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + mode: 'advanced', + required: { field: 'operation', value: 'incidentio_workflows_update' }, + }, + { + id: 'runs_on_incident_modes', + title: 'Incident Modes', + type: 'short-input', + placeholder: '["standard"]', + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate a JSON array of incident.io incident modes, such as ["standard"] or ["standard","retrospective"]. Return ONLY the JSON array - no explanations, no extra text.', + placeholder: 'Describe which incident modes should run the workflow...', + generationType: 'json-object', + }, + }, + { + id: 'steps', + title: 'Steps', + type: 'long-input', + placeholder: '[{"label":"Notify team","name":"slack.post_message"}]', + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + mode: 'advanced', + required: { field: 'operation', value: 'incidentio_workflows_update' }, + wandConfig: { + enabled: true, + prompt: + 'Generate a JSON array of incident.io workflow steps. Return ONLY the JSON array - no explanations, no extra text.', + placeholder: 'Describe the workflow steps...', + generationType: 'json-object', + }, + }, + { + id: 'condition_groups', + title: 'Condition Groups', + type: 'long-input', + placeholder: '[]', + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + mode: 'advanced', + required: { field: 'operation', value: 'incidentio_workflows_update' }, + wandConfig: { + enabled: true, + prompt: + 'Generate a JSON array of incident.io workflow condition groups. Return ONLY the JSON array - no explanations, no extra text.', + placeholder: 'Describe the workflow conditions...', + generationType: 'json-object', + }, + }, + { + id: 'expressions', + title: 'Expressions', + type: 'long-input', + placeholder: '[]', + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + mode: 'advanced', + required: { field: 'operation', value: 'incidentio_workflows_update' }, + wandConfig: { + enabled: true, + prompt: + 'Generate a JSON array of incident.io workflow expressions. Return ONLY the JSON array - no explanations, no extra text.', + placeholder: 'Describe any workflow expressions...', + generationType: 'json-object', + }, + }, + { + id: 'once_for', + title: 'Once For', + type: 'short-input', + placeholder: '[]', + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + mode: 'advanced', + required: { field: 'operation', value: 'incidentio_workflows_update' }, + wandConfig: { + enabled: true, + prompt: + 'Generate a JSON array of fields that should make an incident.io workflow run only once for each unique combination. Return ONLY the JSON array - no explanations, no extra text.', + placeholder: 'Describe what should make the workflow run once...', + generationType: 'json-object', + }, + }, + { + id: 'delay', + title: 'Delay', + type: 'long-input', + placeholder: '{"for_seconds":60,"conditions_apply_over_delay":false}', + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate a JSON object for an incident.io workflow delay. Return ONLY the JSON object - no explanations, no extra text.', + placeholder: 'Describe the workflow delay...', + generationType: 'json-object', + }, + }, + { + id: 'include_private_incidents', + title: 'Include Private Incidents', + type: 'switch', + value: () => 'true', + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + mode: 'advanced', + required: { field: 'operation', value: 'incidentio_workflows_update' }, + }, + { + id: 'continue_on_step_error', + title: 'Continue On Step Error', + type: 'switch', + value: () => 'false', + condition: { + field: 'operation', + value: ['incidentio_workflows_create', 'incidentio_workflows_update'], + }, + mode: 'advanced', + required: { field: 'operation', value: 'incidentio_workflows_update' }, }, // Schedules inputs { @@ -406,8 +611,11 @@ Return ONLY the title - no explanations.`, { label: 'UTC', id: 'UTC' }, ], value: () => 'UTC', - condition: { field: 'operation', value: 'incidentio_schedules_create' }, - required: true, + condition: { + field: 'operation', + value: ['incidentio_schedules_create', 'incidentio_schedules_update'], + }, + required: { field: 'operation', value: 'incidentio_schedules_create' }, }, { id: 'config', @@ -438,38 +646,6 @@ Return ONLY the JSON object - no explanations or markdown formatting.`, generationType: 'json-object', }, }, - { - id: 'timezone', - title: 'Timezone', - type: 'dropdown', - options: [ - { label: 'America/New_York (Eastern)', id: 'America/New_York' }, - { label: 'America/Chicago (Central)', id: 'America/Chicago' }, - { label: 'America/Denver (Mountain)', id: 'America/Denver' }, - { label: 'America/Los_Angeles (Pacific)', id: 'America/Los_Angeles' }, - { label: 'America/Phoenix (Arizona)', id: 'America/Phoenix' }, - { label: 'America/Anchorage (Alaska)', id: 'America/Anchorage' }, - { label: 'Pacific/Honolulu (Hawaii)', id: 'Pacific/Honolulu' }, - { label: 'Europe/London (UK)', id: 'Europe/London' }, - { label: 'Europe/Paris (Central Europe)', id: 'Europe/Paris' }, - { label: 'Europe/Berlin (Germany)', id: 'Europe/Berlin' }, - { label: 'Europe/Dublin (Ireland)', id: 'Europe/Dublin' }, - { label: 'Europe/Amsterdam (Netherlands)', id: 'Europe/Amsterdam' }, - { label: 'Asia/Tokyo (Japan)', id: 'Asia/Tokyo' }, - { label: 'Asia/Singapore', id: 'Asia/Singapore' }, - { label: 'Asia/Hong_Kong', id: 'Asia/Hong_Kong' }, - { label: 'Asia/Shanghai (China)', id: 'Asia/Shanghai' }, - { label: 'Asia/Seoul (South Korea)', id: 'Asia/Seoul' }, - { label: 'Asia/Dubai (UAE)', id: 'Asia/Dubai' }, - { label: 'Asia/Kolkata (India)', id: 'Asia/Kolkata' }, - { label: 'Australia/Sydney', id: 'Australia/Sydney' }, - { label: 'Australia/Melbourne', id: 'Australia/Melbourne' }, - { label: 'Pacific/Auckland (New Zealand)', id: 'Pacific/Auckland' }, - { label: 'UTC', id: 'UTC' }, - ], - value: () => 'UTC', - condition: { field: 'operation', value: 'incidentio_schedules_update' }, - }, // Custom Fields inputs { id: 'description', @@ -478,7 +654,12 @@ Return ONLY the JSON object - no explanations or markdown formatting.`, placeholder: 'Enter description...', condition: { field: 'operation', - value: ['incidentio_custom_fields_create', 'incidentio_custom_fields_update'], + value: [ + 'incidentio_custom_fields_create', + 'incidentio_custom_fields_update', + 'incidentio_incident_roles_create', + 'incidentio_incident_roles_update', + ], }, required: true, wandConfig: { @@ -510,29 +691,6 @@ Return ONLY the description text - no explanations.`, required: true, }, // Incident Roles inputs - { - id: 'description', - title: 'Description', - type: 'long-input', - placeholder: 'Enter description...', - condition: { - field: 'operation', - value: ['incidentio_incident_roles_create', 'incidentio_incident_roles_update'], - }, - required: true, - wandConfig: { - enabled: true, - prompt: `Generate a description for an incident role based on the user's description. -The description should: -- Explain the role's responsibilities -- Clarify when this role is needed -- Be suitable for incident response documentation - -Return ONLY the description text - no explanations.`, - placeholder: - 'Describe the role (e.g., "coordinates communication with stakeholders", "leads technical investigation")...', - }, - }, { id: 'instructions', title: 'Instructions', @@ -568,14 +726,6 @@ Return ONLY the instructions text - no explanations.`, required: true, }, // Incident Updates inputs - { - id: 'incident_id', - title: 'Incident ID', - type: 'short-input', - placeholder: 'Enter incident ID (optional - leave blank for all incidents)...', - condition: { field: 'operation', value: 'incidentio_incident_updates_list' }, - required: false, - }, // Schedule Entries inputs { id: 'schedule_id', @@ -637,6 +787,14 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' }, required: true, }, + { + id: 'layer_id', + title: 'Layer ID', + type: 'short-input', + placeholder: 'Enter layer ID...', + condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' }, + required: true, + }, { id: 'user_id', title: 'User ID', @@ -649,16 +807,22 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, id: 'user_email', title: 'User Email', type: 'short-input', - placeholder: 'Enter user email (provide one of: user_id, user_email, or user_slack_id)...', - condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' }, + placeholder: 'Enter user email...', + condition: { + field: 'operation', + value: ['incidentio_schedule_overrides_create', 'incidentio_users_list'], + }, required: false, }, { id: 'user_slack_id', title: 'User Slack ID', type: 'short-input', - placeholder: 'Enter user Slack ID (provide one of: user_id, user_email, or user_slack_id)...', - condition: { field: 'operation', value: 'incidentio_schedule_overrides_create' }, + placeholder: 'Enter user Slack ID...', + condition: { + field: 'operation', + value: ['incidentio_schedule_overrides_create', 'incidentio_users_list'], + }, required: false, }, { @@ -712,7 +876,7 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, 'JSON array of escalation levels: [{"targets": [{"id": "...", "type": "...", "urgency": "..."}], "time_to_ack_seconds": 300}]', condition: { field: 'operation', - value: 'incidentio_escalation_paths_create', + value: ['incidentio_escalation_paths_create', 'incidentio_escalation_paths_update'], }, required: true, wandConfig: { @@ -734,18 +898,6 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, generationType: 'json-object', }, }, - { - id: 'path', - title: 'Path Configuration', - type: 'long-input', - placeholder: - 'JSON array of escalation levels (optional for update): [{"targets": [{"id": "...", "type": "...", "urgency": "..."}], "time_to_ack_seconds": 300}]', - condition: { - field: 'operation', - value: 'incidentio_escalation_paths_update', - }, - required: false, - }, { id: 'working_hours', title: 'Working Hours', @@ -792,6 +944,7 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, 'incidentio_users_list', 'incidentio_users_show', 'incidentio_workflows_list', + 'incidentio_workflows_create', 'incidentio_workflows_show', 'incidentio_workflows_update', 'incidentio_workflows_delete', @@ -821,6 +974,7 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, 'incidentio_incident_updates_list', 'incidentio_schedule_entries_list', 'incidentio_schedule_overrides_create', + 'incidentio_escalation_paths_list', 'incidentio_escalation_paths_create', 'incidentio_escalation_paths_show', 'incidentio_escalation_paths_update', @@ -851,6 +1005,8 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, return 'incidentio_users_show' case 'incidentio_workflows_list': return 'incidentio_workflows_list' + case 'incidentio_workflows_create': + return 'incidentio_workflows_create' case 'incidentio_workflows_show': return 'incidentio_workflows_show' case 'incidentio_workflows_update': @@ -909,6 +1065,8 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, return 'incidentio_schedule_entries_list' case 'incidentio_schedule_overrides_create': return 'incidentio_schedule_overrides_create' + case 'incidentio_escalation_paths_list': + return 'incidentio_escalation_paths_list' case 'incidentio_escalation_paths_create': return 'incidentio_escalation_paths_create' case 'incidentio_escalation_paths_show': @@ -923,9 +1081,23 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, }, params: (params) => { const result: Record = {} + const toBoolean = (value: unknown) => value === true || value === 'true' if (params.page_size) result.page_size = Number(params.page_size) if (params.notify_incident_channel !== undefined) { - result.notify_incident_channel = params.notify_incident_channel === 'true' + result.notify_incident_channel = toBoolean(params.notify_incident_channel) + } + if (params.include_private_incidents !== undefined) { + result.include_private_incidents = toBoolean(params.include_private_incidents) + } + if (params.continue_on_step_error !== undefined) { + result.continue_on_step_error = toBoolean(params.continue_on_step_error) + } + if (params.skip_step_upgrades !== undefined) { + result.skip_step_upgrades = toBoolean(params.skip_step_upgrades) + } + if (params.operation === 'incidentio_users_list') { + if (params.user_email) result.email = params.user_email + if (params.user_slack_id) result.slack_user_id = params.user_slack_id } return result }, @@ -939,6 +1111,8 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, name: { type: 'string', description: 'Resource name' }, page_size: { type: 'number', description: 'Number of results per page' }, after: { type: 'string', description: 'Pagination cursor' }, + sort_by: { type: 'string', description: 'Incident sort order' }, + filter_mode: { type: 'string', description: 'Incident filter combination mode' }, // Incident fields summary: { type: 'string', description: 'Incident summary' }, severity_id: { type: 'string', description: 'Severity ID' }, @@ -946,6 +1120,7 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, incident_status_id: { type: 'string', description: 'Incident status ID' }, visibility: { type: 'string', description: 'Incident visibility' }, incident_id: { type: 'string', description: 'Incident ID for filtering' }, + incident_mode: { type: 'string', description: 'Incident mode filter' }, notify_incident_channel: { type: 'boolean', description: 'Whether to notify the incident channel', @@ -953,6 +1128,29 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, // Workflow fields folder: { type: 'string', description: 'Workflow folder' }, state: { type: 'string', description: 'Workflow state' }, + trigger: { type: 'string', description: 'Workflow trigger type' }, + skip_step_upgrades: { type: 'boolean', description: 'Whether to skip workflow step upgrades' }, + steps: { type: 'string', description: 'Workflow steps JSON' }, + condition_groups: { type: 'string', description: 'Workflow condition groups JSON' }, + runs_on_incidents: { + type: 'string', + description: 'Incident lifecycle filter for workflow runs', + }, + runs_on_incident_modes: { + type: 'string', + description: 'Incident modes JSON for workflow runs', + }, + include_private_incidents: { + type: 'boolean', + description: 'Whether the workflow includes private incidents', + }, + continue_on_step_error: { + type: 'boolean', + description: 'Whether workflow execution continues after a step error', + }, + once_for: { type: 'string', description: 'Workflow run-once fields JSON' }, + expressions: { type: 'string', description: 'Workflow expressions JSON' }, + delay: { type: 'string', description: 'Workflow delay JSON' }, // Schedule fields timezone: { type: 'string', description: 'Schedule timezone' }, // Custom field fields @@ -964,9 +1162,12 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, required: { type: 'boolean', description: 'Whether the role is required' }, // Schedule Entries/Overrides fields schedule_id: { type: 'string', description: 'Schedule ID' }, - from: { type: 'string', description: 'Start date/time for filtering' }, - to: { type: 'string', description: 'End date/time for filtering' }, + entry_window_start: { type: 'string', description: 'Schedule entry window start' }, + entry_window_end: { type: 'string', description: 'Schedule entry window end' }, + rotation_id: { type: 'string', description: 'Schedule rotation ID' }, user_id: { type: 'string', description: 'User ID' }, + user_email: { type: 'string', description: 'User email' }, + user_slack_id: { type: 'string', description: 'User Slack ID' }, start_at: { type: 'string', description: 'Start date/time' }, end_at: { type: 'string', description: 'End date/time' }, layer_id: { type: 'string', description: 'Schedule layer ID' }, @@ -990,6 +1191,7 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, // Workflows workflows: { type: 'json', description: 'List of workflows' }, workflow: { type: 'json', description: 'Workflow details' }, + management_meta: { type: 'json', description: 'Workflow management metadata' }, // Schedules schedules: { type: 'json', description: 'List of schedules' }, schedule: { type: 'json', description: 'Schedule details' }, @@ -1016,6 +1218,7 @@ Return ONLY the JSON array - no explanations or markdown formatting.`, // Schedule Overrides schedule_override: { type: 'json', description: 'Schedule override details' }, // Escalation Paths + escalation_paths: { type: 'json', description: 'List of escalation paths' }, escalation_path: { type: 'json', description: 'Escalation path details' }, // General message: { type: 'string', description: 'Operation result message' }, diff --git a/apps/sim/blocks/blocks/new_relic.ts b/apps/sim/blocks/blocks/new_relic.ts new file mode 100644 index 00000000000..d9001b0df26 --- /dev/null +++ b/apps/sim/blocks/blocks/new_relic.ts @@ -0,0 +1,355 @@ +import { NewRelicIcon } from '@/components/icons' +import type { BlockConfig } from '@/blocks/types' +import { AuthMode, IntegrationType } from '@/blocks/types' +import type { NewRelicCustomAttributes, NewRelicResponse } from '@/tools/new_relic/types' + +function parseCustomAttributes(value: unknown): NewRelicCustomAttributes | undefined { + if (!value) return undefined + if (typeof value !== 'string') return value as NewRelicCustomAttributes + + const trimmed = value.trim() + if (!trimmed) return undefined + + try { + return JSON.parse(trimmed) as NewRelicCustomAttributes + } catch (error) { + throw new Error( + `Invalid JSON for customAttributes: ${error instanceof Error ? error.message : String(error)}` + ) + } +} + +export const NewRelicBlock: BlockConfig = { + type: 'new_relic', + name: 'New Relic', + description: 'Query observability data and record deployments in New Relic', + longDescription: + 'Integrate New Relic into workflows. Run NRQL queries, search monitored entities, fetch entity details, and record deployment change events.', + docsLink: 'https://docs.sim.ai/tools/new_relic', + category: 'tools', + authMode: AuthMode.ApiKey, + integrationType: IntegrationType.Analytics, + tags: ['monitoring', 'data-analytics', 'incident-management'], + bgColor: '#000000', + icon: NewRelicIcon, + subBlocks: [ + { + id: 'operation', + title: 'Operation', + type: 'dropdown', + options: [ + { label: 'Run NRQL Query', id: 'new_relic_nrql_query' }, + { label: 'Search Entities', id: 'new_relic_search_entities' }, + { label: 'Get Entity', id: 'new_relic_get_entity' }, + { label: 'Create Deployment Event', id: 'new_relic_create_deployment_event' }, + ], + value: () => 'new_relic_nrql_query', + }, + { + id: 'apiKey', + title: 'User API Key', + type: 'short-input', + placeholder: 'NRAK-...', + password: true, + required: true, + }, + { + id: 'region', + title: 'Region', + type: 'dropdown', + options: [ + { label: 'US', id: 'us' }, + { label: 'EU', id: 'eu' }, + ], + value: () => 'us', + }, + { + id: 'accountId', + title: 'Account ID', + type: 'short-input', + placeholder: '1234567', + condition: { field: 'operation', value: 'new_relic_nrql_query' }, + required: true, + }, + { + id: 'nrql', + title: 'NRQL Query', + type: 'code', + placeholder: 'SELECT count(*) FROM Transaction SINCE 1 hour ago', + condition: { field: 'operation', value: 'new_relic_nrql_query' }, + required: true, + wandConfig: { + enabled: true, + prompt: `Generate a New Relic NRQL query based on the user's request. + +Return ONLY the NRQL query - no explanations, no extra text.`, + placeholder: 'Describe the New Relic data you want to query...', + }, + }, + { + id: 'timeout', + title: 'Timeout (Seconds)', + type: 'short-input', + placeholder: '70', + condition: { field: 'operation', value: 'new_relic_nrql_query' }, + mode: 'advanced', + }, + { + id: 'query', + title: 'Entity Search Query', + type: 'long-input', + placeholder: 'name like "api" and domainType = "APM-APPLICATION"', + condition: { field: 'operation', value: 'new_relic_search_entities' }, + required: true, + wandConfig: { + enabled: true, + prompt: `Generate a New Relic entity search query based on the user's request. + +Examples: +name like "api" +domainType = "APM-APPLICATION" +reporting is false and lastReportingChangeAt > 1651708800000 + +Return ONLY the entity search query - no explanations, no extra text.`, + placeholder: 'Describe the entities you want to find...', + }, + }, + { + id: 'cursor', + title: 'Cursor', + type: 'short-input', + placeholder: 'Next cursor from prior search', + condition: { field: 'operation', value: 'new_relic_search_entities' }, + mode: 'advanced', + }, + { + id: 'guid', + title: 'Entity GUID', + type: 'short-input', + placeholder: 'Entity GUID', + condition: { field: 'operation', value: 'new_relic_get_entity' }, + required: true, + }, + { + id: 'entityGuid', + title: 'Entity GUID', + type: 'short-input', + placeholder: 'Entity GUID', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + required: true, + }, + { + id: 'version', + title: 'Version', + type: 'short-input', + placeholder: '1.2.3 or commit SHA', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + required: true, + }, + { + id: 'shortDescription', + title: 'Short Description', + type: 'short-input', + placeholder: 'Deploy version 1.2.3', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + wandConfig: { + enabled: true, + prompt: `Generate a concise New Relic deployment change description based on the user's request. + +Return ONLY the description text - no explanations, no extra text.`, + placeholder: 'Describe the deployment...', + }, + }, + { + id: 'description', + title: 'Description', + type: 'long-input', + placeholder: 'Deployment details', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + mode: 'advanced', + }, + { + id: 'changelog', + title: 'Changelog', + type: 'long-input', + placeholder: 'Release notes, summary, or changelog URL', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + mode: 'advanced', + }, + { + id: 'commit', + title: 'Commit', + type: 'short-input', + placeholder: 'Commit SHA or build identifier', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + mode: 'advanced', + }, + { + id: 'deepLink', + title: 'Deep Link', + type: 'short-input', + placeholder: 'https://github.com/org/repo/actions/runs/123', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + mode: 'advanced', + }, + { + id: 'user', + title: 'User', + type: 'short-input', + placeholder: 'deploy-bot@example.com', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + mode: 'advanced', + }, + { + id: 'groupId', + title: 'Group ID', + type: 'short-input', + placeholder: 'release-2026-05-19', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + mode: 'advanced', + }, + { + id: 'customAttributes', + title: 'Custom Attributes', + type: 'code', + language: 'json', + placeholder: '{"isProduction": true, "region": "us-east-1", "instances": 2}', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: `Generate a JSON object of New Relic change tracking custom attributes based on the user's request. +Use only string, number, and boolean values. + +Return ONLY the JSON object - no explanations, no extra text.`, + placeholder: 'Describe the custom metadata to attach...', + generationType: 'json-object', + }, + }, + { + id: 'deploymentType', + title: 'Deployment Type', + type: 'dropdown', + options: [ + { label: 'Basic', id: 'basic' }, + { label: 'Blue Green', id: 'blue green' }, + { label: 'Canary', id: 'canary' }, + { label: 'Rolling', id: 'rolling' }, + { label: 'Shadow', id: 'shadow' }, + ], + value: () => 'basic', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + mode: 'advanced', + }, + { + id: 'timestamp', + title: 'Timestamp (Epoch ms)', + type: 'short-input', + placeholder: '1767225600000', + condition: { field: 'operation', value: 'new_relic_create_deployment_event' }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: `Generate an epoch millisecond timestamp based on the user's request. + +Return ONLY the numeric timestamp - no explanations, no extra text.`, + placeholder: 'Describe the deployment time...', + generationType: 'timestamp', + }, + }, + ], + tools: { + access: [ + 'new_relic_nrql_query', + 'new_relic_search_entities', + 'new_relic_get_entity', + 'new_relic_create_deployment_event', + ], + config: { + tool: (params) => String(params.operation || 'new_relic_nrql_query'), + params: (params) => { + const baseParams = { + apiKey: params.apiKey, + region: params.region || 'us', + } + + switch (params.operation) { + case 'new_relic_nrql_query': + return { + ...baseParams, + accountId: Number(params.accountId), + nrql: params.nrql, + timeout: params.timeout ? Number(params.timeout) : undefined, + } + + case 'new_relic_search_entities': + return { + ...baseParams, + query: params.query, + cursor: params.cursor, + } + + case 'new_relic_get_entity': + return { + ...baseParams, + guid: params.guid, + } + + case 'new_relic_create_deployment_event': + return { + ...baseParams, + entityGuid: params.entityGuid, + version: params.version, + shortDescription: params.shortDescription, + description: params.description, + changelog: params.changelog, + commit: params.commit, + deepLink: params.deepLink, + user: params.user, + groupId: params.groupId, + customAttributes: parseCustomAttributes(params.customAttributes), + deploymentType: params.deploymentType, + timestamp: params.timestamp ? Number(params.timestamp) : undefined, + } + + default: + return baseParams + } + }, + }, + }, + inputs: { + operation: { type: 'string', description: 'Operation to perform' }, + apiKey: { type: 'string', description: 'New Relic user API key' }, + region: { type: 'string', description: 'New Relic data center region' }, + accountId: { type: 'number', description: 'New Relic account ID' }, + nrql: { type: 'string', description: 'NRQL query' }, + timeout: { type: 'number', description: 'Optional NRQL timeout in seconds' }, + query: { type: 'string', description: 'Entity search query' }, + cursor: { type: 'string', description: 'Entity search pagination cursor' }, + guid: { type: 'string', description: 'Entity GUID' }, + entityGuid: { type: 'string', description: 'Deployment entity GUID' }, + version: { type: 'string', description: 'Deployment version' }, + shortDescription: { type: 'string', description: 'Short deployment description' }, + description: { type: 'string', description: 'Deployment description' }, + changelog: { type: 'string', description: 'Deployment changelog text or URL' }, + commit: { type: 'string', description: 'Deployment commit SHA or identifier' }, + deepLink: { type: 'string', description: 'Deployment, build, or release URL' }, + user: { type: 'string', description: 'Deployment user' }, + groupId: { type: 'string', description: 'Deployment group ID' }, + customAttributes: { type: 'json', description: 'Custom change event metadata' }, + deploymentType: { type: 'string', description: 'Deployment type' }, + timestamp: { type: 'number', description: 'Deployment timestamp in epoch milliseconds' }, + }, + outputs: { + results: { type: 'json', description: 'NRQL result rows' }, + resultCount: { type: 'number', description: 'Number of NRQL result rows' }, + count: { type: 'number', description: 'Number of matching entities' }, + query: { type: 'string', description: 'Entity search query New Relic executed' }, + entities: { type: 'json', description: 'Matching New Relic entities (guid, name, entityType)' }, + nextCursor: { type: 'string', description: 'Cursor for the next entity search page' }, + entity: { type: 'json', description: 'New Relic entity details (guid, name, entityType)' }, + event: { type: 'json', description: 'Created change tracking event metadata' }, + messages: { type: 'json', description: 'New Relic change tracking messages' }, + }, +} diff --git a/apps/sim/blocks/blocks/railway.ts b/apps/sim/blocks/blocks/railway.ts new file mode 100644 index 00000000000..e011afea67e --- /dev/null +++ b/apps/sim/blocks/blocks/railway.ts @@ -0,0 +1,642 @@ +import { RailwayIcon } from '@/components/icons' +import type { BlockConfig } from '@/blocks/types' +import { AuthMode, IntegrationType } from '@/blocks/types' +import type { RailwayResponse } from '@/tools/railway/types' + +export const RailwayBlock: BlockConfig = { + type: 'railway', + name: 'Railway', + description: 'Manage Railway projects, deployments, and variables', + longDescription: + 'Integrate Railway into workflows to list projects, inspect services and environments, monitor deployments, trigger service deployments, and manage environment variables.', + docsLink: 'https://docs.sim.ai/tools/railway', + category: 'tools', + integrationType: IntegrationType.DeveloperTools, + tags: ['cloud', 'ci-cd'], + bgColor: '#FFFFFF', + icon: RailwayIcon, + authMode: AuthMode.ApiKey, + + subBlocks: [ + { + id: 'operation', + title: 'Operation', + type: 'dropdown', + options: [ + { label: 'List Projects', id: 'list_projects' }, + { label: 'Get Project', id: 'get_project' }, + { label: 'Create Project', id: 'create_project' }, + { label: 'Update Project', id: 'update_project' }, + { label: 'Delete Project', id: 'delete_project' }, + { label: 'Transfer Project', id: 'transfer_project' }, + { label: 'List Project Members', id: 'list_project_members' }, + { label: 'Create Environment', id: 'create_environment' }, + { label: 'Delete Environment', id: 'delete_environment' }, + { label: 'List Deployments', id: 'list_deployments' }, + { label: 'Deploy Service', id: 'deploy_service' }, + { label: 'List Variables', id: 'list_variables' }, + { label: 'Upsert Variable', id: 'upsert_variable' }, + ], + value: () => 'list_projects', + }, + { + id: 'apiKey', + title: 'API Token', + type: 'short-input', + placeholder: 'Enter Railway API token', + password: true, + required: true, + }, + { + id: 'tokenType', + title: 'Token Type', + type: 'dropdown', + options: [ + { label: 'Account / Workspace / OAuth', id: 'account' }, + { label: 'Project', id: 'project' }, + ], + value: () => 'account', + mode: 'advanced', + }, + { + id: 'listProjectsWorkspaceId', + title: 'Workspace ID', + type: 'short-input', + placeholder: 'Workspace ID', + condition: { field: 'operation', value: 'list_projects' }, + mode: 'advanced', + }, + { + id: 'first', + title: 'Limit', + type: 'short-input', + placeholder: '20', + condition: { field: 'operation', value: 'list_projects' }, + mode: 'advanced', + }, + { + id: 'after', + title: 'After Cursor', + type: 'short-input', + placeholder: 'Cursor from a previous response', + condition: { field: 'operation', value: 'list_projects' }, + mode: 'advanced', + }, + { + id: 'detailProjectId', + title: 'Project ID', + type: 'short-input', + placeholder: 'Railway project ID', + condition: { field: 'operation', value: 'get_project' }, + required: { field: 'operation', value: 'get_project' }, + }, + { + id: 'createProjectName', + title: 'Project Name', + type: 'short-input', + placeholder: 'my-app', + condition: { field: 'operation', value: 'create_project' }, + required: { field: 'operation', value: 'create_project' }, + }, + { + id: 'createProjectDescription', + title: 'Description', + type: 'long-input', + placeholder: 'Project description', + condition: { field: 'operation', value: 'create_project' }, + mode: 'advanced', + }, + { + id: 'createProjectWorkspaceId', + title: 'Workspace ID', + type: 'short-input', + placeholder: 'Workspace ID', + condition: { field: 'operation', value: 'create_project' }, + mode: 'advanced', + }, + { + id: 'createProjectIsPublic', + title: 'Public Project', + type: 'dropdown', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + condition: { field: 'operation', value: 'create_project' }, + mode: 'advanced', + }, + { + id: 'defaultEnvironmentName', + title: 'Default Environment', + type: 'short-input', + placeholder: 'production', + condition: { field: 'operation', value: 'create_project' }, + mode: 'advanced', + }, + { + id: 'prDeploys', + title: 'PR Deploys', + type: 'dropdown', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + condition: { field: 'operation', value: 'create_project' }, + mode: 'advanced', + }, + { + id: 'updateProjectId', + title: 'Project ID', + type: 'short-input', + placeholder: 'Railway project ID', + condition: { field: 'operation', value: 'update_project' }, + required: { field: 'operation', value: 'update_project' }, + }, + { + id: 'updateProjectName', + title: 'Project Name', + type: 'short-input', + placeholder: 'Updated project name', + condition: { field: 'operation', value: 'update_project' }, + }, + { + id: 'updateProjectDescription', + title: 'Description', + type: 'long-input', + placeholder: 'Updated project description', + condition: { field: 'operation', value: 'update_project' }, + }, + { + id: 'updateProjectIsPublic', + title: 'Public Project', + type: 'dropdown', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + condition: { field: 'operation', value: 'update_project' }, + mode: 'advanced', + }, + { + id: 'updateProjectPrDeploys', + title: 'PR Deploys', + type: 'dropdown', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + condition: { field: 'operation', value: 'update_project' }, + mode: 'advanced', + }, + { + id: 'deleteProjectId', + title: 'Project ID', + type: 'short-input', + placeholder: 'Railway project ID', + condition: { field: 'operation', value: 'delete_project' }, + required: { field: 'operation', value: 'delete_project' }, + }, + { + id: 'transferProjectId', + title: 'Project ID', + type: 'short-input', + placeholder: 'Railway project ID', + condition: { field: 'operation', value: 'transfer_project' }, + required: { field: 'operation', value: 'transfer_project' }, + }, + { + id: 'workspaceId', + title: 'Workspace ID', + type: 'short-input', + placeholder: 'Destination workspace ID', + condition: { field: 'operation', value: 'transfer_project' }, + required: { field: 'operation', value: 'transfer_project' }, + }, + { + id: 'membersProjectId', + title: 'Project ID', + type: 'short-input', + placeholder: 'Railway project ID', + condition: { field: 'operation', value: 'list_project_members' }, + required: { field: 'operation', value: 'list_project_members' }, + }, + { + id: 'createEnvironmentProjectId', + title: 'Project ID', + type: 'short-input', + placeholder: 'Railway project ID', + condition: { field: 'operation', value: 'create_environment' }, + required: { field: 'operation', value: 'create_environment' }, + }, + { + id: 'environmentName', + title: 'Environment Name', + type: 'short-input', + placeholder: 'staging', + condition: { field: 'operation', value: 'create_environment' }, + required: { field: 'operation', value: 'create_environment' }, + }, + { + id: 'sourceEnvironmentId', + title: 'Source Environment ID', + type: 'short-input', + placeholder: 'Environment ID to clone from', + condition: { field: 'operation', value: 'create_environment' }, + mode: 'advanced', + }, + { + id: 'ephemeral', + title: 'Ephemeral', + type: 'dropdown', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + condition: { field: 'operation', value: 'create_environment' }, + mode: 'advanced', + }, + { + id: 'skipInitialDeploys', + title: 'Skip Initial Deploys', + type: 'dropdown', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + condition: { field: 'operation', value: 'create_environment' }, + mode: 'advanced', + }, + { + id: 'stageInitialChanges', + title: 'Stage Initial Changes', + type: 'dropdown', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + condition: { field: 'operation', value: 'create_environment' }, + mode: 'advanced', + }, + { + id: 'deleteEnvironmentId', + title: 'Environment ID', + type: 'short-input', + placeholder: 'Railway environment ID', + condition: { field: 'operation', value: 'delete_environment' }, + required: { field: 'operation', value: 'delete_environment' }, + }, + { + id: 'deploymentProjectId', + title: 'Project ID', + type: 'short-input', + placeholder: 'Railway project ID', + condition: { field: 'operation', value: 'list_deployments' }, + required: { field: 'operation', value: 'list_deployments' }, + }, + { + id: 'deploymentServiceId', + title: 'Service ID', + type: 'short-input', + placeholder: 'Railway service ID', + condition: { field: 'operation', value: 'list_deployments' }, + required: { field: 'operation', value: 'list_deployments' }, + }, + { + id: 'deploymentEnvironmentId', + title: 'Environment ID', + type: 'short-input', + placeholder: 'Railway environment ID', + condition: { field: 'operation', value: 'list_deployments' }, + required: { field: 'operation', value: 'list_deployments' }, + }, + { + id: 'deploymentFirst', + title: 'Limit', + type: 'short-input', + placeholder: '10', + condition: { field: 'operation', value: 'list_deployments' }, + mode: 'advanced', + }, + { + id: 'deploymentAfter', + title: 'After Cursor', + type: 'short-input', + placeholder: 'Cursor from a previous response', + condition: { field: 'operation', value: 'list_deployments' }, + mode: 'advanced', + }, + { + id: 'deployServiceId', + title: 'Service ID', + type: 'short-input', + placeholder: 'Railway service ID', + condition: { field: 'operation', value: 'deploy_service' }, + required: { field: 'operation', value: 'deploy_service' }, + }, + { + id: 'deployEnvironmentId', + title: 'Environment ID', + type: 'short-input', + placeholder: 'Railway environment ID', + condition: { field: 'operation', value: 'deploy_service' }, + required: { field: 'operation', value: 'deploy_service' }, + }, + { + id: 'deployCommitSha', + title: 'Commit SHA', + type: 'short-input', + placeholder: 'abc123...', + condition: { field: 'operation', value: 'deploy_service' }, + mode: 'advanced', + }, + { + id: 'variablesProjectId', + title: 'Project ID', + type: 'short-input', + placeholder: 'Railway project ID', + condition: { field: 'operation', value: 'list_variables' }, + required: { field: 'operation', value: 'list_variables' }, + }, + { + id: 'variablesEnvironmentId', + title: 'Environment ID', + type: 'short-input', + placeholder: 'Railway environment ID', + condition: { field: 'operation', value: 'list_variables' }, + required: { field: 'operation', value: 'list_variables' }, + }, + { + id: 'variablesServiceId', + title: 'Service ID', + type: 'short-input', + placeholder: 'Leave blank for shared variables', + condition: { field: 'operation', value: 'list_variables' }, + mode: 'advanced', + }, + { + id: 'upsertProjectId', + title: 'Project ID', + type: 'short-input', + placeholder: 'Railway project ID', + condition: { field: 'operation', value: 'upsert_variable' }, + required: { field: 'operation', value: 'upsert_variable' }, + }, + { + id: 'upsertEnvironmentId', + title: 'Environment ID', + type: 'short-input', + placeholder: 'Railway environment ID', + condition: { field: 'operation', value: 'upsert_variable' }, + required: { field: 'operation', value: 'upsert_variable' }, + }, + { + id: 'upsertServiceId', + title: 'Service ID', + type: 'short-input', + placeholder: 'Leave blank for shared variables', + condition: { field: 'operation', value: 'upsert_variable' }, + mode: 'advanced', + }, + { + id: 'variableName', + title: 'Variable Name', + type: 'short-input', + placeholder: 'DATABASE_URL', + condition: { field: 'operation', value: 'upsert_variable' }, + required: { field: 'operation', value: 'upsert_variable' }, + }, + { + id: 'variableValue', + title: 'Variable Value', + type: 'long-input', + placeholder: 'Variable value', + condition: { field: 'operation', value: 'upsert_variable' }, + required: { field: 'operation', value: 'upsert_variable' }, + }, + { + id: 'skipDeploys', + title: 'Skip Deploys', + type: 'dropdown', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + condition: { field: 'operation', value: 'upsert_variable' }, + mode: 'advanced', + }, + ], + + tools: { + access: [ + 'railway_list_projects', + 'railway_get_project', + 'railway_create_project', + 'railway_update_project', + 'railway_delete_project', + 'railway_transfer_project', + 'railway_list_project_members', + 'railway_create_environment', + 'railway_delete_environment', + 'railway_list_deployments', + 'railway_deploy_service', + 'railway_list_variables', + 'railway_upsert_variable', + ], + config: { + tool: (params) => `railway_${params.operation}`, + params: (params) => { + const baseParams = { + apiKey: params.apiKey, + tokenType: params.tokenType, + } + + switch (params.operation) { + case 'list_projects': + return { + ...baseParams, + workspaceId: params.listProjectsWorkspaceId, + first: params.first ? Number(params.first) : undefined, + after: params.after, + } + case 'create_project': + return { + ...baseParams, + name: params.createProjectName, + description: params.createProjectDescription, + workspaceId: params.createProjectWorkspaceId, + isPublic: params.createProjectIsPublic + ? params.createProjectIsPublic === 'true' + : undefined, + defaultEnvironmentName: params.defaultEnvironmentName, + prDeploys: params.prDeploys ? params.prDeploys === 'true' : undefined, + } + case 'update_project': + return { + ...baseParams, + projectId: params.updateProjectId, + name: params.updateProjectName, + description: params.updateProjectDescription, + isPublic: params.updateProjectIsPublic + ? params.updateProjectIsPublic === 'true' + : undefined, + prDeploys: params.updateProjectPrDeploys + ? params.updateProjectPrDeploys === 'true' + : undefined, + } + case 'delete_project': + return { + ...baseParams, + projectId: params.deleteProjectId, + } + case 'transfer_project': + return { + ...baseParams, + projectId: params.transferProjectId, + workspaceId: params.workspaceId, + } + case 'list_project_members': + return { + ...baseParams, + projectId: params.membersProjectId, + } + case 'create_environment': + return { + ...baseParams, + projectId: params.createEnvironmentProjectId, + name: params.environmentName, + sourceEnvironmentId: params.sourceEnvironmentId, + ephemeral: params.ephemeral ? params.ephemeral === 'true' : undefined, + skipInitialDeploys: params.skipInitialDeploys + ? params.skipInitialDeploys === 'true' + : undefined, + stageInitialChanges: params.stageInitialChanges + ? params.stageInitialChanges === 'true' + : undefined, + } + case 'delete_environment': + return { + ...baseParams, + environmentId: params.deleteEnvironmentId, + } + case 'get_project': + return { + ...baseParams, + projectId: params.detailProjectId, + } + case 'list_deployments': + return { + ...baseParams, + projectId: params.deploymentProjectId, + serviceId: params.deploymentServiceId, + environmentId: params.deploymentEnvironmentId, + first: params.deploymentFirst ? Number(params.deploymentFirst) : undefined, + after: params.deploymentAfter, + } + case 'deploy_service': + return { + ...baseParams, + serviceId: params.deployServiceId, + environmentId: params.deployEnvironmentId, + commitSha: params.deployCommitSha, + } + case 'list_variables': + return { + ...baseParams, + projectId: params.variablesProjectId, + environmentId: params.variablesEnvironmentId, + serviceId: params.variablesServiceId, + } + case 'upsert_variable': + return { + ...baseParams, + projectId: params.upsertProjectId, + environmentId: params.upsertEnvironmentId, + serviceId: params.upsertServiceId, + name: params.variableName, + value: params.variableValue, + skipDeploys: params.skipDeploys ? params.skipDeploys === 'true' : undefined, + } + default: + return baseParams + } + }, + }, + }, + + inputs: { + apiKey: { type: 'string', description: 'Railway API token' }, + tokenType: { type: 'string', description: 'Railway token type' }, + listProjectsWorkspaceId: { type: 'string', description: 'Workspace ID for project listing' }, + first: { type: 'number', description: 'List projects limit' }, + after: { type: 'string', description: 'List projects pagination cursor' }, + detailProjectId: { type: 'string', description: 'Project ID for project lookup' }, + createProjectName: { type: 'string', description: 'Project name to create' }, + createProjectDescription: { type: 'string', description: 'Project description to create' }, + createProjectWorkspaceId: { type: 'string', description: 'Workspace ID for created project' }, + createProjectIsPublic: { type: 'string', description: 'Whether the created project is public' }, + defaultEnvironmentName: { type: 'string', description: 'Default environment name' }, + prDeploys: { type: 'string', description: 'Whether to enable PR deploys' }, + updateProjectId: { type: 'string', description: 'Project ID to update' }, + updateProjectName: { type: 'string', description: 'Updated project name' }, + updateProjectDescription: { type: 'string', description: 'Updated project description' }, + updateProjectIsPublic: { type: 'string', description: 'Whether the project is public' }, + updateProjectPrDeploys: { type: 'string', description: 'Whether to enable PR deploys' }, + deleteProjectId: { type: 'string', description: 'Project ID to delete' }, + transferProjectId: { type: 'string', description: 'Project ID to transfer' }, + workspaceId: { type: 'string', description: 'Destination workspace ID' }, + membersProjectId: { type: 'string', description: 'Project ID for member listing' }, + createEnvironmentProjectId: { type: 'string', description: 'Project ID for new environment' }, + environmentName: { type: 'string', description: 'Environment name to create' }, + sourceEnvironmentId: { type: 'string', description: 'Environment ID to clone from' }, + ephemeral: { type: 'string', description: 'Whether the environment is ephemeral' }, + skipInitialDeploys: { type: 'string', description: 'Whether to skip initial deploys' }, + stageInitialChanges: { type: 'string', description: 'Whether to stage initial changes' }, + deleteEnvironmentId: { type: 'string', description: 'Environment ID to delete' }, + deploymentProjectId: { type: 'string', description: 'Project ID for deployments' }, + deploymentServiceId: { type: 'string', description: 'Service ID for deployments' }, + deploymentEnvironmentId: { type: 'string', description: 'Environment ID for deployments' }, + deploymentFirst: { type: 'number', description: 'List deployments limit' }, + deploymentAfter: { type: 'string', description: 'List deployments pagination cursor' }, + deployServiceId: { type: 'string', description: 'Service ID to deploy' }, + deployEnvironmentId: { type: 'string', description: 'Environment ID to deploy' }, + deployCommitSha: { type: 'string', description: 'Specific Git commit SHA to deploy' }, + variablesProjectId: { type: 'string', description: 'Project ID for variables' }, + variablesEnvironmentId: { type: 'string', description: 'Environment ID for variables' }, + variablesServiceId: { type: 'string', description: 'Optional service ID for variables' }, + upsertProjectId: { type: 'string', description: 'Project ID for variable upsert' }, + upsertEnvironmentId: { type: 'string', description: 'Environment ID for variable upsert' }, + upsertServiceId: { type: 'string', description: 'Optional service ID for variable upsert' }, + variableName: { type: 'string', description: 'Variable name' }, + variableValue: { type: 'string', description: 'Variable value' }, + skipDeploys: { type: 'string', description: 'Whether to skip deploys after variable upsert' }, + }, + + outputs: { + projects: { type: 'json', description: 'List of Railway projects' }, + project: { type: 'json', description: 'Railway project with services and environments' }, + members: { type: 'json', description: 'Railway project members (id, role, user)' }, + environment: { type: 'json', description: 'Railway environment (id, name)' }, + deployments: { type: 'json', description: 'List of Railway deployments' }, + variables: { type: 'json', description: 'Railway environment variables' }, + deploymentId: { type: 'string', description: 'Created deployment ID' }, + success: { type: 'boolean', description: 'Whether the operation succeeded' }, + count: { type: 'number', description: 'Number of items returned' }, + pageInfo: { type: 'json', description: 'Pagination information' }, + }, +} diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index 64c0e44859e..b343f743d29 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -140,6 +140,7 @@ import { MongoDBBlock } from '@/blocks/blocks/mongodb' import { MothershipBlock } from '@/blocks/blocks/mothership' import { MySQLBlock } from '@/blocks/blocks/mysql' import { Neo4jBlock } from '@/blocks/blocks/neo4j' +import { NewRelicBlock } from '@/blocks/blocks/new_relic' import { NoteBlock } from '@/blocks/blocks/note' import { NotionBlock, NotionV2Block } from '@/blocks/blocks/notion' import { ObsidianBlock } from '@/blocks/blocks/obsidian' @@ -162,6 +163,7 @@ import { ProspeoBlock } from '@/blocks/blocks/prospeo' import { PulseBlock, PulseV2Block } from '@/blocks/blocks/pulse' import { QdrantBlock } from '@/blocks/blocks/qdrant' import { QuiverBlock } from '@/blocks/blocks/quiver' +import { RailwayBlock } from '@/blocks/blocks/railway' import { RDSBlock } from '@/blocks/blocks/rds' import { RedditBlock } from '@/blocks/blocks/reddit' import { RedisBlock } from '@/blocks/blocks/redis' @@ -396,6 +398,7 @@ export const registry: Record = { mothership: MothershipBlock, mysql: MySQLBlock, neo4j: Neo4jBlock, + new_relic: NewRelicBlock, note: NoteBlock, notion: NotionBlock, notion_v2: NotionV2Block, @@ -420,6 +423,7 @@ export const registry: Record = { pulse_v2: PulseV2Block, qdrant: QdrantBlock, quiver: QuiverBlock, + railway: RailwayBlock, rds: RDSBlock, reddit: RedditBlock, redis: RedisBlock, diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index ab234725964..cd326d6220a 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -6958,6 +6958,14 @@ export function HexIcon(props: SVGProps) { ) } +export function RailwayIcon(props: SVGProps) { + return ( + + + + ) +} + export function BigQueryIcon(props: SVGProps) { return ( @@ -6981,6 +6989,21 @@ export function SnowflakeIcon(props: SVGProps) { ) } +export function NewRelicIcon(props: SVGProps) { + return ( + + + + + ) +} + export function WizaIcon(props: SVGProps) { return ( diff --git a/apps/sim/tools/gong/aggregate_activity.ts b/apps/sim/tools/gong/aggregate_activity.ts index d0c3388b0e1..a962e00dc75 100644 --- a/apps/sim/tools/gong/aggregate_activity.ts +++ b/apps/sim/tools/gong/aggregate_activity.ts @@ -1,4 +1,5 @@ import type { GongAggregateActivityParams, GongAggregateActivityResponse } from '@/tools/gong/types' +import { getGongErrorMessage, parseGongIdList } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const aggregateActivityTool: ToolConfig< @@ -59,14 +60,13 @@ export const aggregateActivityTool: ToolConfig< }), body: (params) => { const filter: Record = { - fromDate: params.fromDate, - toDate: params.toDate, - } - if (params.userIds) { - filter.userIds = params.userIds.split(',').map((id) => id.trim()) + fromDate: params.fromDate.trim(), + toDate: params.toDate.trim(), } + const userIds = parseGongIdList(params.userIds) + if (userIds) filter.userIds = userIds const body: Record = { filter } - if (params.cursor) body.cursor = params.cursor + if (params.cursor?.trim()) body.cursor = params.cursor.trim() return body }, }, @@ -74,9 +74,7 @@ export const aggregateActivityTool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() if (!response.ok) { - throw new Error( - data.errors?.[0]?.message || data.message || 'Failed to get aggregate activity' - ) + throw new Error(getGongErrorMessage(data, 'Failed to get aggregate activity')) } const usersActivity = (data.usersAggregateActivityStats ?? []).map( (ua: Record) => { diff --git a/apps/sim/tools/gong/answered_scorecards.ts b/apps/sim/tools/gong/answered_scorecards.ts index a37899477db..92e105fdc55 100644 --- a/apps/sim/tools/gong/answered_scorecards.ts +++ b/apps/sim/tools/gong/answered_scorecards.ts @@ -2,6 +2,7 @@ import type { GongAnsweredScorecardsParams, GongAnsweredScorecardsResponse, } from '@/tools/gong/types' +import { getGongErrorMessage, parseGongIdList } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const answeredScorecardsTool: ToolConfig< @@ -83,18 +84,16 @@ export const answeredScorecardsTool: ToolConfig< }), body: (params) => { const filter: Record = {} - if (params.callFromDate) filter.callFromDate = params.callFromDate - if (params.callToDate) filter.callToDate = params.callToDate - if (params.reviewFromDate) filter.reviewFromDate = params.reviewFromDate - if (params.reviewToDate) filter.reviewToDate = params.reviewToDate - if (params.scorecardIds) { - filter.scorecardIds = params.scorecardIds.split(',').map((id) => id.trim()) - } - if (params.reviewedUserIds) { - filter.reviewedUserIds = params.reviewedUserIds.split(',').map((id) => id.trim()) - } + if (params.callFromDate?.trim()) filter.callFromDate = params.callFromDate.trim() + if (params.callToDate?.trim()) filter.callToDate = params.callToDate.trim() + if (params.reviewFromDate?.trim()) filter.reviewFromDate = params.reviewFromDate.trim() + if (params.reviewToDate?.trim()) filter.reviewToDate = params.reviewToDate.trim() + const scorecardIds = parseGongIdList(params.scorecardIds) + const reviewedUserIds = parseGongIdList(params.reviewedUserIds) + if (scorecardIds) filter.scorecardIds = scorecardIds + if (reviewedUserIds) filter.reviewedUserIds = reviewedUserIds const body: Record = { filter } - if (params.cursor) body.cursor = params.cursor + if (params.cursor?.trim()) body.cursor = params.cursor.trim() return body }, }, @@ -102,9 +101,7 @@ export const answeredScorecardsTool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() if (!response.ok) { - throw new Error( - data.errors?.[0]?.message || data.message || 'Failed to get answered scorecards' - ) + throw new Error(getGongErrorMessage(data, 'Failed to get answered scorecards')) } const answeredScorecards = (data.answeredScorecards ?? []).map( (sc: Record) => ({ diff --git a/apps/sim/tools/gong/create_call.ts b/apps/sim/tools/gong/create_call.ts new file mode 100644 index 00000000000..5a2c35f0858 --- /dev/null +++ b/apps/sim/tools/gong/create_call.ts @@ -0,0 +1,157 @@ +import type { GongCreateCallParams, GongCreateCallResponse } from '@/tools/gong/types' +import { getGongErrorMessage, parseGongJsonArray } from '@/tools/gong/utils' +import type { ToolConfig } from '@/tools/types' + +export const createCallTool: ToolConfig = { + id: 'gong_create_call', + name: 'Gong Create Call', + description: 'Upload call metadata to Gong and let Gong pull the media from a URL.', + version: '1.0.0', + + params: { + accessKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Gong API Access Key', + }, + accessKeySecret: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Gong API Access Key Secret', + }, + clientUniqueId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Unique call ID from the source telephony or recording system', + }, + actualStart: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Actual call start time in ISO-8601 format', + }, + primaryUser: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: "Gong user ID for the call's host or owner", + }, + parties: { + type: 'json', + required: true, + visibility: 'user-or-llm', + description: 'Array of call parties, with at least the primary user included', + }, + direction: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Call direction: Inbound, Outbound, Conference, or Unknown', + }, + downloadMediaUrl: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'URL where Gong can download the call media file', + }, + title: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Human-readable call title', + }, + workspaceId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional Gong workspace ID', + }, + disposition: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional call disposition', + }, + purpose: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional call purpose', + }, + context: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: 'Optional CRM context array for the call', + }, + callProviderCode: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional conferencing or telephony provider code', + }, + }, + + request: { + url: 'https://api.gong.io/v2/calls', + method: 'POST', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Basic ${btoa(`${params.accessKey}:${params.accessKeySecret}`)}`, + }), + body: (params) => { + const body: Record = { + clientUniqueId: params.clientUniqueId.trim(), + actualStart: params.actualStart.trim(), + primaryUser: params.primaryUser.trim(), + parties: parseGongJsonArray(params.parties, 'parties'), + direction: params.direction, + downloadMediaUrl: params.downloadMediaUrl.trim(), + } + + if (params.title?.trim()) body.title = params.title.trim() + if (params.workspaceId?.trim()) body.workspaceId = params.workspaceId.trim() + if (params.disposition?.trim()) body.disposition = params.disposition.trim() + if (params.purpose?.trim()) body.purpose = params.purpose.trim() + if (params.context) body.context = parseGongJsonArray(params.context, 'context') + if (params.callProviderCode?.trim()) body.callProviderCode = params.callProviderCode.trim() + + return body + }, + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + if (!response.ok) { + throw new Error(getGongErrorMessage(data, 'Failed to create Gong call')) + } + + return { + success: true, + output: { + callId: data.callId ?? '', + requestId: data.requestId ?? '', + url: data.url ?? null, + }, + } + }, + + outputs: { + callId: { + type: 'string', + description: "Gong's unique numeric identifier for the created call", + }, + requestId: { + type: 'string', + description: 'Gong request reference ID for troubleshooting', + }, + url: { + type: 'string', + description: 'URL to the created call in the Gong web app', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/gong/get_call.ts b/apps/sim/tools/gong/get_call.ts index d9595a049a2..35b31585248 100644 --- a/apps/sim/tools/gong/get_call.ts +++ b/apps/sim/tools/gong/get_call.ts @@ -1,4 +1,5 @@ import type { GongGetCallParams, GongGetCallResponse } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const getCallTool: ToolConfig = { @@ -29,7 +30,7 @@ export const getCallTool: ToolConfig = { }, request: { - url: (params) => `https://api.gong.io/v2/calls/${params.callId}`, + url: (params) => `https://api.gong.io/v2/calls/${params.callId.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', @@ -40,7 +41,7 @@ export const getCallTool: ToolConfig = { transformResponse: async (response: Response) => { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to get call') + throw new Error(getGongErrorMessage(data, 'Failed to get call')) } const call = data.call ?? data return { diff --git a/apps/sim/tools/gong/get_call_transcript.ts b/apps/sim/tools/gong/get_call_transcript.ts index 31f327fd6be..ddd26bfb6e6 100644 --- a/apps/sim/tools/gong/get_call_transcript.ts +++ b/apps/sim/tools/gong/get_call_transcript.ts @@ -1,4 +1,5 @@ import type { GongGetCallTranscriptParams, GongGetCallTranscriptResponse } from '@/tools/gong/types' +import { getGongErrorMessage, parseGongIdList } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const getCallTranscriptTool: ToolConfig< @@ -64,14 +65,13 @@ export const getCallTranscriptTool: ToolConfig< }), body: (params) => { const filter: Record = {} - if (params.callIds) { - filter.callIds = params.callIds.split(',').map((id) => id.trim()) - } - if (params.fromDateTime) filter.fromDateTime = params.fromDateTime - if (params.toDateTime) filter.toDateTime = params.toDateTime - if (params.workspaceId) filter.workspaceId = params.workspaceId + const callIds = parseGongIdList(params.callIds) + if (callIds) filter.callIds = callIds + if (params.fromDateTime?.trim()) filter.fromDateTime = params.fromDateTime.trim() + if (params.toDateTime?.trim()) filter.toDateTime = params.toDateTime.trim() + if (params.workspaceId?.trim()) filter.workspaceId = params.workspaceId.trim() const body: Record = { filter } - if (params.cursor) body.cursor = params.cursor + if (params.cursor?.trim()) body.cursor = params.cursor.trim() return body }, }, @@ -79,7 +79,7 @@ export const getCallTranscriptTool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to get call transcript') + throw new Error(getGongErrorMessage(data, 'Failed to get call transcript')) } const callTranscripts = (data.callTranscripts ?? []).map((ct: Record) => ({ callId: ct.callId ?? '', diff --git a/apps/sim/tools/gong/get_coaching.ts b/apps/sim/tools/gong/get_coaching.ts index b16e3b28cef..21b0323131b 100644 --- a/apps/sim/tools/gong/get_coaching.ts +++ b/apps/sim/tools/gong/get_coaching.ts @@ -5,6 +5,7 @@ import type { GongGetCoachingParams, GongGetCoachingResponse, } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const getCoachingTool: ToolConfig = { @@ -55,10 +56,10 @@ export const getCoachingTool: ToolConfig { const url = new URL('https://api.gong.io/v2/coaching') - url.searchParams.set('manager-id', params.managerId) - url.searchParams.set('workspace-id', params.workspaceId) - url.searchParams.set('from', params.fromDate) - url.searchParams.set('to', params.toDate) + url.searchParams.set('manager-id', params.managerId.trim()) + url.searchParams.set('workspace-id', params.workspaceId.trim()) + url.searchParams.set('from', params.fromDate.trim()) + url.searchParams.set('to', params.toDate.trim()) return url.toString() }, method: 'GET', @@ -71,7 +72,7 @@ export const getCoachingTool: ToolConfig { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to get coaching metrics') + throw new Error(getGongErrorMessage(data, 'Failed to get coaching metrics')) } const mapUser = (u: Record | null | undefined): GongCoachingUser | null => { diff --git a/apps/sim/tools/gong/get_extensive_calls.ts b/apps/sim/tools/gong/get_extensive_calls.ts index 6a7c91b4315..aee5065e219 100644 --- a/apps/sim/tools/gong/get_extensive_calls.ts +++ b/apps/sim/tools/gong/get_extensive_calls.ts @@ -1,4 +1,5 @@ import type { GongGetExtensiveCallsParams, GongGetExtensiveCallsResponse } from '@/tools/gong/types' +import { getGongErrorMessage, parseGongIdList } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const getExtensiveCallsTool: ToolConfig< @@ -70,15 +71,13 @@ export const getExtensiveCallsTool: ToolConfig< }), body: (params) => { const filter: Record = {} - if (params.callIds) { - filter.callIds = params.callIds.split(',').map((id) => id.trim()) - } - if (params.fromDateTime) filter.fromDateTime = params.fromDateTime - if (params.toDateTime) filter.toDateTime = params.toDateTime - if (params.workspaceId) filter.workspaceId = params.workspaceId - if (params.primaryUserIds) { - filter.primaryUserIds = params.primaryUserIds.split(',').map((id) => id.trim()) - } + const callIds = parseGongIdList(params.callIds) + const primaryUserIds = parseGongIdList(params.primaryUserIds) + if (callIds) filter.callIds = callIds + if (params.fromDateTime?.trim()) filter.fromDateTime = params.fromDateTime.trim() + if (params.toDateTime?.trim()) filter.toDateTime = params.toDateTime.trim() + if (params.workspaceId?.trim()) filter.workspaceId = params.workspaceId.trim() + if (primaryUserIds) filter.primaryUserIds = primaryUserIds const body: Record = { filter, contentSelector: { @@ -102,7 +101,7 @@ export const getExtensiveCallsTool: ToolConfig< }, }, } - if (params.cursor) body.cursor = params.cursor + if (params.cursor?.trim()) body.cursor = params.cursor.trim() return body }, }, @@ -110,9 +109,7 @@ export const getExtensiveCallsTool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() if (!response.ok) { - throw new Error( - data.errors?.[0]?.message || data.message || 'Failed to get extensive call data' - ) + throw new Error(getGongErrorMessage(data, 'Failed to get extensive call data')) } return { success: true, diff --git a/apps/sim/tools/gong/get_folder_content.ts b/apps/sim/tools/gong/get_folder_content.ts index 6704d7ce8e7..65a91da7843 100644 --- a/apps/sim/tools/gong/get_folder_content.ts +++ b/apps/sim/tools/gong/get_folder_content.ts @@ -1,4 +1,5 @@ import type { GongGetFolderContentParams, GongGetFolderContentResponse } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const getFolderContentTool: ToolConfig< @@ -34,7 +35,7 @@ export const getFolderContentTool: ToolConfig< request: { url: (params) => { const url = new URL('https://api.gong.io/v2/library/folder-content') - url.searchParams.set('folderId', params.folderId) + url.searchParams.set('folderId', params.folderId.trim()) return url.toString() }, method: 'GET', @@ -47,7 +48,7 @@ export const getFolderContentTool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to get folder content') + throw new Error(getGongErrorMessage(data, 'Failed to get folder content')) } const calls = (data.calls ?? []).map((c: Record) => ({ id: (c.id as string) ?? '', diff --git a/apps/sim/tools/gong/get_user.ts b/apps/sim/tools/gong/get_user.ts index a8b071389fe..6c5be146d69 100644 --- a/apps/sim/tools/gong/get_user.ts +++ b/apps/sim/tools/gong/get_user.ts @@ -1,4 +1,5 @@ import type { GongGetUserParams, GongGetUserResponse } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const getUserTool: ToolConfig = { @@ -29,7 +30,7 @@ export const getUserTool: ToolConfig = { }, request: { - url: (params) => `https://api.gong.io/v2/users/${params.userId}`, + url: (params) => `https://api.gong.io/v2/users/${params.userId.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', @@ -40,7 +41,7 @@ export const getUserTool: ToolConfig = { transformResponse: async (response: Response) => { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to get user') + throw new Error(getGongErrorMessage(data, 'Failed to get user')) } const user = data.user ?? data return { diff --git a/apps/sim/tools/gong/index.ts b/apps/sim/tools/gong/index.ts index 89c6b80e8c5..c838bd8e075 100644 --- a/apps/sim/tools/gong/index.ts +++ b/apps/sim/tools/gong/index.ts @@ -1,5 +1,6 @@ import { aggregateActivityTool } from '@/tools/gong/aggregate_activity' import { answeredScorecardsTool } from '@/tools/gong/answered_scorecards' +import { createCallTool } from '@/tools/gong/create_call' import { getCallTool } from '@/tools/gong/get_call' import { getCallTranscriptTool } from '@/tools/gong/get_call_transcript' import { getCoachingTool } from '@/tools/gong/get_coaching' @@ -18,6 +19,7 @@ import { lookupEmailTool } from '@/tools/gong/lookup_email' import { lookupPhoneTool } from '@/tools/gong/lookup_phone' export const gongListCallsTool = listCallsTool +export const gongCreateCallTool = createCallTool export const gongGetCallTool = getCallTool export const gongGetCallTranscriptTool = getCallTranscriptTool export const gongGetExtensiveCallsTool = getExtensiveCallsTool @@ -35,3 +37,5 @@ export const gongListFlowsTool = listFlowsTool export const gongGetCoachingTool = getCoachingTool export const gongLookupEmailTool = lookupEmailTool export const gongLookupPhoneTool = lookupPhoneTool + +export * from './types' diff --git a/apps/sim/tools/gong/interaction_stats.ts b/apps/sim/tools/gong/interaction_stats.ts index 6ec3cdca4ff..d8b16709174 100644 --- a/apps/sim/tools/gong/interaction_stats.ts +++ b/apps/sim/tools/gong/interaction_stats.ts @@ -1,4 +1,5 @@ import type { GongInteractionStatsParams, GongInteractionStatsResponse } from '@/tools/gong/types' +import { getGongErrorMessage, parseGongIdList } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const interactionStatsTool: ToolConfig< @@ -60,14 +61,13 @@ export const interactionStatsTool: ToolConfig< }), body: (params) => { const filter: Record = { - fromDate: params.fromDate, - toDate: params.toDate, - } - if (params.userIds) { - filter.userIds = params.userIds.split(',').map((id) => id.trim()) + fromDate: params.fromDate.trim(), + toDate: params.toDate.trim(), } + const userIds = parseGongIdList(params.userIds) + if (userIds) filter.userIds = userIds const body: Record = { filter } - if (params.cursor) body.cursor = params.cursor + if (params.cursor?.trim()) body.cursor = params.cursor.trim() return body }, }, @@ -75,9 +75,7 @@ export const interactionStatsTool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() if (!response.ok) { - throw new Error( - data.errors?.[0]?.message || data.message || 'Failed to get interaction stats' - ) + throw new Error(getGongErrorMessage(data, 'Failed to get interaction stats')) } const peopleInteractionStats = (data.peopleInteractionStats ?? []).map( (entry: Record) => ({ diff --git a/apps/sim/tools/gong/list_calls.ts b/apps/sim/tools/gong/list_calls.ts index 3ef67dee7bd..655bed2966d 100644 --- a/apps/sim/tools/gong/list_calls.ts +++ b/apps/sim/tools/gong/list_calls.ts @@ -1,4 +1,5 @@ import type { GongListCallsParams, GongListCallsResponse } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const listCallsTool: ToolConfig = { @@ -31,7 +32,7 @@ export const listCallsTool: ToolConfig { const url = new URL('https://api.gong.io/v2/calls') - url.searchParams.set('fromDateTime', params.fromDateTime) - if (params.toDateTime) url.searchParams.set('toDateTime', params.toDateTime) - if (params.cursor) url.searchParams.set('cursor', params.cursor) - if (params.workspaceId) url.searchParams.set('workspaceId', params.workspaceId) + url.searchParams.set('fromDateTime', params.fromDateTime.trim()) + url.searchParams.set('toDateTime', params.toDateTime?.trim() || new Date().toISOString()) + if (params.cursor?.trim()) url.searchParams.set('cursor', params.cursor.trim()) + if (params.workspaceId?.trim()) url.searchParams.set('workspaceId', params.workspaceId.trim()) return url.toString() }, method: 'GET', @@ -66,7 +67,7 @@ export const listCallsTool: ToolConfig { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to list calls') + throw new Error(getGongErrorMessage(data, 'Failed to list calls')) } const calls = (data.calls ?? []).map((call: Record) => ({ id: call.id ?? '', @@ -93,14 +94,22 @@ export const listCallsTool: ToolConfig = { @@ -45,9 +46,9 @@ export const listFlowsTool: ToolConfig { const url = new URL('https://api.gong.io/v2/flows') - url.searchParams.set('flowOwnerEmail', params.flowOwnerEmail) - if (params.workspaceId) url.searchParams.set('workspaceId', params.workspaceId) - if (params.cursor) url.searchParams.set('cursor', params.cursor) + url.searchParams.set('flowEmailOwner', params.flowOwnerEmail.trim()) + if (params.workspaceId) url.searchParams.set('workspaceId', params.workspaceId.trim()) + if (params.cursor?.trim()) url.searchParams.set('cursor', params.cursor.trim()) return url.toString() }, method: 'GET', @@ -60,7 +61,7 @@ export const listFlowsTool: ToolConfig { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to list flows') + throw new Error(getGongErrorMessage(data, 'Failed to list flows')) } const flows = (data.flows ?? []).map((f: Record) => ({ id: f.id ?? '', diff --git a/apps/sim/tools/gong/list_library_folders.ts b/apps/sim/tools/gong/list_library_folders.ts index d947a4f78ba..e3d77b9a7a5 100644 --- a/apps/sim/tools/gong/list_library_folders.ts +++ b/apps/sim/tools/gong/list_library_folders.ts @@ -2,6 +2,7 @@ import type { GongListLibraryFoldersParams, GongListLibraryFoldersResponse, } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const listLibraryFoldersTool: ToolConfig< @@ -37,7 +38,7 @@ export const listLibraryFoldersTool: ToolConfig< request: { url: (params) => { const url = new URL('https://api.gong.io/v2/library/folders') - if (params.workspaceId) url.searchParams.set('workspaceId', params.workspaceId) + if (params.workspaceId?.trim()) url.searchParams.set('workspaceId', params.workspaceId.trim()) return url.toString() }, method: 'GET', @@ -50,7 +51,7 @@ export const listLibraryFoldersTool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to list library folders') + throw new Error(getGongErrorMessage(data, 'Failed to list library folders')) } const folders = (data.folders ?? []).map((f: Record) => ({ id: f.id ?? '', diff --git a/apps/sim/tools/gong/list_scorecards.ts b/apps/sim/tools/gong/list_scorecards.ts index 742b520ced9..c08fb1a018a 100644 --- a/apps/sim/tools/gong/list_scorecards.ts +++ b/apps/sim/tools/gong/list_scorecards.ts @@ -1,4 +1,5 @@ import type { GongListScorecardsParams, GongListScorecardsResponse } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const listScorecardsTool: ToolConfig = @@ -35,7 +36,7 @@ export const listScorecardsTool: ToolConfig { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to list scorecards') + throw new Error(getGongErrorMessage(data, 'Failed to list scorecards')) } const scorecards = (data.scorecards ?? []).map((sc: Record) => ({ scorecardId: sc.scorecardId ?? '', diff --git a/apps/sim/tools/gong/list_trackers.ts b/apps/sim/tools/gong/list_trackers.ts index 2c54e3eea84..ff0d9055fa9 100644 --- a/apps/sim/tools/gong/list_trackers.ts +++ b/apps/sim/tools/gong/list_trackers.ts @@ -1,4 +1,5 @@ import type { GongListTrackersParams, GongListTrackersResponse } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const listTrackersTool: ToolConfig = { @@ -32,7 +33,7 @@ export const listTrackersTool: ToolConfig { const url = new URL('https://api.gong.io/v2/settings/trackers') - if (params.workspaceId) url.searchParams.set('workspaceId', params.workspaceId) + if (params.workspaceId?.trim()) url.searchParams.set('workspaceId', params.workspaceId.trim()) return url.toString() }, method: 'GET', @@ -45,7 +46,7 @@ export const listTrackersTool: ToolConfig { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to list trackers') + throw new Error(getGongErrorMessage(data, 'Failed to list trackers')) } const trackers = (data.keywordTrackers ?? []).map((t: Record) => ({ trackerId: t.trackerId ?? '', diff --git a/apps/sim/tools/gong/list_users.ts b/apps/sim/tools/gong/list_users.ts index 54ac8303934..b829075eacc 100644 --- a/apps/sim/tools/gong/list_users.ts +++ b/apps/sim/tools/gong/list_users.ts @@ -1,4 +1,5 @@ import type { GongListUsersParams, GongListUsersResponse } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const listUsersTool: ToolConfig = { @@ -37,7 +38,7 @@ export const listUsersTool: ToolConfig { const url = new URL('https://api.gong.io/v2/users') - if (params.cursor) url.searchParams.set('cursor', params.cursor) + if (params.cursor?.trim()) url.searchParams.set('cursor', params.cursor.trim()) if (params.includeAvatars) url.searchParams.set('includeAvatars', params.includeAvatars) return url.toString() }, @@ -51,7 +52,7 @@ export const listUsersTool: ToolConfig { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to list users') + throw new Error(getGongErrorMessage(data, 'Failed to list users')) } const users = (data.users ?? []).map((user: Record) => ({ id: user.id ?? '', @@ -74,6 +75,7 @@ export const listUsersTool: ToolConfig = @@ -35,7 +36,7 @@ export const listWorkspacesTool: ToolConfig { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to list workspaces') + throw new Error(getGongErrorMessage(data, 'Failed to list workspaces')) } const workspaces = (data.workspaces ?? []).map((w: Record) => ({ id: w.id ?? '', diff --git a/apps/sim/tools/gong/lookup_email.ts b/apps/sim/tools/gong/lookup_email.ts index 16e9376830f..57076d4df1f 100644 --- a/apps/sim/tools/gong/lookup_email.ts +++ b/apps/sim/tools/gong/lookup_email.ts @@ -1,4 +1,5 @@ import type { GongLookupEmailParams, GongLookupEmailResponse } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const lookupEmailTool: ToolConfig = { @@ -32,7 +33,7 @@ export const lookupEmailTool: ToolConfig { const url = new URL('https://api.gong.io/v2/data-privacy/data-for-email-address') - url.searchParams.set('emailAddress', params.emailAddress) + url.searchParams.set('emailAddress', params.emailAddress.trim()) return url.toString() }, method: 'GET', @@ -45,7 +46,7 @@ export const lookupEmailTool: ToolConfig { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to lookup email address') + throw new Error(getGongErrorMessage(data, 'Failed to lookup email address')) } return { success: true, diff --git a/apps/sim/tools/gong/lookup_phone.ts b/apps/sim/tools/gong/lookup_phone.ts index fd5c214de24..9101d40b9dd 100644 --- a/apps/sim/tools/gong/lookup_phone.ts +++ b/apps/sim/tools/gong/lookup_phone.ts @@ -1,4 +1,5 @@ import type { GongLookupPhoneParams, GongLookupPhoneResponse } from '@/tools/gong/types' +import { getGongErrorMessage } from '@/tools/gong/utils' import type { ToolConfig } from '@/tools/types' export const lookupPhoneTool: ToolConfig = { @@ -32,7 +33,7 @@ export const lookupPhoneTool: ToolConfig { const url = new URL('https://api.gong.io/v2/data-privacy/data-for-phone-number') - url.searchParams.set('phoneNumber', params.phoneNumber) + url.searchParams.set('phoneNumber', params.phoneNumber.trim()) return url.toString() }, method: 'GET', @@ -45,7 +46,7 @@ export const lookupPhoneTool: ToolConfig { const data = await response.json() if (!response.ok) { - throw new Error(data.errors?.[0]?.message || data.message || 'Failed to lookup phone number') + throw new Error(getGongErrorMessage(data, 'Failed to lookup phone number')) } return { success: true, diff --git a/apps/sim/tools/gong/types.ts b/apps/sim/tools/gong/types.ts index 71d6a92da5c..55d7c9b3c94 100644 --- a/apps/sim/tools/gong/types.ts +++ b/apps/sim/tools/gong/types.ts @@ -14,6 +14,30 @@ export interface GongListCallsParams extends GongBaseParams { workspaceId?: string } +/** Create Call */ +export interface GongCreateCallParams extends GongBaseParams { + clientUniqueId: string + actualStart: string + primaryUser: string + parties: unknown + direction: string + downloadMediaUrl: string + title?: string + workspaceId?: string + disposition?: string + purpose?: string + context?: unknown + callProviderCode?: string +} + +export interface GongCreateCallResponse extends ToolResponse { + output: { + callId: string + requestId: string + url: string | null + } +} + interface GongCallBasic { id: string title: string | null @@ -52,9 +76,12 @@ interface GongParty { export interface GongListCallsResponse extends ToolResponse { output: { + requestId: string | null calls: GongCallBasic[] cursor: string | null totalRecords: number + currentPageSize: number | null + currentPageNumber: number | null } } @@ -168,6 +195,7 @@ interface GongUser { export interface GongListUsersResponse extends ToolResponse { output: { + requestId: string | null users: GongUser[] cursor: string | null totalRecords: number | null @@ -585,6 +613,7 @@ export interface GongLookupPhoneResponse extends ToolResponse { /** Union type for all Gong responses */ export type GongResponse = | GongListCallsResponse + | GongCreateCallResponse | GongGetCallResponse | GongGetCallTranscriptResponse | GongGetExtensiveCallsResponse diff --git a/apps/sim/tools/gong/utils.ts b/apps/sim/tools/gong/utils.ts new file mode 100644 index 00000000000..06c725e5504 --- /dev/null +++ b/apps/sim/tools/gong/utils.ts @@ -0,0 +1,68 @@ +/** + * Extract a useful Gong API error message from documented error payloads. + */ +export function getGongErrorMessage(data: unknown, fallback: string): string { + if (!data || typeof data !== 'object') { + return fallback + } + + const payload = data as Record + const firstError = Array.isArray(payload.errors) ? payload.errors[0] : undefined + if (typeof firstError === 'string' && firstError.trim()) { + return firstError + } + if (firstError && typeof firstError === 'object') { + const message = (firstError as Record).message + if (typeof message === 'string' && message.trim()) { + return message + } + } + if (typeof payload.message === 'string' && payload.message.trim()) { + return payload.message + } + + return fallback +} + +/** + * Normalize comma-separated Gong IDs from block text inputs. + */ +export function parseGongIdList(value?: string): string[] | undefined { + if (!value) { + return undefined + } + + const ids = value + .split(',') + .map((id) => id.trim()) + .filter(Boolean) + + return ids.length > 0 ? ids : undefined +} + +/** + * Parse a JSON object or array field that may already be resolved to structured data. + */ +export function parseGongJsonField(value: unknown, fieldName: string): T { + if (typeof value === 'string') { + try { + return JSON.parse(value) as T + } catch { + throw new Error(`${fieldName} must be valid JSON`) + } + } + + return value as T +} + +/** + * Parse and validate a JSON array field. + */ +export function parseGongJsonArray(value: unknown, fieldName: string): unknown[] { + const parsed = parseGongJsonField(value, fieldName) + if (!Array.isArray(parsed)) { + throw new Error(`${fieldName} must be a JSON array`) + } + + return parsed +} diff --git a/apps/sim/tools/incidentio/actions_list.ts b/apps/sim/tools/incidentio/actions_list.ts index 35e2fe02c8c..5c81c556647 100644 --- a/apps/sim/tools/incidentio/actions_list.ts +++ b/apps/sim/tools/incidentio/actions_list.ts @@ -26,6 +26,13 @@ export const actionsListTool: ToolConfig< visibility: 'user-or-llm', description: 'Filter actions by incident ID (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")', }, + incident_mode: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Filter actions by incident mode (standard, retrospective, test, tutorial, or stream)', + }, }, request: { @@ -33,7 +40,11 @@ export const actionsListTool: ToolConfig< const url = new URL('https://api.incident.io/v2/actions') if (params.incident_id) { - url.searchParams.append('incident_id', params.incident_id) + url.searchParams.append('incident_id', params.incident_id.trim()) + } + + if (params.incident_mode) { + url.searchParams.append('incident_mode', params.incident_mode) } return url.toString() diff --git a/apps/sim/tools/incidentio/actions_show.ts b/apps/sim/tools/incidentio/actions_show.ts index d18e1ce83f5..04d506bfb28 100644 --- a/apps/sim/tools/incidentio/actions_show.ts +++ b/apps/sim/tools/incidentio/actions_show.ts @@ -29,7 +29,7 @@ export const actionsShowTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/actions/${params.id}`, + url: (params) => `https://api.incident.io/v2/actions/${params.id.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/custom_fields_delete.ts b/apps/sim/tools/incidentio/custom_fields_delete.ts index 3e2dad99579..cf022423eb1 100644 --- a/apps/sim/tools/incidentio/custom_fields_delete.ts +++ b/apps/sim/tools/incidentio/custom_fields_delete.ts @@ -26,7 +26,7 @@ export const customFieldsDeleteTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/custom_fields/${params.id}`, + url: (params) => `https://api.incident.io/v2/custom_fields/${params.id.trim()}`, method: 'DELETE', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/custom_fields_show.ts b/apps/sim/tools/incidentio/custom_fields_show.ts index ec96b021e35..c0589dec580 100644 --- a/apps/sim/tools/incidentio/custom_fields_show.ts +++ b/apps/sim/tools/incidentio/custom_fields_show.ts @@ -23,7 +23,7 @@ export const customFieldsShowTool: ToolConfig `https://api.incident.io/v2/custom_fields/${params.id}`, + url: (params) => `https://api.incident.io/v2/custom_fields/${params.id.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/custom_fields_update.ts b/apps/sim/tools/incidentio/custom_fields_update.ts index f8d8410b62a..de1d5151ae3 100644 --- a/apps/sim/tools/incidentio/custom_fields_update.ts +++ b/apps/sim/tools/incidentio/custom_fields_update.ts @@ -38,7 +38,7 @@ export const customFieldsUpdateTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/custom_fields/${params.id}`, + url: (params) => `https://api.incident.io/v2/custom_fields/${params.id.trim()}`, method: 'PUT', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/escalation_paths_create.ts b/apps/sim/tools/incidentio/escalation_paths_create.ts index 8794bdd033b..b4a4ee48a8d 100644 --- a/apps/sim/tools/incidentio/escalation_paths_create.ts +++ b/apps/sim/tools/incidentio/escalation_paths_create.ts @@ -49,7 +49,7 @@ export const escalationPathsCreateTool: ToolConfig< Authorization: `Bearer ${params.apiKey}`, }), body: (params) => { - const body: Record = { + const body: Record = { name: params.name, path: params.path, } @@ -128,8 +128,6 @@ export const escalationPathsCreateTool: ToolConfig< }, }, }, - created_at: { type: 'string', description: 'When the path was created' }, - updated_at: { type: 'string', description: 'When the path was last updated' }, }, }, }, diff --git a/apps/sim/tools/incidentio/escalation_paths_delete.ts b/apps/sim/tools/incidentio/escalation_paths_delete.ts index 1bb73935e0a..ba70fa8f294 100644 --- a/apps/sim/tools/incidentio/escalation_paths_delete.ts +++ b/apps/sim/tools/incidentio/escalation_paths_delete.ts @@ -29,7 +29,7 @@ export const escalationPathsDeleteTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id}`, + url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id.trim()}`, method: 'DELETE', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/escalation_paths_list.ts b/apps/sim/tools/incidentio/escalation_paths_list.ts new file mode 100644 index 00000000000..e92d78b4c72 --- /dev/null +++ b/apps/sim/tools/incidentio/escalation_paths_list.ts @@ -0,0 +1,96 @@ +import type { + IncidentioEscalationPathsListParams, + IncidentioEscalationPathsListResponse, +} from '@/tools/incidentio/types' +import type { ToolConfig } from '@/tools/types' + +export const escalationPathsListTool: ToolConfig< + IncidentioEscalationPathsListParams, + IncidentioEscalationPathsListResponse +> = { + id: 'incidentio_escalation_paths_list', + name: 'List Escalation Paths', + description: 'List escalation paths in incident.io', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'incident.io API Key', + }, + page_size: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Number of escalation paths to return per page', + }, + after: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor to fetch the next page of results', + }, + }, + + request: { + url: (params) => { + const url = new URL('https://api.incident.io/v2/escalation_paths') + if (params.page_size) url.searchParams.set('page_size', params.page_size.toString()) + if (params.after) url.searchParams.set('after', params.after) + return url.toString() + }, + method: 'GET', + headers: (params) => ({ + 'Content-Type': 'application/json', + Authorization: `Bearer ${params.apiKey}`, + }), + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + + return { + success: true, + output: { + escalation_paths: data.escalation_paths ?? [], + pagination_meta: data.pagination_meta + ? { + after: data.pagination_meta.after, + page_size: data.pagination_meta.page_size, + } + : undefined, + }, + } + }, + + outputs: { + escalation_paths: { + type: 'array', + description: 'List of escalation paths', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'The escalation path ID' }, + name: { type: 'string', description: 'The escalation path name' }, + path: { type: 'array', description: 'Array of escalation levels' }, + working_hours: { + type: 'array', + description: 'Working hours configuration', + optional: true, + }, + }, + }, + }, + pagination_meta: { + type: 'object', + description: 'Pagination metadata', + optional: true, + properties: { + after: { type: 'string', description: 'Cursor for next page', optional: true }, + page_size: { type: 'number', description: 'Number of results per page' }, + }, + }, + }, +} diff --git a/apps/sim/tools/incidentio/escalation_paths_show.ts b/apps/sim/tools/incidentio/escalation_paths_show.ts index 5b188f56a49..ffb9b887d9e 100644 --- a/apps/sim/tools/incidentio/escalation_paths_show.ts +++ b/apps/sim/tools/incidentio/escalation_paths_show.ts @@ -29,7 +29,7 @@ export const escalationPathsShowTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id}`, + url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', @@ -103,8 +103,6 @@ export const escalationPathsShowTool: ToolConfig< }, }, }, - created_at: { type: 'string', description: 'When the path was created' }, - updated_at: { type: 'string', description: 'When the path was last updated' }, }, }, }, diff --git a/apps/sim/tools/incidentio/escalation_paths_update.ts b/apps/sim/tools/incidentio/escalation_paths_update.ts index f1829ed5934..c4a27972ee5 100644 --- a/apps/sim/tools/incidentio/escalation_paths_update.ts +++ b/apps/sim/tools/incidentio/escalation_paths_update.ts @@ -28,13 +28,13 @@ export const escalationPathsUpdateTool: ToolConfig< }, name: { type: 'string', - required: false, + required: true, visibility: 'user-or-llm', description: 'New name for the escalation path (e.g., "Critical Incident Path")', }, path: { type: 'json', - required: false, + required: true, visibility: 'user-or-llm', description: 'New escalation path configuration. Array of escalation levels with targets and time_to_ack_seconds', @@ -48,21 +48,16 @@ export const escalationPathsUpdateTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id}`, + url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id.trim()}`, method: 'PUT', headers: (params) => ({ 'Content-Type': 'application/json', Authorization: `Bearer ${params.apiKey}`, }), body: (params) => { - const body: Record = {} - - if (params.name !== undefined) { - body.name = params.name - } - - if (params.path !== undefined) { - body.path = params.path + const body: Record = { + name: params.name, + path: params.path, } if (params.working_hours !== undefined) { @@ -139,8 +134,6 @@ export const escalationPathsUpdateTool: ToolConfig< }, }, }, - created_at: { type: 'string', description: 'When the path was created' }, - updated_at: { type: 'string', description: 'When the path was last updated' }, }, }, }, diff --git a/apps/sim/tools/incidentio/escalations_list.ts b/apps/sim/tools/incidentio/escalations_list.ts index 5d5f76f7b90..01da43ecbee 100644 --- a/apps/sim/tools/incidentio/escalations_list.ts +++ b/apps/sim/tools/incidentio/escalations_list.ts @@ -20,10 +20,27 @@ export const escalationsListTool: ToolConfig< visibility: 'user-only', description: 'incident.io API Key', }, + page_size: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Number of escalations to return per page', + }, + after: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor to fetch the next page of results', + }, }, request: { - url: () => 'https://api.incident.io/v2/escalations', + url: (params) => { + const url = new URL('https://api.incident.io/v2/escalations') + if (params.page_size) url.searchParams.set('page_size', params.page_size.toString()) + if (params.after) url.searchParams.set('after', params.after) + return url.toString() + }, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', @@ -38,6 +55,12 @@ export const escalationsListTool: ToolConfig< success: true, output: { escalations: data.escalations || [], + pagination_meta: data.pagination_meta + ? { + after: data.pagination_meta.after, + page_size: data.pagination_meta.page_size, + } + : undefined, }, } }, @@ -59,5 +82,14 @@ export const escalationsListTool: ToolConfig< }, }, }, + pagination_meta: { + type: 'object', + description: 'Pagination metadata', + optional: true, + properties: { + after: { type: 'string', description: 'Cursor for next page', optional: true }, + page_size: { type: 'number', description: 'Number of results per page' }, + }, + }, }, } diff --git a/apps/sim/tools/incidentio/escalations_show.ts b/apps/sim/tools/incidentio/escalations_show.ts index 8606de600cf..469f01ce4eb 100644 --- a/apps/sim/tools/incidentio/escalations_show.ts +++ b/apps/sim/tools/incidentio/escalations_show.ts @@ -29,7 +29,7 @@ export const escalationsShowTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/escalations/${params.id}`, + url: (params) => `https://api.incident.io/v2/escalations/${params.id.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/follow_ups_list.ts b/apps/sim/tools/incidentio/follow_ups_list.ts index 603547b43e0..9fd33864779 100644 --- a/apps/sim/tools/incidentio/follow_ups_list.ts +++ b/apps/sim/tools/incidentio/follow_ups_list.ts @@ -26,6 +26,13 @@ export const followUpsListTool: ToolConfig< visibility: 'user-or-llm', description: 'Filter follow-ups by incident ID (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")', }, + incident_mode: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Filter follow-ups by incident mode (standard, retrospective, test, tutorial, or stream)', + }, }, request: { @@ -33,7 +40,11 @@ export const followUpsListTool: ToolConfig< const url = new URL('https://api.incident.io/v2/follow_ups') if (params.incident_id) { - url.searchParams.append('incident_id', params.incident_id) + url.searchParams.append('incident_id', params.incident_id.trim()) + } + + if (params.incident_mode) { + url.searchParams.append('incident_mode', params.incident_mode) } return url.toString() diff --git a/apps/sim/tools/incidentio/follow_ups_show.ts b/apps/sim/tools/incidentio/follow_ups_show.ts index 4dc62d1042a..495be6d7b4e 100644 --- a/apps/sim/tools/incidentio/follow_ups_show.ts +++ b/apps/sim/tools/incidentio/follow_ups_show.ts @@ -29,7 +29,7 @@ export const followUpsShowTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/follow_ups/${params.id}`, + url: (params) => `https://api.incident.io/v2/follow_ups/${params.id.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/incident_roles_delete.ts b/apps/sim/tools/incidentio/incident_roles_delete.ts index 93472c6f95b..c28c9ae5796 100644 --- a/apps/sim/tools/incidentio/incident_roles_delete.ts +++ b/apps/sim/tools/incidentio/incident_roles_delete.ts @@ -29,7 +29,7 @@ export const incidentRolesDeleteTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/incident_roles/${params.id}`, + url: (params) => `https://api.incident.io/v2/incident_roles/${params.id.trim()}`, method: 'DELETE', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/incident_roles_show.ts b/apps/sim/tools/incidentio/incident_roles_show.ts index 7e4b5813362..97d4355ed22 100644 --- a/apps/sim/tools/incidentio/incident_roles_show.ts +++ b/apps/sim/tools/incidentio/incident_roles_show.ts @@ -29,7 +29,7 @@ export const incidentRolesShowTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/incident_roles/${params.id}`, + url: (params) => `https://api.incident.io/v2/incident_roles/${params.id.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/incident_roles_update.ts b/apps/sim/tools/incidentio/incident_roles_update.ts index a27bfca02ad..ca325f713a9 100644 --- a/apps/sim/tools/incidentio/incident_roles_update.ts +++ b/apps/sim/tools/incidentio/incident_roles_update.ts @@ -53,7 +53,7 @@ export const incidentRolesUpdateTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/incident_roles/${params.id}`, + url: (params) => `https://api.incident.io/v2/incident_roles/${params.id.trim()}`, method: 'PUT', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/incident_timestamps_show.ts b/apps/sim/tools/incidentio/incident_timestamps_show.ts index 2640c4c126a..b2425d3103e 100644 --- a/apps/sim/tools/incidentio/incident_timestamps_show.ts +++ b/apps/sim/tools/incidentio/incident_timestamps_show.ts @@ -29,7 +29,7 @@ export const incidentTimestampsShowTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/incident_timestamps/${params.id}`, + url: (params) => `https://api.incident.io/v2/incident_timestamps/${params.id.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/incident_updates_list.ts b/apps/sim/tools/incidentio/incident_updates_list.ts index 2501f33bdba..2d738b7221f 100644 --- a/apps/sim/tools/incidentio/incident_updates_list.ts +++ b/apps/sim/tools/incidentio/incident_updates_list.ts @@ -43,22 +43,21 @@ export const incidentUpdatesListTool: ToolConfig< request: { url: (params) => { - const queryParams: string[] = [] + const url = new URL('https://api.incident.io/v2/incident_updates') if (params.incident_id) { - queryParams.push(`incident_id=${params.incident_id}`) + url.searchParams.set('incident_id', params.incident_id.trim()) } if (params.page_size) { - queryParams.push(`page_size=${params.page_size}`) + url.searchParams.set('page_size', params.page_size.toString()) } if (params.after) { - queryParams.push(`after=${params.after}`) + url.searchParams.set('after', params.after.trim()) } - const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : '' - return `https://api.incident.io/v2/incident_updates${queryString}` + return url.toString() }, method: 'GET', headers: (params) => ({ diff --git a/apps/sim/tools/incidentio/incidents_list.ts b/apps/sim/tools/incidentio/incidents_list.ts index 85a076c40f2..f27907db675 100644 --- a/apps/sim/tools/incidentio/incidents_list.ts +++ b/apps/sim/tools/incidentio/incidents_list.ts @@ -38,6 +38,18 @@ export const incidentsListTool: ToolConfig< description: 'Pagination cursor to fetch the next page of results (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")', }, + sort_by: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Sort order for incidents: created_at_newest_first or created_at_oldest_first', + }, + filter_mode: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'How to combine filters: all or any', + }, }, request: { @@ -49,7 +61,15 @@ export const incidentsListTool: ToolConfig< } if (params.after) { - url.searchParams.append('after', params.after) + url.searchParams.append('after', params.after.trim()) + } + + if (params.sort_by) { + url.searchParams.append('sort_by', params.sort_by) + } + + if (params.filter_mode) { + url.searchParams.append('filter_mode', params.filter_mode) } return url.toString() diff --git a/apps/sim/tools/incidentio/incidents_show.ts b/apps/sim/tools/incidentio/incidents_show.ts index 8996fa50f3b..3421d12ec5b 100644 --- a/apps/sim/tools/incidentio/incidents_show.ts +++ b/apps/sim/tools/incidentio/incidents_show.ts @@ -30,7 +30,7 @@ export const incidentsShowTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/incidents/${params.id}`, + url: (params) => `https://api.incident.io/v2/incidents/${params.id.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/incidents_update.ts b/apps/sim/tools/incidentio/incidents_update.ts index 465bea2eb78..15e8a881a0f 100644 --- a/apps/sim/tools/incidentio/incidents_update.ts +++ b/apps/sim/tools/incidentio/incidents_update.ts @@ -67,7 +67,7 @@ export const incidentsUpdateTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/incidents/${params.id}/actions/edit`, + url: (params) => `https://api.incident.io/v2/incidents/${params.id.trim()}/actions/edit`, method: 'POST', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/index.ts b/apps/sim/tools/incidentio/index.ts index ae4470e7c90..91faa4b09bd 100644 --- a/apps/sim/tools/incidentio/index.ts +++ b/apps/sim/tools/incidentio/index.ts @@ -7,6 +7,7 @@ import { customFieldsShowTool } from '@/tools/incidentio/custom_fields_show' import { customFieldsUpdateTool } from '@/tools/incidentio/custom_fields_update' import { escalationPathsCreateTool } from '@/tools/incidentio/escalation_paths_create' import { escalationPathsDeleteTool } from '@/tools/incidentio/escalation_paths_delete' +import { escalationPathsListTool } from '@/tools/incidentio/escalation_paths_list' import { escalationPathsShowTool } from '@/tools/incidentio/escalation_paths_show' import { escalationPathsUpdateTool } from '@/tools/incidentio/escalation_paths_update' import { escalationsCreateTool } from '@/tools/incidentio/escalations_create' @@ -85,7 +86,10 @@ export const incidentioIncidentTimestampsShowTool = incidentTimestampsShowTool export const incidentioIncidentUpdatesListTool = incidentUpdatesListTool export const incidentioScheduleEntriesListTool = scheduleEntriesListTool export const incidentioScheduleOverridesCreateTool = scheduleOverridesCreateTool +export const incidentioEscalationPathsListTool = escalationPathsListTool export const incidentioEscalationPathsCreateTool = escalationPathsCreateTool export const incidentioEscalationPathsShowTool = escalationPathsShowTool export const incidentioEscalationPathsUpdateTool = escalationPathsUpdateTool export const incidentioEscalationPathsDeleteTool = escalationPathsDeleteTool + +export * from '@/tools/incidentio/types' diff --git a/apps/sim/tools/incidentio/schedule_entries_list.ts b/apps/sim/tools/incidentio/schedule_entries_list.ts index cf7633f3d07..d3d601622ff 100644 --- a/apps/sim/tools/incidentio/schedule_entries_list.ts +++ b/apps/sim/tools/incidentio/schedule_entries_list.ts @@ -40,44 +40,23 @@ export const scheduleEntriesListTool: ToolConfig< description: 'End date/time to filter entries in ISO 8601 format (e.g., "2024-01-22T09:00:00Z")', }, - page_size: { - type: 'number', - required: false, - visibility: 'user-or-llm', - description: 'Number of results to return per page (e.g., 10, 25, 50)', - }, - after: { - type: 'string', - required: false, - visibility: 'user-or-llm', - description: 'Cursor for pagination (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")', - }, }, request: { url: (params) => { - const queryParams: string[] = [] + const url = new URL('https://api.incident.io/v2/schedule_entries') - queryParams.push(`schedule_id=${params.schedule_id}`) + url.searchParams.set('schedule_id', params.schedule_id.trim()) if (params.entry_window_start) { - queryParams.push(`entry_window_start=${encodeURIComponent(params.entry_window_start)}`) + url.searchParams.set('entry_window_start', params.entry_window_start) } if (params.entry_window_end) { - queryParams.push(`entry_window_end=${encodeURIComponent(params.entry_window_end)}`) + url.searchParams.set('entry_window_end', params.entry_window_end) } - if (params.page_size) { - queryParams.push(`page_size=${params.page_size}`) - } - - if (params.after) { - queryParams.push(`after=${params.after}`) - } - - const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : '' - return `https://api.incident.io/v2/schedule_entries${queryString}` + return url.toString() }, method: 'GET', headers: (params) => ({ @@ -92,7 +71,11 @@ export const scheduleEntriesListTool: ToolConfig< return { success: true, output: { - schedule_entries: data.schedule_entries || data, + schedule_entries: { + final: data.schedule_entries?.final ?? [], + overrides: data.schedule_entries?.overrides ?? [], + scheduled: data.schedule_entries?.scheduled ?? [], + }, pagination_meta: data.pagination_meta, }, } @@ -100,28 +83,12 @@ export const scheduleEntriesListTool: ToolConfig< outputs: { schedule_entries: { - type: 'array', - description: 'List of schedule entries', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'The entry ID' }, - schedule_id: { type: 'string', description: 'The schedule ID' }, - user: { - type: 'object', - description: 'User assigned to this entry', - properties: { - id: { type: 'string', description: 'User ID' }, - name: { type: 'string', description: 'User name' }, - email: { type: 'string', description: 'User email' }, - }, - }, - start_at: { type: 'string', description: 'When the entry starts' }, - end_at: { type: 'string', description: 'When the entry ends' }, - layer_id: { type: 'string', description: 'The schedule layer ID' }, - created_at: { type: 'string', description: 'When the entry was created' }, - updated_at: { type: 'string', description: 'When the entry was last updated' }, - }, + type: 'object', + description: 'Schedule entries grouped by final, overrides, and scheduled entries', + properties: { + final: { type: 'array', description: 'Final computed schedule entries' }, + overrides: { type: 'array', description: 'Override schedule entries' }, + scheduled: { type: 'array', description: 'Scheduled entries before overrides are applied' }, }, }, pagination_meta: { @@ -131,7 +98,6 @@ export const scheduleEntriesListTool: ToolConfig< properties: { after: { type: 'string', description: 'Cursor for next page', optional: true }, after_url: { type: 'string', description: 'URL for next page', optional: true }, - page_size: { type: 'number', description: 'Number of results per page' }, }, }, }, diff --git a/apps/sim/tools/incidentio/schedule_overrides_create.ts b/apps/sim/tools/incidentio/schedule_overrides_create.ts index 75b1a87a8a7..7c4858c271a 100644 --- a/apps/sim/tools/incidentio/schedule_overrides_create.ts +++ b/apps/sim/tools/incidentio/schedule_overrides_create.ts @@ -26,6 +26,12 @@ export const scheduleOverridesCreateTool: ToolConfig< visibility: 'user-or-llm', description: 'The ID of the rotation to override (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")', }, + layer_id: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'The ID of the layer this override applies to', + }, schedule_id: { type: 'string', required: true, @@ -81,6 +87,7 @@ export const scheduleOverridesCreateTool: ToolConfig< if (params.user_slack_id) user.slack_user_id = params.user_slack_id return { + layer_id: params.layer_id.trim(), rotation_id: params.rotation_id, schedule_id: params.schedule_id, user, @@ -107,6 +114,7 @@ export const scheduleOverridesCreateTool: ToolConfig< description: 'The created schedule override', properties: { id: { type: 'string', description: 'The override ID' }, + layer_id: { type: 'string', description: 'The schedule layer ID' }, rotation_id: { type: 'string', description: 'The rotation ID' }, schedule_id: { type: 'string', description: 'The schedule ID' }, user: { diff --git a/apps/sim/tools/incidentio/schedules_delete.ts b/apps/sim/tools/incidentio/schedules_delete.ts index 928a1d7780c..4a1fc8829aa 100644 --- a/apps/sim/tools/incidentio/schedules_delete.ts +++ b/apps/sim/tools/incidentio/schedules_delete.ts @@ -29,7 +29,7 @@ export const schedulesDeleteTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/schedules/${params.id}`, + url: (params) => `https://api.incident.io/v2/schedules/${params.id.trim()}`, method: 'DELETE', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/schedules_show.ts b/apps/sim/tools/incidentio/schedules_show.ts index fa21c21a18a..146721e379b 100644 --- a/apps/sim/tools/incidentio/schedules_show.ts +++ b/apps/sim/tools/incidentio/schedules_show.ts @@ -29,7 +29,7 @@ export const schedulesShowTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/schedules/${params.id}`, + url: (params) => `https://api.incident.io/v2/schedules/${params.id.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/schedules_update.ts b/apps/sim/tools/incidentio/schedules_update.ts index 6b962b20b93..a8a4802cc23 100644 --- a/apps/sim/tools/incidentio/schedules_update.ts +++ b/apps/sim/tools/incidentio/schedules_update.ts @@ -48,7 +48,7 @@ export const schedulesUpdateTool: ToolConfig< }, request: { - url: (params) => `https://api.incident.io/v2/schedules/${params.id}`, + url: (params) => `https://api.incident.io/v2/schedules/${params.id.trim()}`, method: 'PUT', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/types.ts b/apps/sim/tools/incidentio/types.ts index 317a6ca2691..c43971184f9 100644 --- a/apps/sim/tools/incidentio/types.ts +++ b/apps/sim/tools/incidentio/types.ts @@ -175,10 +175,31 @@ export const INCIDENTIO_FOLLOW_UP_OUTPUT: OutputProperty = { export const INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES = { id: { type: 'string', description: 'Workflow ID' }, name: { type: 'string', description: 'Workflow name' }, + trigger: { type: 'string', description: 'Workflow trigger' }, + once_for: { type: 'array', description: 'Fields that make the workflow run once' }, + version: { type: 'number', description: 'Workflow version' }, + expressions: { type: 'array', description: 'Workflow expressions' }, + condition_groups: { type: 'array', description: 'Workflow condition groups' }, + steps: { type: 'array', description: 'Workflow steps' }, + include_private_incidents: { + type: 'boolean', + description: 'Whether the workflow includes private incidents', + }, + include_private_escalations: { + type: 'boolean', + description: 'Whether the workflow includes private escalations', + }, + runs_on_incident_modes: { type: 'array', description: 'Incident modes the workflow runs on' }, + continue_on_step_error: { + type: 'boolean', + description: 'Whether execution continues after a step error', + }, + runs_on_incidents: { type: 'string', description: 'Incident lifecycle filter' }, state: { type: 'string', description: 'Workflow state (active, draft, disabled)' }, + delay: { type: 'object', description: 'Workflow delay configuration', optional: true }, folder: { type: 'string', description: 'Workflow folder', optional: true }, - created_at: { type: 'string', description: 'When the workflow was created', optional: true }, - updated_at: { type: 'string', description: 'When the workflow was last updated', optional: true }, + runs_from: { type: 'string', description: 'When the workflow runs from', optional: true }, + shortform: { type: 'string', description: 'Workflow shortform identifier', optional: true }, } as const satisfies Record /** @@ -279,6 +300,8 @@ interface IncidentioBaseParams { export interface IncidentioIncidentsListParams extends IncidentioBaseParams { page_size?: number after?: string + sort_by?: 'created_at_newest_first' | 'created_at_oldest_first' + filter_mode?: 'all' | 'any' } interface IncidentioIncident { @@ -396,6 +419,7 @@ export interface IncidentioIncidentsUpdateResponse extends ToolResponse { // Action types export interface IncidentioActionsListParams extends IncidentioBaseParams { incident_id?: string + incident_mode?: 'standard' | 'retrospective' | 'test' | 'tutorial' | 'stream' } interface IncidentioAction { @@ -445,6 +469,7 @@ export interface IncidentioActionsShowResponse extends ToolResponse { // Follow-up types export interface IncidentioFollowUpsListParams extends IncidentioBaseParams { incident_id?: string + incident_mode?: 'standard' | 'retrospective' | 'test' | 'tutorial' | 'stream' } interface IncidentioFollowUp { @@ -499,28 +524,33 @@ export interface IncidentioFollowUpsShowResponse extends ToolResponse { } // Workflow types -interface Workflow { +export interface Workflow { id: string name: string + trigger: string + once_for: unknown[] + version: number + expressions: unknown[] + condition_groups: unknown[] + steps: unknown[] + include_private_incidents: boolean + include_private_escalations: boolean + runs_on_incident_modes: string[] + continue_on_step_error: boolean + runs_on_incidents: 'newly_created' | 'newly_created_and_active' | 'active' | 'all' state: 'active' | 'draft' | 'disabled' + delay?: unknown folder?: string - created_at?: string - updated_at?: string + runs_from?: string + shortform?: string } // Workflows List tool types -export interface WorkflowsListParams extends IncidentioBaseParams { - page_size?: number - after?: string -} +export interface WorkflowsListParams extends IncidentioBaseParams {} export interface WorkflowsListResponse extends ToolResponse { output: { workflows: Workflow[] - pagination_meta?: { - after?: string - page_size: number - } } } @@ -543,6 +573,7 @@ export interface WorkflowsCreateParams extends IncidentioBaseParams { export interface WorkflowsCreateResponse extends ToolResponse { output: { + management_meta?: Record workflow: Workflow } } @@ -550,10 +581,12 @@ export interface WorkflowsCreateResponse extends ToolResponse { // Workflows Show tool types export interface WorkflowsShowParams extends IncidentioBaseParams { id: string + skip_step_upgrades?: boolean } export interface WorkflowsShowResponse extends ToolResponse { output: { + management_meta?: Record workflow: Workflow } } @@ -561,13 +594,23 @@ export interface WorkflowsShowResponse extends ToolResponse { // Workflows Update tool types export interface WorkflowsUpdateParams extends IncidentioBaseParams { id: string - name?: string + name: string + steps: string + condition_groups: string + runs_on_incidents: 'newly_created' | 'newly_created_and_active' | 'active' | 'all' + runs_on_incident_modes: string + include_private_incidents: boolean + continue_on_step_error: boolean + once_for: string + expressions: string state?: 'active' | 'draft' | 'disabled' folder?: string + delay?: string } export interface WorkflowsUpdateResponse extends ToolResponse { output: { + management_meta?: Record workflow: Workflow } } @@ -663,6 +706,8 @@ export interface CustomFieldsDeleteResponse extends ToolResponse { export interface IncidentioUsersListParams extends IncidentioBaseParams { page_size?: number after?: string + email?: string + slack_user_id?: string } interface IncidentioUser { @@ -784,13 +829,17 @@ export type IncidentioResponse = | IncidentioIncidentUpdatesListResponse | IncidentioScheduleEntriesListResponse | IncidentioScheduleOverridesCreateResponse + | IncidentioEscalationPathsListResponse | IncidentioEscalationPathsCreateResponse | IncidentioEscalationPathsShowResponse | IncidentioEscalationPathsUpdateResponse | IncidentioEscalationPathsDeleteResponse // Escalations types -export interface IncidentioEscalationsListParams extends IncidentioBaseParams {} +export interface IncidentioEscalationsListParams extends IncidentioBaseParams { + page_size?: number + after?: string +} interface IncidentioEscalation { id: string @@ -802,6 +851,10 @@ interface IncidentioEscalation { export interface IncidentioEscalationsListResponse extends ToolResponse { output: { escalations: IncidentioEscalation[] + pagination_meta?: { + after?: string + page_size: number + } } } @@ -1034,8 +1087,10 @@ export interface IncidentioIncidentUpdatesListResponse extends ToolResponse { // Schedule Entries types interface IncidentioScheduleEntry { - id: string - schedule_id: string + entry_id: string + fingerprint: string + rotation_id: string + layer_id: string user: { id: string name: string @@ -1043,26 +1098,24 @@ interface IncidentioScheduleEntry { } start_at: string end_at: string - layer_id: string - created_at: string - updated_at: string } export interface IncidentioScheduleEntriesListParams extends IncidentioBaseParams { schedule_id: string entry_window_start?: string entry_window_end?: string - page_size?: number - after?: string } export interface IncidentioScheduleEntriesListResponse extends ToolResponse { output: { - schedule_entries: IncidentioScheduleEntry[] + schedule_entries: { + final: IncidentioScheduleEntry[] + overrides: IncidentioScheduleEntry[] + scheduled: IncidentioScheduleEntry[] + } pagination_meta?: { after?: string after_url?: string - page_size: number } } } @@ -1070,6 +1123,7 @@ export interface IncidentioScheduleEntriesListResponse extends ToolResponse { // Schedule Overrides types interface IncidentioScheduleOverride { id: string + layer_id: string rotation_id: string schedule_id: string user: { @@ -1084,6 +1138,7 @@ interface IncidentioScheduleOverride { } export interface IncidentioScheduleOverridesCreateParams extends IncidentioBaseParams { + layer_id: string rotation_id: string schedule_id: string user_id?: string @@ -1122,8 +1177,21 @@ interface IncidentioEscalationPath { start_time: string end_time: string }> - created_at: string - updated_at: string +} + +export interface IncidentioEscalationPathsListParams extends IncidentioBaseParams { + page_size?: number + after?: string +} + +export interface IncidentioEscalationPathsListResponse extends ToolResponse { + output: { + escalation_paths: IncidentioEscalationPath[] + pagination_meta?: { + after?: string + page_size: number + } + } } export interface IncidentioEscalationPathsCreateParams extends IncidentioBaseParams { @@ -1163,8 +1231,8 @@ export interface IncidentioEscalationPathsShowResponse extends ToolResponse { export interface IncidentioEscalationPathsUpdateParams extends IncidentioBaseParams { id: string - name?: string - path?: Array<{ + name: string + path: Array<{ targets: Array<{ id: string type: string diff --git a/apps/sim/tools/incidentio/users_list.ts b/apps/sim/tools/incidentio/users_list.ts index cbf98291156..cfe56def211 100644 --- a/apps/sim/tools/incidentio/users_list.ts +++ b/apps/sim/tools/incidentio/users_list.ts @@ -31,6 +31,18 @@ export const usersListTool: ToolConfig `https://api.incident.io/v2/users/${params.id}`, + url: (params) => `https://api.incident.io/v2/users/${params.id.trim()}`, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/utils.ts b/apps/sim/tools/incidentio/utils.ts new file mode 100644 index 00000000000..c08e81f4433 --- /dev/null +++ b/apps/sim/tools/incidentio/utils.ts @@ -0,0 +1,73 @@ +import type { Workflow } from '@/tools/incidentio/types' + +function getJsonParseErrorMessage(error: unknown): string { + return error instanceof Error ? error.message : String(error) +} + +function toStringValue(value: unknown): string { + return typeof value === 'string' ? value : String(value ?? '') +} + +function toOptionalStringValue(value: unknown): string | undefined { + return typeof value === 'string' && value ? value : undefined +} + +function toNumberValue(value: unknown): number { + return typeof value === 'number' ? value : Number(value ?? 0) +} + +function toBooleanValue(value: unknown): boolean { + return value === true +} + +function toArrayValue(value: unknown): T[] { + return Array.isArray(value) ? (value as T[]) : [] +} + +export function parseIncidentioJsonParam( + jsonString: string | undefined, + paramName: string, + defaultValue: unknown +): unknown { + if (jsonString === undefined || jsonString === '') return defaultValue + + try { + return JSON.parse(jsonString) + } catch (error) { + throw new Error(`Invalid JSON for ${paramName}: ${getJsonParseErrorMessage(error)}`) + } +} + +export function parseRequiredIncidentioJsonParam( + jsonString: string | undefined, + paramName: string +): unknown { + if (jsonString === undefined || jsonString === '') { + throw new Error(`Missing required JSON for ${paramName}`) + } + + return parseIncidentioJsonParam(jsonString, paramName, undefined) +} + +export function mapIncidentioWorkflow(workflow: Record): Workflow { + return { + id: toStringValue(workflow.id), + name: toStringValue(workflow.name), + trigger: toStringValue(workflow.trigger), + once_for: toArrayValue(workflow.once_for), + version: toNumberValue(workflow.version), + expressions: toArrayValue(workflow.expressions), + condition_groups: toArrayValue(workflow.condition_groups), + steps: toArrayValue(workflow.steps), + include_private_incidents: toBooleanValue(workflow.include_private_incidents), + include_private_escalations: toBooleanValue(workflow.include_private_escalations), + runs_on_incident_modes: toArrayValue(workflow.runs_on_incident_modes), + continue_on_step_error: toBooleanValue(workflow.continue_on_step_error), + runs_on_incidents: toStringValue(workflow.runs_on_incidents) as Workflow['runs_on_incidents'], + state: toStringValue(workflow.state) as Workflow['state'], + delay: workflow.delay, + folder: toOptionalStringValue(workflow.folder), + runs_from: toOptionalStringValue(workflow.runs_from), + shortform: toOptionalStringValue(workflow.shortform), + } +} diff --git a/apps/sim/tools/incidentio/workflows_create.ts b/apps/sim/tools/incidentio/workflows_create.ts index 87c3e2cd023..4a22510986f 100644 --- a/apps/sim/tools/incidentio/workflows_create.ts +++ b/apps/sim/tools/incidentio/workflows_create.ts @@ -1,9 +1,8 @@ -import { createLogger } from '@sim/logger' import type { WorkflowsCreateParams, WorkflowsCreateResponse } from '@/tools/incidentio/types' +import { INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES } from '@/tools/incidentio/types' +import { mapIncidentioWorkflow, parseIncidentioJsonParam } from '@/tools/incidentio/utils' import type { ToolConfig } from '@/tools/types' -const logger = createLogger('IncidentIOCreate') - export const workflowsCreateTool: ToolConfig = { id: 'incidentio_workflows_create', name: 'incident.io Workflows Create', @@ -122,27 +121,19 @@ export const workflowsCreateTool: ToolConfig { - // Helper function to safely parse JSON strings - const parseJsonParam = (jsonString: string | undefined, defaultValue: any) => { - if (!jsonString) return defaultValue - try { - return JSON.parse(jsonString) - } catch (error) { - logger.warn(`Failed to parse JSON parameter: ${jsonString}`, error) - return defaultValue - } - } - - // incident.io requires all these fields to create a workflow - const body: Record = { + const body: Record = { name: params.name, trigger: params.trigger || 'incident.updated', - once_for: parseJsonParam(params.once_for, []), - condition_groups: parseJsonParam(params.condition_groups, []), - steps: parseJsonParam(params.steps, []), - expressions: parseJsonParam(params.expressions, []), + once_for: parseIncidentioJsonParam(params.once_for, 'once_for', []), + condition_groups: parseIncidentioJsonParam(params.condition_groups, 'condition_groups', []), + steps: parseIncidentioJsonParam(params.steps, 'steps', []), + expressions: parseIncidentioJsonParam(params.expressions, 'expressions', []), include_private_incidents: params.include_private_incidents ?? true, - runs_on_incident_modes: parseJsonParam(params.runs_on_incident_modes, ['standard']), + runs_on_incident_modes: parseIncidentioJsonParam( + params.runs_on_incident_modes, + 'runs_on_incident_modes', + ['standard'] + ), continue_on_step_error: params.continue_on_step_error ?? false, runs_on_incidents: params.runs_on_incidents || 'newly_created', state: params.state || 'draft', @@ -153,7 +144,7 @@ export const workflowsCreateTool: ToolConfig `https://api.incident.io/v2/workflows/${params.id}`, + url: (params) => `https://api.incident.io/v2/workflows/${params.id.trim()}`, method: 'DELETE', headers: (params) => ({ 'Content-Type': 'application/json', diff --git a/apps/sim/tools/incidentio/workflows_list.ts b/apps/sim/tools/incidentio/workflows_list.ts index ec45d3d1fce..490f4c74de5 100644 --- a/apps/sim/tools/incidentio/workflows_list.ts +++ b/apps/sim/tools/incidentio/workflows_list.ts @@ -1,4 +1,6 @@ import type { WorkflowsListParams, WorkflowsListResponse } from '@/tools/incidentio/types' +import { INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES } from '@/tools/incidentio/types' +import { mapIncidentioWorkflow } from '@/tools/incidentio/utils' import type { ToolConfig } from '@/tools/types' export const workflowsListTool: ToolConfig = { @@ -14,35 +16,10 @@ export const workflowsListTool: ToolConfig { - const url = new URL('https://api.incident.io/v2/workflows') - - if (params.page_size) { - url.searchParams.set('page_size', Number(params.page_size).toString()) - } - - if (params.after) { - url.searchParams.set('after', params.after) - } - - return url.toString() - }, + url: 'https://api.incident.io/v2/workflows', method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', @@ -56,20 +33,10 @@ export const workflowsListTool: ToolConfig ({ - id: workflow.id, - name: workflow.name, - state: workflow.state, - folder: workflow.folder, - created_at: workflow.created_at, - updated_at: workflow.updated_at, - })), - pagination_meta: data.pagination_meta - ? { - after: data.pagination_meta.after, - page_size: data.pagination_meta.page_size, - } - : undefined, + workflows: + data.workflows?.map((workflow: Record) => + mapIncidentioWorkflow(workflow) + ) ?? [], }, } }, @@ -80,34 +47,7 @@ export const workflowsListTool: ToolConfig = { @@ -20,10 +22,22 @@ export const workflowsShowTool: ToolConfig `https://api.incident.io/v2/workflows/${params.id}`, + url: (params) => { + const url = new URL(`https://api.incident.io/v2/workflows/${params.id.trim()}`) + if (params.skip_step_upgrades !== undefined) { + url.searchParams.set('skip_step_upgrades', String(params.skip_step_upgrades)) + } + return url.toString() + }, method: 'GET', headers: (params) => ({ 'Content-Type': 'application/json', @@ -37,14 +51,8 @@ export const workflowsShowTool: ToolConfig = { @@ -22,10 +28,59 @@ export const workflowsUpdateTool: ToolConfig `https://api.incident.io/v2/workflows/${params.id}`, + url: (params) => `https://api.incident.io/v2/workflows/${params.id.trim()}`, method: 'PUT', headers: (params) => ({ 'Content-Type': 'application/json', Authorization: `Bearer ${params.apiKey}`, }), body: (params) => { - const body: Record = {} - - if (params.name) { - body.name = params.name + const body: Record = { + name: params.name, + once_for: parseRequiredIncidentioJsonParam(params.once_for, 'once_for'), + condition_groups: parseRequiredIncidentioJsonParam( + params.condition_groups, + 'condition_groups' + ), + steps: parseRequiredIncidentioJsonParam(params.steps, 'steps'), + expressions: parseRequiredIncidentioJsonParam(params.expressions, 'expressions'), + include_private_incidents: params.include_private_incidents, + runs_on_incident_modes: parseRequiredIncidentioJsonParam( + params.runs_on_incident_modes, + 'runs_on_incident_modes' + ), + continue_on_step_error: params.continue_on_step_error, + runs_on_incidents: params.runs_on_incidents, } - if (params.state) { - body.state = params.state - } - - if (params.folder) { - body.folder = params.folder - } + if (params.state) body.state = params.state + if (params.folder) body.folder = params.folder + if (params.delay) body.delay = parseIncidentioJsonParam(params.delay, 'delay', undefined) return body }, @@ -72,14 +141,8 @@ export const workflowsUpdateTool: ToolConfig { + const normalized = value?.toLowerCase().replace(/[_-]/g, ' ') + return DEPLOYMENT_TYPES.includes(normalized as NewRelicDeploymentType) + ? (normalized as NewRelicDeploymentType) + : 'basic' +} + +const graphqlLiteral = (value: string | number | boolean): string => { + if (typeof value === 'string') return gqlString(value) + return String(value) +} + +const buildCustomAttributes = ( + customAttributes?: NewRelicCreateDeploymentEventParams['customAttributes'] +): string | undefined => { + if (!customAttributes) return undefined + + const entries = Object.entries(customAttributes) + if (!entries.length) return undefined + + for (const [key, value] of entries) { + if (!CUSTOM_ATTRIBUTE_NAME_PATTERN.test(key)) { + throw new Error( + `Invalid New Relic custom attribute name "${key}". Use letters, numbers, and underscores, and do not start with a number.` + ) + } + if (RESTRICTED_CUSTOM_ATTRIBUTE_NAMES.has(key) || key.includes('.')) { + throw new Error(`New Relic custom attribute name "${key}" is restricted`) + } + if (!['string', 'number', 'boolean'].includes(typeof value)) { + throw new Error( + `Invalid value for New Relic custom attribute "${key}". Use a string, number, or boolean.` + ) + } + if (typeof value === 'number' && !Number.isFinite(value)) { + throw new Error(`Invalid numeric value for New Relic custom attribute "${key}"`) + } + } + + const fields = entries.map(([key, value]) => `${key}: ${graphqlLiteral(value)}`).join(', ') + return `customAttributes: { ${fields} }` +} + +const buildDeploymentMutation = (params: NewRelicCreateDeploymentEventParams): string => { + const deploymentType = getDeploymentType(params.deploymentType) + const entityGuid = params.entityGuid.trim() + if (!entityGuid || entityGuid.includes("'")) { + throw new Error('Invalid entity GUID: value must not be empty or contain single quotes') + } + const version = params.version.trim() + const shortDescription = cleanOptionalString(params.shortDescription) + const description = cleanOptionalString(params.description) + const changelog = cleanOptionalString(params.changelog) + const commit = cleanOptionalString(params.commit) + const deepLink = cleanOptionalString(params.deepLink) + const user = cleanOptionalString(params.user) + const groupId = cleanOptionalString(params.groupId) + const customAttributes = buildCustomAttributes(params.customAttributes) + const deploymentFields = [ + `version: ${gqlString(version)}`, + changelog ? `changelog: ${gqlString(changelog)}` : undefined, + commit ? `commit: ${gqlString(commit)}` : undefined, + deepLink ? `deepLink: ${gqlString(deepLink)}` : undefined, + ] + .filter((field): field is string => Boolean(field)) + .join(', ') + const optionalFields = [ + shortDescription ? `shortDescription: ${gqlString(shortDescription)}` : undefined, + description ? `description: ${gqlString(description)}` : undefined, + user ? `user: ${gqlString(user)}` : undefined, + groupId ? `groupId: ${gqlString(groupId)}` : undefined, + customAttributes, + params.timestamp ? `timestamp: ${Math.trunc(Number(params.timestamp))}` : undefined, + ] + .filter((field): field is string => Boolean(field)) + .join('\n ') + + return `mutation { + changeTrackingCreateEvent( + changeTrackingEvent: { + categoryAndTypeData: { + categoryFields: { deployment: { ${deploymentFields} } } + kind: { category: "deployment", type: ${gqlString(deploymentType)} } + } + entitySearch: { query: ${gqlString(`id = '${entityGuid}'`)} } + ${optionalFields} + } + ) { + changeTrackingEvent { + category + categoryAndType + changeTrackingId + customAttributes + description + entity { + guid + name + } + groupId + shortDescription + timestamp + type + user + } + messages + } +}` +} + +export const newRelicCreateDeploymentEventTool: ToolConfig< + NewRelicCreateDeploymentEventParams, + NewRelicCreateDeploymentEventResponse +> = { + id: 'new_relic_create_deployment_event', + name: 'New Relic Create Deployment Event', + description: 'Record a deployment change event in New Relic change tracking.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'New Relic user API key for NerdGraph', + }, + region: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'New Relic data center region: us or eu', + }, + entityGuid: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'GUID of the entity associated with the deployment', + }, + version: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Deployment version, release name, or commit SHA', + }, + shortDescription: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Short description of the deployment', + }, + description: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Longer deployment description', + }, + changelog: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Deployment changelog text or URL', + }, + commit: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Commit SHA or identifier associated with the deployment', + }, + deepLink: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'URL to the deployment, build, or release details', + }, + user: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'User or automation that performed the deployment', + }, + groupId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional group ID to correlate related changes', + }, + customAttributes: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'Custom change event metadata as key-value pairs with string, number, or boolean values', + }, + deploymentType: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Deployment type: basic, blue green, canary, rolling, or shadow', + }, + timestamp: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Event timestamp in milliseconds since Unix epoch', + }, + }, + + request: { + url: (params) => getNerdGraphEndpoint(params.region), + method: 'POST', + headers: (params) => newRelicHeaders(params.apiKey), + body: (params) => ({ + query: buildDeploymentMutation(params), + }), + }, + + transformResponse: async (response) => { + const payload = await parseNerdGraphResponse(response) + const result = payload.data?.changeTrackingCreateEvent + if (!result) { + throw new Error('New Relic did not return a deployment change tracking result') + } + if (!result.changeTrackingEvent) { + const message = result.messages?.length + ? result.messages.join('; ') + : 'New Relic did not create a deployment change tracking event' + throw new Error(message) + } + + return { + success: true, + output: { + event: result.changeTrackingEvent, + messages: result?.messages ?? [], + }, + } + }, + + outputs: { + event: { + type: 'object', + description: 'Created New Relic change tracking event', + properties: { + changeTrackingId: { + type: 'string', + description: 'New Relic change tracking ID', + nullable: true, + }, + customAttributes: { + type: 'json', + description: 'Custom attributes on the change tracking event', + optional: true, + nullable: true, + }, + category: { type: 'string', description: 'Change category', nullable: true }, + categoryAndType: { + type: 'string', + description: 'Combined category and type', + nullable: true, + }, + type: { type: 'string', description: 'Change type', nullable: true }, + shortDescription: { + type: 'string', + description: 'Short change description', + nullable: true, + }, + description: { type: 'string', description: 'Change description', nullable: true }, + timestamp: { + type: 'number', + description: 'Change timestamp in milliseconds', + nullable: true, + }, + user: { type: 'string', description: 'User associated with the change', nullable: true }, + groupId: { type: 'string', description: 'Change group ID', nullable: true }, + entity: { + type: 'object', + description: 'Entity associated with the change', + nullable: true, + properties: { + guid: { type: 'string', description: 'Entity GUID', nullable: true }, + name: { type: 'string', description: 'Entity name', nullable: true }, + }, + }, + }, + }, + messages: { + type: 'array', + description: 'Messages returned by New Relic for the created change event', + items: { + type: 'string', + description: 'New Relic message', + }, + }, + }, +} diff --git a/apps/sim/tools/new_relic/get_entity.ts b/apps/sim/tools/new_relic/get_entity.ts new file mode 100644 index 00000000000..4e839a04f3b --- /dev/null +++ b/apps/sim/tools/new_relic/get_entity.ts @@ -0,0 +1,93 @@ +import type { NewRelicGetEntityParams, NewRelicGetEntityResponse } from '@/tools/new_relic/types' +import { + getNerdGraphEndpoint, + gqlString, + newRelicHeaders, + parseNerdGraphResponse, +} from '@/tools/new_relic/utils' +import type { ToolConfig } from '@/tools/types' + +interface GetEntityData { + actor?: { + entity?: { + name?: string | null + entityType?: string | null + } | null + } | null +} + +export const newRelicGetEntityTool: ToolConfig = + { + id: 'new_relic_get_entity', + name: 'New Relic Get Entity', + description: 'Fetch a New Relic entity by GUID.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'New Relic user API key for NerdGraph', + }, + region: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'New Relic data center region: us or eu', + }, + guid: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Entity GUID', + }, + }, + + request: { + url: (params) => getNerdGraphEndpoint(params.region), + method: 'POST', + headers: (params) => newRelicHeaders(params.apiKey), + body: (params) => ({ + query: `{ + actor { + entity(guid: ${gqlString(params.guid.trim())}) { + name + entityType + } + } +}`, + }), + }, + + transformResponse: async (response, params) => { + const payload = await parseNerdGraphResponse(response) + const entity = payload.data?.actor?.entity + + return { + success: true, + output: { + entity: entity + ? { + guid: params?.guid ?? null, + name: entity.name ?? null, + entityType: entity.entityType ?? null, + } + : null, + }, + } + }, + + outputs: { + entity: { + type: 'object', + description: 'New Relic entity details', + optional: true, + properties: { + guid: { type: 'string', description: 'Entity GUID', nullable: true }, + name: { type: 'string', description: 'Entity name', nullable: true }, + entityType: { type: 'string', description: 'Entity type', nullable: true }, + }, + }, + }, + } diff --git a/apps/sim/tools/new_relic/index.ts b/apps/sim/tools/new_relic/index.ts new file mode 100644 index 00000000000..31877b8cd65 --- /dev/null +++ b/apps/sim/tools/new_relic/index.ts @@ -0,0 +1,5 @@ +export { newRelicCreateDeploymentEventTool } from '@/tools/new_relic/create_deployment_event' +export { newRelicGetEntityTool } from '@/tools/new_relic/get_entity' +export { newRelicNrqlQueryTool } from '@/tools/new_relic/nrql_query' +export { newRelicSearchEntitiesTool } from '@/tools/new_relic/search_entities' +export type * from '@/tools/new_relic/types' diff --git a/apps/sim/tools/new_relic/nrql_query.ts b/apps/sim/tools/new_relic/nrql_query.ts new file mode 100644 index 00000000000..9b7d0da4d4f --- /dev/null +++ b/apps/sim/tools/new_relic/nrql_query.ts @@ -0,0 +1,111 @@ +import type { NewRelicNrqlQueryParams, NewRelicNrqlQueryResponse } from '@/tools/new_relic/types' +import { + getNerdGraphEndpoint, + gqlString, + newRelicHeaders, + parseNerdGraphResponse, +} from '@/tools/new_relic/utils' +import type { ToolConfig } from '@/tools/types' + +interface NrqlQueryData { + actor?: { + account?: { + nrql?: { + results?: Record[] + } | null + } | null + } | null +} + +export const newRelicNrqlQueryTool: ToolConfig = + { + id: 'new_relic_nrql_query', + name: 'New Relic NRQL Query', + description: 'Run a NRQL query against a New Relic account using NerdGraph.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'New Relic user API key for NerdGraph', + }, + region: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'New Relic data center region: us or eu', + }, + accountId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'New Relic account ID to query', + }, + nrql: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'NRQL query to execute', + }, + timeout: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Optional query timeout in seconds', + }, + }, + + request: { + url: (params) => getNerdGraphEndpoint(params.region), + method: 'POST', + headers: (params) => newRelicHeaders(params.apiKey), + body: (params) => { + const timeout = params.timeout ? `, timeout: ${Math.trunc(Number(params.timeout))}` : '' + return { + query: `{ + actor { + account(id: ${Math.trunc(Number(params.accountId))}) { + nrql(query: ${gqlString(params.nrql)}${timeout}) { + results + } + } + } +}`, + } + }, + }, + + transformResponse: async (response) => { + const payload = await parseNerdGraphResponse(response) + const nrql = payload.data?.actor?.account?.nrql + if (!nrql) { + throw new Error('New Relic did not return NRQL data for the requested account') + } + const results = nrql.results ?? [] + + return { + success: true, + output: { + results, + resultCount: results.length, + }, + } + }, + + outputs: { + results: { + type: 'array', + description: 'NRQL result rows. Row fields depend on the query projection.', + items: { + type: 'object', + description: 'A NRQL result row', + }, + }, + resultCount: { + type: 'number', + description: 'Number of NRQL result rows returned', + }, + }, + } diff --git a/apps/sim/tools/new_relic/search_entities.ts b/apps/sim/tools/new_relic/search_entities.ts new file mode 100644 index 00000000000..9d0e1985626 --- /dev/null +++ b/apps/sim/tools/new_relic/search_entities.ts @@ -0,0 +1,131 @@ +import type { + NewRelicEntity, + NewRelicSearchEntitiesParams, + NewRelicSearchEntitiesResponse, +} from '@/tools/new_relic/types' +import { + getNerdGraphEndpoint, + newRelicHeaders, + parseNerdGraphResponse, +} from '@/tools/new_relic/utils' +import type { ToolConfig } from '@/tools/types' + +interface SearchEntitiesData { + actor?: { + entitySearch?: { + count?: number + query?: string + results?: { + nextCursor?: string | null + entities?: NewRelicEntity[] + } | null + } | null + } | null +} + +export const newRelicSearchEntitiesTool: ToolConfig< + NewRelicSearchEntitiesParams, + NewRelicSearchEntitiesResponse +> = { + id: 'new_relic_search_entities', + name: 'New Relic Search Entities', + description: 'Search New Relic entities by name, GUID, domain type, tags, or reporting state.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'New Relic user API key for NerdGraph', + }, + region: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'New Relic data center region: us or eu', + }, + query: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: + 'Entity search query, for example: name like "api" or domainType = "APM-APPLICATION"', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous entity search', + }, + }, + + request: { + url: (params) => getNerdGraphEndpoint(params.region), + method: 'POST', + headers: (params) => newRelicHeaders(params.apiKey), + body: (params) => ({ + query: `query($query: String!, $cursor: String) { + actor { + entitySearch(query: $query) { + count + query + results(cursor: $cursor) { + nextCursor + entities { + guid + name + entityType + } + } + } + } +}`, + variables: { + query: params.query, + cursor: params.cursor || null, + }, + }), + }, + + transformResponse: async (response) => { + const payload = await parseNerdGraphResponse(response) + const entitySearch = payload.data?.actor?.entitySearch + if (!entitySearch) { + throw new Error('New Relic did not return entity search data') + } + const entities = entitySearch?.results?.entities ?? [] + + return { + success: true, + output: { + count: entitySearch?.count ?? entities.length, + query: entitySearch?.query ?? '', + entities, + nextCursor: entitySearch?.results?.nextCursor ?? null, + }, + } + }, + + outputs: { + count: { type: 'number', description: 'Total number of entities matching the query' }, + query: { type: 'string', description: 'Entity search query New Relic executed' }, + entities: { + type: 'array', + description: 'Matching New Relic entities', + items: { + type: 'object', + properties: { + guid: { type: 'string', description: 'Entity GUID', nullable: true }, + name: { type: 'string', description: 'Entity name', nullable: true }, + entityType: { type: 'string', description: 'Entity type', nullable: true }, + }, + }, + }, + nextCursor: { + type: 'string', + description: 'Cursor for the next page of results', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/new_relic/types.ts b/apps/sim/tools/new_relic/types.ts new file mode 100644 index 00000000000..1cd123f4d88 --- /dev/null +++ b/apps/sim/tools/new_relic/types.ts @@ -0,0 +1,100 @@ +import type { ToolResponse } from '@/tools/types' + +export type NewRelicRegion = 'us' | 'eu' + +export interface NewRelicBaseParams { + apiKey: string + region?: NewRelicRegion +} + +export interface NewRelicNrqlQueryParams extends NewRelicBaseParams { + accountId: number + nrql: string + timeout?: number +} + +export interface NewRelicNrqlQueryResponse extends ToolResponse { + output: { + results: Record[] + resultCount: number + } +} + +export interface NewRelicSearchEntitiesParams extends NewRelicBaseParams { + query: string + cursor?: string +} + +export interface NewRelicEntity { + guid: string | null + name: string | null + entityType: string | null +} + +export interface NewRelicSearchEntitiesResponse extends ToolResponse { + output: { + count: number + query: string + entities: NewRelicEntity[] + nextCursor: string | null + } +} + +export interface NewRelicGetEntityParams extends NewRelicBaseParams { + guid: string +} + +export interface NewRelicGetEntityResponse extends ToolResponse { + output: { + entity: NewRelicEntity | null + } +} + +export type NewRelicDeploymentType = 'basic' | 'blue green' | 'canary' | 'rolling' | 'shadow' + +export type NewRelicCustomAttributes = Record + +export interface NewRelicCreateDeploymentEventParams extends NewRelicBaseParams { + entityGuid: string + version: string + shortDescription?: string + description?: string + changelog?: string + commit?: string + deepLink?: string + user?: string + groupId?: string + customAttributes?: NewRelicCustomAttributes + deploymentType?: NewRelicDeploymentType + timestamp?: number +} + +export interface NewRelicChangeTrackingEvent { + category: string | null + categoryAndType: string | null + changeTrackingId: string | null + customAttributes?: Record | null + description: string | null + groupId: string | null + shortDescription: string | null + timestamp: number | null + type: string | null + user: string | null + entity: { + guid: string | null + name: string | null + } | null +} + +export interface NewRelicCreateDeploymentEventResponse extends ToolResponse { + output: { + event: NewRelicChangeTrackingEvent | null + messages: string[] + } +} + +export type NewRelicResponse = + | NewRelicNrqlQueryResponse + | NewRelicSearchEntitiesResponse + | NewRelicGetEntityResponse + | NewRelicCreateDeploymentEventResponse diff --git a/apps/sim/tools/new_relic/utils.ts b/apps/sim/tools/new_relic/utils.ts new file mode 100644 index 00000000000..032ae1263f1 --- /dev/null +++ b/apps/sim/tools/new_relic/utils.ts @@ -0,0 +1,42 @@ +import type { NewRelicRegion } from '@/tools/new_relic/types' + +interface GraphQLError { + message?: string +} + +interface GraphQLResponse { + data?: TData + errors?: GraphQLError[] +} + +export const getNerdGraphEndpoint = (region?: NewRelicRegion): string => + region === 'eu' ? 'https://api.eu.newrelic.com/graphql' : 'https://api.newrelic.com/graphql' + +export const newRelicHeaders = (apiKey: string): Record => ({ + 'API-Key': apiKey, + 'Content-Type': 'application/json', +}) + +export const gqlString = (value: string): string => JSON.stringify(value) + +export async function parseNerdGraphResponse( + response: Response +): Promise> { + const payload = (await response.json().catch(() => ({}))) as GraphQLResponse + + if (!response.ok || payload.errors?.length) { + const message = + payload.errors + ?.map((error) => error.message) + .filter((errorMessage): errorMessage is string => Boolean(errorMessage)) + .join('; ') || `HTTP ${response.status}: ${response.statusText}` + throw new Error(message) + } + + return payload +} + +export const cleanOptionalString = (value?: string): string | undefined => { + const trimmed = value?.trim() + return trimmed ? trimmed : undefined +} diff --git a/apps/sim/tools/railway/create_environment.ts b/apps/sim/tools/railway/create_environment.ts new file mode 100644 index 00000000000..68a3b17c064 --- /dev/null +++ b/apps/sim/tools/railway/create_environment.ts @@ -0,0 +1,131 @@ +import type { + RailwayCreatedResource, + RailwayCreateEnvironmentParams, + RailwayCreateEnvironmentResponse, +} from '@/tools/railway/types' +import { + compactVariables, + optionalString, + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayCreateEnvironmentData { + environmentCreate?: RailwayCreatedResource +} + +export const railwayCreateEnvironmentTool: ToolConfig< + RailwayCreateEnvironmentParams, + RailwayCreateEnvironmentResponse +> = { + id: 'railway_create_environment', + name: 'Railway Create Environment', + description: 'Create a Railway project environment', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + projectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway project ID', + }, + name: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Environment name', + }, + sourceEnvironmentId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Environment ID to clone from', + }, + ephemeral: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether the environment is ephemeral', + }, + skipInitialDeploys: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether to skip initial deploys for the environment', + }, + stageInitialChanges: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether to stage initial changes instead of applying them immediately', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + mutation CreateEnvironment($input: EnvironmentCreateInput!) { + environmentCreate(input: $input) { + id + name + } + } + `, + variables: { + input: compactVariables({ + projectId: params.projectId.trim(), + name: params.name.trim(), + sourceEnvironmentId: optionalString(params.sourceEnvironmentId), + ephemeral: params.ephemeral, + skipInitialDeploys: params.skipInitialDeploys, + stageInitialChanges: params.stageInitialChanges, + }), + }, + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + const environment = data.data?.environmentCreate + if (!environment) throw new Error('Railway did not return a created environment') + + return { + success: true, + output: { + environment: { + id: environment.id, + name: environment.name, + }, + }, + } + }, + + outputs: { + environment: { + type: 'object', + description: 'Created environment', + properties: { + id: { type: 'string', description: 'Environment ID' }, + name: { type: 'string', description: 'Environment name' }, + }, + }, + }, +} diff --git a/apps/sim/tools/railway/create_project.ts b/apps/sim/tools/railway/create_project.ts new file mode 100644 index 00000000000..0634801bbef --- /dev/null +++ b/apps/sim/tools/railway/create_project.ts @@ -0,0 +1,131 @@ +import type { + RailwayCreatedResource, + RailwayCreateProjectParams, + RailwayCreateProjectResponse, +} from '@/tools/railway/types' +import { + compactVariables, + optionalString, + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayCreateProjectData { + projectCreate?: RailwayCreatedResource +} + +export const railwayCreateProjectTool: ToolConfig< + RailwayCreateProjectParams, + RailwayCreateProjectResponse +> = { + id: 'railway_create_project', + name: 'Railway Create Project', + description: 'Create a Railway project', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + name: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Project name', + }, + description: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Project description', + }, + workspaceId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Workspace ID to create the project in', + }, + isPublic: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether the project should be publicly visible', + }, + defaultEnvironmentName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Name for the default environment', + }, + prDeploys: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether to enable pull request deploys', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + mutation CreateProject($input: ProjectCreateInput!) { + projectCreate(input: $input) { + id + name + } + } + `, + variables: { + input: compactVariables({ + name: params.name.trim(), + description: optionalString(params.description), + workspaceId: optionalString(params.workspaceId), + isPublic: params.isPublic, + defaultEnvironmentName: optionalString(params.defaultEnvironmentName), + prDeploys: params.prDeploys, + }), + }, + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + const project = data.data?.projectCreate + if (!project) throw new Error('Railway did not return a created project') + + return { + success: true, + output: { + project: { + id: project.id, + name: project.name, + }, + }, + } + }, + + outputs: { + project: { + type: 'object', + description: 'Created project', + properties: { + id: { type: 'string', description: 'Project ID' }, + name: { type: 'string', description: 'Project name' }, + }, + }, + }, +} diff --git a/apps/sim/tools/railway/delete_environment.ts b/apps/sim/tools/railway/delete_environment.ts new file mode 100644 index 00000000000..5d7c27417b0 --- /dev/null +++ b/apps/sim/tools/railway/delete_environment.ts @@ -0,0 +1,82 @@ +import type { + RailwayDeleteEnvironmentParams, + RailwayDeleteEnvironmentResponse, +} from '@/tools/railway/types' +import { + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayDeleteEnvironmentData { + environmentDelete?: boolean +} + +export const railwayDeleteEnvironmentTool: ToolConfig< + RailwayDeleteEnvironmentParams, + RailwayDeleteEnvironmentResponse +> = { + id: 'railway_delete_environment', + name: 'Railway Delete Environment', + description: 'Delete a Railway project environment', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + environmentId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway environment ID', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + mutation DeleteEnvironment($id: String!) { + environmentDelete(id: $id) + } + `, + variables: { + id: params.environmentId.trim(), + }, + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + if (typeof data.data?.environmentDelete !== 'boolean') { + throw new Error('Railway did not return an environment deletion result') + } + + return { + success: true, + output: { + success: data.data.environmentDelete, + }, + } + }, + + outputs: { + success: { + type: 'boolean', + description: 'Whether the environment was deleted', + }, + }, +} diff --git a/apps/sim/tools/railway/delete_project.ts b/apps/sim/tools/railway/delete_project.ts new file mode 100644 index 00000000000..e81d5406cca --- /dev/null +++ b/apps/sim/tools/railway/delete_project.ts @@ -0,0 +1,82 @@ +import type { + RailwayDeleteProjectParams, + RailwayDeleteProjectResponse, +} from '@/tools/railway/types' +import { + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayDeleteProjectData { + projectDelete?: boolean +} + +export const railwayDeleteProjectTool: ToolConfig< + RailwayDeleteProjectParams, + RailwayDeleteProjectResponse +> = { + id: 'railway_delete_project', + name: 'Railway Delete Project', + description: 'Delete a Railway project', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + projectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway project ID', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + mutation DeleteProject($id: String!) { + projectDelete(id: $id) + } + `, + variables: { + id: params.projectId.trim(), + }, + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + if (typeof data.data?.projectDelete !== 'boolean') { + throw new Error('Railway did not return a project deletion result') + } + + return { + success: true, + output: { + success: data.data.projectDelete, + }, + } + }, + + outputs: { + success: { + type: 'boolean', + description: 'Whether the project was deleted', + }, + }, +} diff --git a/apps/sim/tools/railway/deploy_service.ts b/apps/sim/tools/railway/deploy_service.ts new file mode 100644 index 00000000000..a7acd359a01 --- /dev/null +++ b/apps/sim/tools/railway/deploy_service.ts @@ -0,0 +1,118 @@ +import type { + RailwayDeployServiceParams, + RailwayDeployServiceResponse, +} from '@/tools/railway/types' +import { + optionalString, + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayDeployServiceData { + serviceInstanceDeployV2?: string +} + +export const railwayDeployServiceTool: ToolConfig< + RailwayDeployServiceParams, + RailwayDeployServiceResponse +> = { + id: 'railway_deploy_service', + name: 'Railway Deploy Service', + description: 'Trigger a deployment for a Railway service in an environment', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + serviceId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway service ID', + }, + environmentId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway environment ID', + }, + commitSha: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Specific Git commit SHA to deploy', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => { + const commitSha = optionalString(params.commitSha) + + if (commitSha) { + return { + query: ` + mutation DeployService($serviceId: String!, $environmentId: String!, $commitSha: String!) { + serviceInstanceDeployV2( + serviceId: $serviceId + environmentId: $environmentId + commitSha: $commitSha + ) + } + `, + variables: { + serviceId: params.serviceId.trim(), + environmentId: params.environmentId.trim(), + commitSha, + }, + } + } + + return { + query: ` + mutation DeployService($serviceId: String!, $environmentId: String!) { + serviceInstanceDeployV2(serviceId: $serviceId, environmentId: $environmentId) + } + `, + variables: { + serviceId: params.serviceId.trim(), + environmentId: params.environmentId.trim(), + }, + } + }, + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + const deploymentId = data.data?.serviceInstanceDeployV2 + if (!deploymentId) throw new Error('Railway did not return a deployment ID') + + return { + success: true, + output: { + deploymentId, + }, + } + }, + + outputs: { + deploymentId: { + type: 'string', + description: 'Created deployment ID', + }, + }, +} diff --git a/apps/sim/tools/railway/get_project.ts b/apps/sim/tools/railway/get_project.ts new file mode 100644 index 00000000000..5bc7ef9971b --- /dev/null +++ b/apps/sim/tools/railway/get_project.ts @@ -0,0 +1,166 @@ +import type { + RailwayGetProjectParams, + RailwayGetProjectResponse, + RailwayProjectEnvironment, + RailwayProjectService, + RailwayProjectSummary, +} from '@/tools/railway/types' +import { + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayGetProjectData { + project?: RailwayProjectSummary & { + services?: { + edges?: Array<{ + node?: RailwayProjectService + }> + } + environments?: { + edges?: Array<{ + node?: RailwayProjectEnvironment + }> + } + } +} + +export const railwayGetProjectTool: ToolConfig = + { + id: 'railway_get_project', + name: 'Railway Get Project', + description: 'Get a Railway project with its services and environments', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + projectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway project ID', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + query GetProject($id: String!) { + project(id: $id) { + id + name + description + createdAt + services { + edges { + node { + id + name + icon + } + } + } + environments { + edges { + node { + id + name + } + } + } + } + } + `, + variables: { id: params.projectId.trim() }, + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + const project = data.data?.project + if (!project) throw new Error('Railway did not return a project') + + const services = (project.services?.edges ?? []) + .map((edge) => edge.node) + .filter((service): service is RailwayProjectService => Boolean(service)) + .map((service) => ({ + id: service.id, + name: service.name, + icon: service.icon ?? null, + })) + + const environments = (project.environments?.edges ?? []) + .map((edge) => edge.node) + .filter((environment): environment is RailwayProjectEnvironment => Boolean(environment)) + .map((environment) => ({ + id: environment.id, + name: environment.name, + })) + + return { + success: true, + output: { + project: { + id: project.id, + name: project.name, + description: project.description ?? null, + createdAt: project.createdAt, + services, + environments, + }, + }, + } + }, + + outputs: { + project: { + type: 'object', + description: 'Project with services and environments', + properties: { + id: { type: 'string', description: 'Project ID' }, + name: { type: 'string', description: 'Project name' }, + description: { type: 'string', description: 'Project description', optional: true }, + createdAt: { type: 'string', description: 'Project creation timestamp' }, + services: { + type: 'array', + description: 'Project services', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'Service ID' }, + name: { type: 'string', description: 'Service name' }, + icon: { type: 'string', description: 'Service icon', optional: true }, + }, + }, + }, + environments: { + type: 'array', + description: 'Project environments', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'Environment ID' }, + name: { type: 'string', description: 'Environment name' }, + }, + }, + }, + }, + }, + }, + } diff --git a/apps/sim/tools/railway/index.ts b/apps/sim/tools/railway/index.ts new file mode 100644 index 00000000000..44ccf94867f --- /dev/null +++ b/apps/sim/tools/railway/index.ts @@ -0,0 +1,31 @@ +import { railwayCreateEnvironmentTool } from '@/tools/railway/create_environment' +import { railwayCreateProjectTool } from '@/tools/railway/create_project' +import { railwayDeleteEnvironmentTool } from '@/tools/railway/delete_environment' +import { railwayDeleteProjectTool } from '@/tools/railway/delete_project' +import { railwayDeployServiceTool } from '@/tools/railway/deploy_service' +import { railwayGetProjectTool } from '@/tools/railway/get_project' +import { railwayListDeploymentsTool } from '@/tools/railway/list_deployments' +import { railwayListProjectMembersTool } from '@/tools/railway/list_project_members' +import { railwayListProjectsTool } from '@/tools/railway/list_projects' +import { railwayListVariablesTool } from '@/tools/railway/list_variables' +import { railwayTransferProjectTool } from '@/tools/railway/transfer_project' +import { railwayUpdateProjectTool } from '@/tools/railway/update_project' +import { railwayUpsertVariableTool } from '@/tools/railway/upsert_variable' + +export { + railwayCreateEnvironmentTool, + railwayCreateProjectTool, + railwayDeleteEnvironmentTool, + railwayDeleteProjectTool, + railwayDeployServiceTool, + railwayGetProjectTool, + railwayListDeploymentsTool, + railwayListProjectMembersTool, + railwayListProjectsTool, + railwayListVariablesTool, + railwayTransferProjectTool, + railwayUpdateProjectTool, + railwayUpsertVariableTool, +} + +export * from '@/tools/railway/types' diff --git a/apps/sim/tools/railway/list_deployments.ts b/apps/sim/tools/railway/list_deployments.ts new file mode 100644 index 00000000000..a7d0d7d3501 --- /dev/null +++ b/apps/sim/tools/railway/list_deployments.ts @@ -0,0 +1,171 @@ +import type { + RailwayDeploymentSummary, + RailwayListDeploymentsParams, + RailwayListDeploymentsResponse, + RailwayPageInfo, +} from '@/tools/railway/types' +import { + optionalString, + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayListDeploymentsData { + deployments?: { + edges?: Array<{ + node?: RailwayDeploymentSummary + }> + pageInfo?: RailwayPageInfo + } +} + +export const railwayListDeploymentsTool: ToolConfig< + RailwayListDeploymentsParams, + RailwayListDeploymentsResponse +> = { + id: 'railway_list_deployments', + name: 'Railway List Deployments', + description: 'List deployments for a Railway service in an environment', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + projectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway project ID', + }, + serviceId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway service ID', + }, + environmentId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway environment ID', + }, + first: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of deployments to return', + }, + after: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Cursor for pagination', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + query ListDeployments($input: DeploymentListInput!, $first: Int, $after: String) { + deployments(input: $input, first: $first, after: $after) { + edges { + node { + id + status + createdAt + url + staticUrl + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + `, + variables: { + input: { + projectId: params.projectId.trim(), + serviceId: params.serviceId.trim(), + environmentId: params.environmentId.trim(), + }, + first: params.first ? Number(params.first) : 10, + after: optionalString(params.after), + }, + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + const deploymentConnection = data.data?.deployments + if (!deploymentConnection) throw new Error('Railway did not return deployments') + + const deployments = (deploymentConnection.edges ?? []) + .map((edge) => edge.node) + .filter((deployment): deployment is RailwayDeploymentSummary => Boolean(deployment)) + .map((deployment) => ({ + id: deployment.id, + status: deployment.status, + createdAt: deployment.createdAt, + url: deployment.url ?? null, + staticUrl: deployment.staticUrl ?? null, + })) + + return { + success: true, + output: { + deployments, + pageInfo: { + hasNextPage: deploymentConnection.pageInfo?.hasNextPage ?? false, + endCursor: deploymentConnection.pageInfo?.endCursor ?? null, + }, + count: deployments.length, + }, + } + }, + + outputs: { + deployments: { + type: 'array', + description: 'Service deployments', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'Deployment ID' }, + status: { type: 'string', description: 'Deployment status' }, + createdAt: { type: 'string', description: 'Deployment creation timestamp' }, + url: { type: 'string', description: 'Deployment URL', optional: true }, + staticUrl: { type: 'string', description: 'Static deployment URL', optional: true }, + }, + }, + }, + count: { + type: 'number', + description: 'Number of deployments returned', + }, + pageInfo: { + type: 'object', + description: 'Pagination information', + properties: { + hasNextPage: { type: 'boolean', description: 'Whether more deployments are available' }, + endCursor: { type: 'string', description: 'Cursor for the next page', optional: true }, + }, + }, + }, +} diff --git a/apps/sim/tools/railway/list_project_members.ts b/apps/sim/tools/railway/list_project_members.ts new file mode 100644 index 00000000000..09cde0d7734 --- /dev/null +++ b/apps/sim/tools/railway/list_project_members.ts @@ -0,0 +1,123 @@ +import type { + RailwayListProjectMembersParams, + RailwayListProjectMembersResponse, + RailwayProjectMember, +} from '@/tools/railway/types' +import { + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayListProjectMembersData { + projectMembers?: RailwayProjectMember[] +} + +export const railwayListProjectMembersTool: ToolConfig< + RailwayListProjectMembersParams, + RailwayListProjectMembersResponse +> = { + id: 'railway_list_project_members', + name: 'Railway List Project Members', + description: 'List members for a Railway project', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + projectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway project ID', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + query ProjectMembers($projectId: String!) { + projectMembers(projectId: $projectId) { + id + role + user { + id + name + email + } + } + } + `, + variables: { + projectId: params.projectId.trim(), + }, + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + const projectMembers = data.data?.projectMembers + if (!projectMembers) throw new Error('Railway did not return project members') + + const members = projectMembers.map((member) => ({ + id: member.id, + role: member.role, + user: member.user + ? { + id: member.user.id, + name: member.user.name ?? null, + email: member.user.email ?? null, + } + : null, + })) + + return { + success: true, + output: { + members, + count: members.length, + }, + } + }, + + outputs: { + members: { + type: 'array', + description: 'Project members', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'Project membership ID' }, + role: { type: 'string', description: 'Project role' }, + user: { + type: 'object', + description: 'Railway user', + properties: { + id: { type: 'string', description: 'User ID' }, + name: { type: 'string', description: 'User name', optional: true }, + email: { type: 'string', description: 'User email', optional: true }, + }, + }, + }, + }, + }, + count: { + type: 'number', + description: 'Number of members returned', + }, + }, +} diff --git a/apps/sim/tools/railway/list_projects.ts b/apps/sim/tools/railway/list_projects.ts new file mode 100644 index 00000000000..37b1553f202 --- /dev/null +++ b/apps/sim/tools/railway/list_projects.ts @@ -0,0 +1,156 @@ +import type { + RailwayListProjectsParams, + RailwayListProjectsResponse, + RailwayPageInfo, + RailwayProjectSummary, +} from '@/tools/railway/types' +import { + compactVariables, + optionalString, + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayListProjectsData { + projects?: { + edges?: Array<{ + node?: RailwayProjectSummary + }> + pageInfo?: RailwayPageInfo + } +} + +export const railwayListProjectsTool: ToolConfig< + RailwayListProjectsParams, + RailwayListProjectsResponse +> = { + id: 'railway_list_projects', + name: 'Railway List Projects', + description: 'List Railway projects visible to the provided token', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + workspaceId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Workspace ID to list projects from', + }, + first: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of projects to return', + }, + after: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Cursor for pagination', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + query ListProjects($workspaceId: String, $first: Int, $after: String) { + projects(workspaceId: $workspaceId, first: $first, after: $after) { + edges { + node { + id + name + description + createdAt + updatedAt + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + `, + variables: compactVariables({ + workspaceId: optionalString(params.workspaceId), + first: params.first ? Number(params.first) : undefined, + after: optionalString(params.after), + }), + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + const projectConnection = data.data?.projects + if (!projectConnection) throw new Error('Railway did not return projects') + + const projects = (projectConnection.edges ?? []) + .map((edge) => edge.node) + .filter((project): project is RailwayProjectSummary => Boolean(project)) + .map((project) => ({ + id: project.id, + name: project.name, + description: project.description ?? null, + createdAt: project.createdAt, + updatedAt: project.updatedAt ?? null, + })) + + return { + success: true, + output: { + projects, + pageInfo: { + hasNextPage: projectConnection.pageInfo?.hasNextPage ?? false, + endCursor: projectConnection.pageInfo?.endCursor ?? null, + }, + count: projects.length, + }, + } + }, + + outputs: { + projects: { + type: 'array', + description: 'Railway projects', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'Project ID' }, + name: { type: 'string', description: 'Project name' }, + description: { type: 'string', description: 'Project description', optional: true }, + createdAt: { type: 'string', description: 'Project creation timestamp' }, + updatedAt: { type: 'string', description: 'Project update timestamp', optional: true }, + }, + }, + }, + pageInfo: { + type: 'object', + description: 'Pagination information', + properties: { + hasNextPage: { type: 'boolean', description: 'Whether more projects are available' }, + endCursor: { type: 'string', description: 'Cursor for the next page', optional: true }, + }, + }, + count: { + type: 'number', + description: 'Number of projects returned', + }, + }, +} diff --git a/apps/sim/tools/railway/list_variables.ts b/apps/sim/tools/railway/list_variables.ts new file mode 100644 index 00000000000..91150d6559e --- /dev/null +++ b/apps/sim/tools/railway/list_variables.ts @@ -0,0 +1,102 @@ +import type { + RailwayListVariablesParams, + RailwayListVariablesResponse, +} from '@/tools/railway/types' +import { + compactVariables, + optionalString, + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayListVariablesData { + variables?: Record +} + +export const railwayListVariablesTool: ToolConfig< + RailwayListVariablesParams, + RailwayListVariablesResponse +> = { + id: 'railway_list_variables', + name: 'Railway List Variables', + description: 'List Railway environment variables for a service or shared environment', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + projectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway project ID', + }, + environmentId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway environment ID', + }, + serviceId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Railway service ID. Omit for shared environment variables.', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + query Variables($projectId: String!, $environmentId: String!, $serviceId: String) { + variables(projectId: $projectId, environmentId: $environmentId, serviceId: $serviceId) + } + `, + variables: compactVariables({ + projectId: params.projectId.trim(), + environmentId: params.environmentId.trim(), + serviceId: optionalString(params.serviceId), + }), + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + const variables = data.data?.variables + if (!variables) throw new Error('Railway did not return variables') + + return { + success: true, + output: { + variables, + count: Object.keys(variables).length, + }, + } + }, + + outputs: { + variables: { + type: 'object', + description: 'Variable names and values', + }, + count: { + type: 'number', + description: 'Number of variables returned', + }, + }, +} diff --git a/apps/sim/tools/railway/transfer_project.ts b/apps/sim/tools/railway/transfer_project.ts new file mode 100644 index 00000000000..b0894d9e114 --- /dev/null +++ b/apps/sim/tools/railway/transfer_project.ts @@ -0,0 +1,91 @@ +import type { + RailwayTransferProjectParams, + RailwayTransferProjectResponse, +} from '@/tools/railway/types' +import { + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayTransferProjectData { + projectTransfer?: boolean +} + +export const railwayTransferProjectTool: ToolConfig< + RailwayTransferProjectParams, + RailwayTransferProjectResponse +> = { + id: 'railway_transfer_project', + name: 'Railway Transfer Project', + description: 'Transfer a Railway project to another workspace', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + projectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway project ID', + }, + workspaceId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Destination workspace ID', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + mutation TransferProject($projectId: String!, $input: ProjectTransferInput!) { + projectTransfer(projectId: $projectId, input: $input) + } + `, + variables: { + projectId: params.projectId.trim(), + input: { + workspaceId: params.workspaceId.trim(), + }, + }, + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + if (typeof data.data?.projectTransfer !== 'boolean') { + throw new Error('Railway did not return a project transfer result') + } + + return { + success: true, + output: { + success: data.data.projectTransfer, + }, + } + }, + + outputs: { + success: { + type: 'boolean', + description: 'Whether the project was transferred', + }, + }, +} diff --git a/apps/sim/tools/railway/types.ts b/apps/sim/tools/railway/types.ts new file mode 100644 index 00000000000..deb68792614 --- /dev/null +++ b/apps/sim/tools/railway/types.ts @@ -0,0 +1,245 @@ +import type { ToolResponse } from '@/tools/types' + +export type RailwayTokenType = 'account' | 'workspace' | 'project' | 'oauth' + +export interface RailwayAuthParams { + apiKey: string + tokenType?: RailwayTokenType +} + +export interface RailwayPageInfo { + hasNextPage: boolean + endCursor: string | null +} + +export interface RailwayProjectSummary { + id: string + name: string + description: string | null + createdAt: string + updatedAt?: string | null +} + +export interface RailwayUpdatedProject { + id: string + name: string + description: string | null +} + +export interface RailwayProjectService { + id: string + name: string + icon: string | null +} + +export interface RailwayProjectEnvironment { + id: string + name: string +} + +export interface RailwayProjectMember { + id: string + role: string + user: { + id: string + name: string | null + email: string | null + } | null +} + +export interface RailwayCreatedResource { + id: string + name: string +} + +export interface RailwayDeploymentSummary { + id: string + status: string + createdAt: string + url: string | null + staticUrl: string | null +} + +export interface RailwayListProjectsParams extends RailwayAuthParams { + workspaceId?: string + first?: number + after?: string +} + +export interface RailwayGetProjectParams extends RailwayAuthParams { + projectId: string +} + +export interface RailwayCreateProjectParams extends RailwayAuthParams { + name: string + description?: string + workspaceId?: string + isPublic?: boolean + defaultEnvironmentName?: string + prDeploys?: boolean +} + +export interface RailwayUpdateProjectParams extends RailwayAuthParams { + projectId: string + name?: string + description?: string + isPublic?: boolean + prDeploys?: boolean +} + +export interface RailwayDeleteProjectParams extends RailwayAuthParams { + projectId: string +} + +export interface RailwayTransferProjectParams extends RailwayAuthParams { + projectId: string + workspaceId: string +} + +export interface RailwayListProjectMembersParams extends RailwayAuthParams { + projectId: string +} + +export interface RailwayCreateEnvironmentParams extends RailwayAuthParams { + projectId: string + name: string + sourceEnvironmentId?: string + ephemeral?: boolean + skipInitialDeploys?: boolean + stageInitialChanges?: boolean +} + +export interface RailwayDeleteEnvironmentParams extends RailwayAuthParams { + environmentId: string +} + +export interface RailwayListDeploymentsParams extends RailwayAuthParams { + projectId: string + serviceId: string + environmentId: string + first?: number + after?: string +} + +export interface RailwayDeployServiceParams extends RailwayAuthParams { + serviceId: string + environmentId: string + commitSha?: string +} + +export interface RailwayListVariablesParams extends RailwayAuthParams { + projectId: string + environmentId: string + serviceId?: string +} + +export interface RailwayUpsertVariableParams extends RailwayAuthParams { + projectId: string + environmentId: string + name: string + value: string + serviceId?: string + skipDeploys?: boolean +} + +export interface RailwayListProjectsResponse extends ToolResponse { + output: { + projects: RailwayProjectSummary[] + pageInfo: RailwayPageInfo + count: number + } +} + +export interface RailwayGetProjectResponse extends ToolResponse { + output: { + project: RailwayProjectSummary & { + services: RailwayProjectService[] + environments: RailwayProjectEnvironment[] + } + } +} + +export interface RailwayCreateProjectResponse extends ToolResponse { + output: { + project: RailwayCreatedResource + } +} + +export interface RailwayUpdateProjectResponse extends ToolResponse { + output: { + project: RailwayUpdatedProject + } +} + +export interface RailwayDeleteProjectResponse extends ToolResponse { + output: { + success: boolean + } +} + +export interface RailwayTransferProjectResponse extends ToolResponse { + output: { + success: boolean + } +} + +export interface RailwayListProjectMembersResponse extends ToolResponse { + output: { + members: RailwayProjectMember[] + count: number + } +} + +export interface RailwayCreateEnvironmentResponse extends ToolResponse { + output: { + environment: RailwayCreatedResource + } +} + +export interface RailwayDeleteEnvironmentResponse extends ToolResponse { + output: { + success: boolean + } +} + +export interface RailwayListDeploymentsResponse extends ToolResponse { + output: { + deployments: RailwayDeploymentSummary[] + pageInfo: RailwayPageInfo + count: number + } +} + +export interface RailwayDeployServiceResponse extends ToolResponse { + output: { + deploymentId: string + } +} + +export interface RailwayListVariablesResponse extends ToolResponse { + output: { + variables: Record + count: number + } +} + +export interface RailwayUpsertVariableResponse extends ToolResponse { + output: { + success: boolean + } +} + +export type RailwayResponse = + | RailwayListProjectsResponse + | RailwayGetProjectResponse + | RailwayCreateProjectResponse + | RailwayUpdateProjectResponse + | RailwayDeleteProjectResponse + | RailwayTransferProjectResponse + | RailwayListProjectMembersResponse + | RailwayCreateEnvironmentResponse + | RailwayDeleteEnvironmentResponse + | RailwayListDeploymentsResponse + | RailwayDeployServiceResponse + | RailwayListVariablesResponse + | RailwayUpsertVariableResponse diff --git a/apps/sim/tools/railway/update_project.ts b/apps/sim/tools/railway/update_project.ts new file mode 100644 index 00000000000..3e021d4083c --- /dev/null +++ b/apps/sim/tools/railway/update_project.ts @@ -0,0 +1,127 @@ +import type { + RailwayUpdatedProject, + RailwayUpdateProjectParams, + RailwayUpdateProjectResponse, +} from '@/tools/railway/types' +import { + compactVariables, + optionalString, + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayUpdateProjectData { + projectUpdate?: RailwayUpdatedProject +} + +export const railwayUpdateProjectTool: ToolConfig< + RailwayUpdateProjectParams, + RailwayUpdateProjectResponse +> = { + id: 'railway_update_project', + name: 'Railway Update Project', + description: 'Update a Railway project name or description', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + projectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway project ID', + }, + name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated project name', + }, + description: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Updated project description', + }, + isPublic: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether the project should be publicly visible', + }, + prDeploys: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether to enable pull request deploy environments', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + mutation UpdateProject($id: String!, $input: ProjectUpdateInput!) { + projectUpdate(id: $id, input: $input) { + id + name + description + } + } + `, + variables: { + id: params.projectId.trim(), + input: compactVariables({ + name: optionalString(params.name), + description: optionalString(params.description), + isPublic: params.isPublic, + prDeploys: params.prDeploys, + }), + }, + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + const project = data.data?.projectUpdate + if (!project) throw new Error('Railway did not return an updated project') + + return { + success: true, + output: { + project: { + id: project.id, + name: project.name, + description: project.description ?? null, + }, + }, + } + }, + + outputs: { + project: { + type: 'object', + description: 'Updated project', + properties: { + id: { type: 'string', description: 'Project ID' }, + name: { type: 'string', description: 'Project name' }, + description: { type: 'string', description: 'Project description', optional: true }, + }, + }, + }, +} diff --git a/apps/sim/tools/railway/upsert_variable.ts b/apps/sim/tools/railway/upsert_variable.ts new file mode 100644 index 00000000000..120b9226496 --- /dev/null +++ b/apps/sim/tools/railway/upsert_variable.ts @@ -0,0 +1,123 @@ +import type { + RailwayUpsertVariableParams, + RailwayUpsertVariableResponse, +} from '@/tools/railway/types' +import { + compactVariables, + optionalString, + parseRailwayGraphqlResponse, + RAILWAY_GRAPHQL_URL, + railwayHeaders, +} from '@/tools/railway/utils' +import type { ToolConfig } from '@/tools/types' + +interface RailwayUpsertVariableData { + variableUpsert?: boolean +} + +export const railwayUpsertVariableTool: ToolConfig< + RailwayUpsertVariableParams, + RailwayUpsertVariableResponse +> = { + id: 'railway_upsert_variable', + name: 'Railway Upsert Variable', + description: 'Create or update a Railway environment variable', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Railway API token', + }, + tokenType: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Railway token type: account, workspace, project, or oauth', + }, + projectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway project ID', + }, + environmentId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Railway environment ID', + }, + serviceId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Railway service ID. Omit to create or update a shared variable.', + }, + name: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Variable name', + }, + value: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Variable value', + }, + skipDeploys: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether to skip automatic redeploys after changing the variable', + }, + }, + + request: { + url: RAILWAY_GRAPHQL_URL, + method: 'POST', + headers: (params) => railwayHeaders(params.apiKey, params.tokenType), + body: (params) => ({ + query: ` + mutation UpsertVariable($input: VariableUpsertInput!) { + variableUpsert(input: $input) + } + `, + variables: { + input: { + projectId: params.projectId.trim(), + environmentId: params.environmentId.trim(), + name: params.name.trim(), + value: params.value, + ...compactVariables({ + serviceId: optionalString(params.serviceId), + skipDeploys: params.skipDeploys, + }), + }, + }, + }), + }, + + transformResponse: async (response: Response) => { + const data = await parseRailwayGraphqlResponse(response) + if (typeof data.data?.variableUpsert !== 'boolean') { + throw new Error('Railway did not return a variable upsert result') + } + + return { + success: true, + output: { + success: data.data.variableUpsert, + }, + } + }, + + outputs: { + success: { + type: 'boolean', + description: 'Whether the variable was created or updated', + }, + }, +} diff --git a/apps/sim/tools/railway/utils.ts b/apps/sim/tools/railway/utils.ts new file mode 100644 index 00000000000..02e1f37160f --- /dev/null +++ b/apps/sim/tools/railway/utils.ts @@ -0,0 +1,58 @@ +import type { RailwayTokenType } from '@/tools/railway/types' + +export const RAILWAY_GRAPHQL_URL = 'https://backboard.railway.com/graphql/v2' + +interface RailwayGraphqlError { + message?: string +} + +interface RailwayGraphqlResponse { + data?: TData + errors?: RailwayGraphqlError[] +} + +export function railwayHeaders( + apiKey: string, + tokenType?: RailwayTokenType +): Record { + if (!apiKey) { + throw new Error('Missing API token for Railway API request') + } + + if (tokenType === 'project') { + return { + 'Content-Type': 'application/json', + 'Project-Access-Token': apiKey, + } + } + + return { + 'Content-Type': 'application/json', + Authorization: `Bearer ${apiKey}`, + } +} + +export async function parseRailwayGraphqlResponse( + response: Response +): Promise> { + const data = (await response.json()) as RailwayGraphqlResponse + + if (!response.ok) { + throw new Error(data.errors?.[0]?.message ?? `HTTP ${response.status}: ${response.statusText}`) + } + + if (data.errors?.length) { + throw new Error(data.errors[0]?.message ?? 'Railway API returned a GraphQL error') + } + + return data +} + +export function compactVariables(input: Record) { + return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined)) +} + +export function optionalString(value?: string): string | undefined { + const trimmed = value?.trim() + return trimmed ? trimmed : undefined +} diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index 4ad97b0cdfa..ef081a3f2e2 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -943,6 +943,7 @@ import { import { gongAggregateActivityTool, gongAnsweredScorecardsTool, + gongCreateCallTool, gongGetCallTool, gongGetCallTranscriptTool, gongGetCoachingTool, @@ -1305,6 +1306,7 @@ import { incidentioCustomFieldsUpdateTool, incidentioEscalationPathsCreateTool, incidentioEscalationPathsDeleteTool, + incidentioEscalationPathsListTool, incidentioEscalationPathsShowTool, incidentioEscalationPathsUpdateTool, incidentioEscalationsCreateTool, @@ -1842,6 +1844,12 @@ import { neo4jQueryTool, neo4jUpdateTool, } from '@/tools/neo4j' +import { + newRelicCreateDeploymentEventTool, + newRelicGetEntityTool, + newRelicNrqlQueryTool, + newRelicSearchEntitiesTool, +} from '@/tools/new_relic' import { notionAddDatabaseRowTool, notionAddDatabaseRowV2Tool, @@ -2093,6 +2101,21 @@ import { import { pulseParserTool, pulseParserV2Tool } from '@/tools/pulse' import { qdrantFetchTool, qdrantSearchTool, qdrantUpsertTool } from '@/tools/qdrant' import { quiverImageToSvgTool, quiverListModelsTool, quiverTextToSvgTool } from '@/tools/quiver' +import { + railwayCreateEnvironmentTool, + railwayCreateProjectTool, + railwayDeleteEnvironmentTool, + railwayDeleteProjectTool, + railwayDeployServiceTool, + railwayGetProjectTool, + railwayListDeploymentsTool, + railwayListProjectMembersTool, + railwayListProjectsTool, + railwayListVariablesTool, + railwayTransferProjectTool, + railwayUpdateProjectTool, + railwayUpsertVariableTool, +} from '@/tools/railway' import { rdsDeleteTool, rdsExecuteTool, @@ -3303,22 +3326,23 @@ export const tools: Record = { fireflies_create_bite: firefliesCreateBiteTool, fireflies_list_bites: firefliesListBitesTool, fireflies_list_contacts: firefliesListContactsTool, - gong_list_calls: gongListCallsTool, + gong_aggregate_activity: gongAggregateActivityTool, + gong_answered_scorecards: gongAnsweredScorecardsTool, + gong_create_call: gongCreateCallTool, gong_get_call: gongGetCallTool, gong_get_call_transcript: gongGetCallTranscriptTool, + gong_get_coaching: gongGetCoachingTool, gong_get_extensive_calls: gongGetExtensiveCallsTool, - gong_list_users: gongListUsersTool, + gong_get_folder_content: gongGetFolderContentTool, gong_get_user: gongGetUserTool, - gong_aggregate_activity: gongAggregateActivityTool, gong_interaction_stats: gongInteractionStatsTool, - gong_answered_scorecards: gongAnsweredScorecardsTool, + gong_list_calls: gongListCallsTool, + gong_list_flows: gongListFlowsTool, gong_list_library_folders: gongListLibraryFoldersTool, - gong_get_folder_content: gongGetFolderContentTool, gong_list_scorecards: gongListScorecardsTool, gong_list_trackers: gongListTrackersTool, + gong_list_users: gongListUsersTool, gong_list_workspaces: gongListWorkspacesTool, - gong_list_flows: gongListFlowsTool, - gong_get_coaching: gongGetCoachingTool, gong_lookup_email: gongLookupEmailTool, gong_lookup_phone: gongLookupPhoneTool, grafana_get_dashboard: grafanaGetDashboardTool, @@ -3976,6 +4000,10 @@ export const tools: Record = { neo4j_delete: neo4jDeleteTool, neo4j_execute: neo4jExecuteTool, neo4j_introspect: neo4jIntrospectTool, + new_relic_create_deployment_event: newRelicCreateDeploymentEventTool, + new_relic_get_entity: newRelicGetEntityTool, + new_relic_nrql_query: newRelicNrqlQueryTool, + new_relic_search_entities: newRelicSearchEntitiesTool, github_pr: githubPrTool, github_pr_v2: githubPrV2Tool, github_comment: githubCommentTool, @@ -4250,18 +4278,6 @@ export const tools: Record = { exa_find_similar_links: exaFindSimilarLinksTool, exa_answer: exaAnswerTool, exa_research: exaResearchTool, - incidentio_escalations_list: incidentioEscalationsListTool, - incidentio_escalations_create: incidentioEscalationsCreateTool, - incidentio_escalations_show: incidentioEscalationsShowTool, - incidentio_schedules_list: incidentioSchedulesListTool, - incidentio_schedules_create: incidentioSchedulesCreateTool, - incidentio_schedules_show: incidentioSchedulesShowTool, - incidentio_schedules_update: incidentioSchedulesUpdateTool, - incidentio_schedules_delete: incidentioSchedulesDeleteTool, - incidentio_custom_fields_create: incidentioCustomFieldsCreateTool, - incidentio_custom_fields_show: incidentioCustomFieldsShowTool, - incidentio_custom_fields_update: incidentioCustomFieldsUpdateTool, - incidentio_custom_fields_delete: incidentioCustomFieldsDeleteTool, parallel_search: parallelSearchTool, parallel_extract: parallelExtractTool, parallel_deep_research: parallelDeepResearchTool, @@ -5347,6 +5363,19 @@ export const tools: Record = { qdrant_fetch_points: qdrantFetchTool, qdrant_search_vector: qdrantSearchTool, qdrant_upsert_points: qdrantUpsertTool, + railway_create_environment: railwayCreateEnvironmentTool, + railway_create_project: railwayCreateProjectTool, + railway_delete_environment: railwayDeleteEnvironmentTool, + railway_delete_project: railwayDeleteProjectTool, + railway_deploy_service: railwayDeployServiceTool, + railway_get_project: railwayGetProjectTool, + railway_list_deployments: railwayListDeploymentsTool, + railway_list_project_members: railwayListProjectMembersTool, + railway_list_projects: railwayListProjectsTool, + railway_list_variables: railwayListVariablesTool, + railway_transfer_project: railwayTransferProjectTool, + railway_update_project: railwayUpdateProjectTool, + railway_upsert_variable: railwayUpsertVariableTool, hunter_discover: hunterDiscoverTool, hunter_domain_search: hunterDomainSearchTool, hunter_email_finder: hunterEmailFinderTool, @@ -5400,6 +5429,8 @@ export const tools: Record = { incidentio_incidents_update: incidentioIncidentsUpdateTool, incidentio_actions_list: incidentioActionsListTool, incidentio_actions_show: incidentioActionsShowTool, + incidentio_custom_fields_create: incidentioCustomFieldsCreateTool, + incidentio_custom_fields_delete: incidentioCustomFieldsDeleteTool, incidentio_follow_ups_list: incidentioFollowUpsListTool, incidentio_follow_ups_show: incidentioFollowUpsShowTool, incidentio_workflows_list: incidentioWorkflowsListTool, @@ -5408,6 +5439,11 @@ export const tools: Record = { incidentio_workflows_update: incidentioWorkflowsUpdateTool, incidentio_workflows_delete: incidentioWorkflowsDeleteTool, incidentio_custom_fields_list: incidentioCustomFieldsListTool, + incidentio_custom_fields_show: incidentioCustomFieldsShowTool, + incidentio_custom_fields_update: incidentioCustomFieldsUpdateTool, + incidentio_escalations_create: incidentioEscalationsCreateTool, + incidentio_escalations_list: incidentioEscalationsListTool, + incidentio_escalations_show: incidentioEscalationsShowTool, incidentio_users_list: incidentioUsersListTool, incidentio_users_show: incidentioUsersShowTool, incidentio_severities_list: incidentioSeveritiesListTool, @@ -5423,7 +5459,13 @@ export const tools: Record = { incidentio_incident_updates_list: incidentioIncidentUpdatesListTool, incidentio_schedule_entries_list: incidentioScheduleEntriesListTool, incidentio_schedule_overrides_create: incidentioScheduleOverridesCreateTool, + incidentio_schedules_create: incidentioSchedulesCreateTool, + incidentio_schedules_delete: incidentioSchedulesDeleteTool, + incidentio_schedules_list: incidentioSchedulesListTool, + incidentio_schedules_show: incidentioSchedulesShowTool, + incidentio_schedules_update: incidentioSchedulesUpdateTool, incidentio_escalation_paths_create: incidentioEscalationPathsCreateTool, + incidentio_escalation_paths_list: incidentioEscalationPathsListTool, incidentio_escalation_paths_show: incidentioEscalationPathsShowTool, incidentio_escalation_paths_update: incidentioEscalationPathsUpdateTool, incidentio_escalation_paths_delete: incidentioEscalationPathsDeleteTool, From d7d58cec361d3ccb859cdb34f5b3e4d45ac4f5a0 Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 19 May 2026 15:44:34 -0700 Subject: [PATCH 09/13] improvement(workflow-search): include block names in in-workflow search (#4668) * improvement(workflow-search): include block names in in-workflow search Adds block names to the workflow search index alongside subblock content. Selecting a block-name match navigates to the block and highlights its title in the editor header with the same orange treatment used for subblock labels. Co-Authored-By: Claude Opus 4.7 * refactor(panel-store): derive ActiveSearchTargetKind from WorkflowSearchTarget Replaces the hand-maintained literal union with a derived type so adding a new target kind in search-replace/types.ts automatically propagates here. Co-Authored-By: Claude Opus 4.7 --------- Co-authored-by: Claude Opus 4.7 --- .../panel/components/editor/editor.tsx | 10 +++++- .../workflow-search-replace.tsx | 1 + .../workflows/search-replace/indexer.test.ts | 33 +++++++++++++++++++ .../lib/workflows/search-replace/indexer.ts | 26 +++++++++++++++ .../sim/lib/workflows/search-replace/types.ts | 1 + apps/sim/stores/panel/editor/store.ts | 4 +++ 6 files changed, 74 insertions(+), 1 deletion(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/editor.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/editor.tsx index ac65eab57fa..2c531a80a83 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/editor.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/editor.tsx @@ -32,6 +32,7 @@ import { SubBlock, SubflowEditor, } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components' +import { WORKFLOW_SEARCH_HIGHLIGHT_CLASS } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/constants' import { useBlockConnections, useConnectionsResize, @@ -104,6 +105,8 @@ export function Editor() { const currentBlock = currentBlockId ? currentWorkflow.getBlockById(currentBlockId) : null const blockConfig = currentBlock ? getBlock(currentBlock.type) : null const title = currentBlock?.name || 'Editor' + const isBlockNameSearchHighlighted = + activeSearchTarget?.targetKind === 'block-name' && activeSearchTarget.blockId === currentBlockId const isSubflow = currentBlock && (currentBlock.type === 'loop' || currentBlock.type === 'parallel') @@ -253,6 +256,7 @@ export function Editor() { useEffect(() => { if (!activeSearchTarget || activeSearchTarget.blockId !== currentBlockId) return + if (activeSearchTarget.targetKind === 'block-name') return const container = subBlocksRef.current if (!container) return @@ -402,7 +406,11 @@ export function Editor() { } }} > - {title} + {isBlockNameSearchHighlighted ? ( + {title} + ) : ( + title + )} )} diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/search-replace/workflow-search-replace.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/search-replace/workflow-search-replace.tsx index aad657f5643..d67fcf896ea 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/search-replace/workflow-search-replace.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/search-replace/workflow-search-replace.tsx @@ -265,6 +265,7 @@ export function WorkflowSearchReplace() { canonicalSubBlockId: match.canonicalSubBlockId, valuePath: match.valuePath, kind: match.kind, + targetKind: match.target.kind, resourceGroupKey: match.resource?.resourceGroupKey, }) }, diff --git a/apps/sim/lib/workflows/search-replace/indexer.test.ts b/apps/sim/lib/workflows/search-replace/indexer.test.ts index 53975b65ad5..31e45f3715e 100644 --- a/apps/sim/lib/workflows/search-replace/indexer.test.ts +++ b/apps/sim/lib/workflows/search-replace/indexer.test.ts @@ -31,6 +31,39 @@ describe('indexWorkflowSearchMatches', () => { expect(matches.at(-1)?.reason).toBe('Block is locked') }) + it('finds matches in block names', () => { + const workflow = createSearchReplaceWorkflowFixture() + + const matches = indexWorkflowSearchMatches({ + workflow, + query: 'agent', + mode: 'text', + blockConfigs: SEARCH_REPLACE_BLOCK_CONFIGS, + }) + + const blockNameMatches = matches.filter((match) => match.target.kind === 'block-name') + expect(blockNameMatches.map((match) => [match.blockId, match.rawValue])).toEqual([ + ['agent-1', 'Agent'], + ['locked-1', 'Agent'], + ]) + expect(blockNameMatches.every((match) => match.editable === false)).toBe(true) + expect(blockNameMatches.every((match) => match.navigable === true)).toBe(true) + expect(blockNameMatches[0]?.fieldTitle).toBe('Block name') + }) + + it('does not include block-name matches in resource-only mode', () => { + const workflow = createSearchReplaceWorkflowFixture() + + const matches = indexWorkflowSearchMatches({ + workflow, + query: 'agent', + mode: 'resource', + blockConfigs: SEARCH_REPLACE_BLOCK_CONFIGS, + }) + + expect(matches.some((match) => match.target.kind === 'block-name')).toBe(false) + }) + it('does not index internal row metadata in structured subblock values', () => { const workflow = createSearchReplaceWorkflowFixture() diff --git a/apps/sim/lib/workflows/search-replace/indexer.ts b/apps/sim/lib/workflows/search-replace/indexer.ts index 198b5c6567f..a839bd39008 100644 --- a/apps/sim/lib/workflows/search-replace/indexer.ts +++ b/apps/sim/lib/workflows/search-replace/indexer.ts @@ -982,6 +982,32 @@ export function indexWorkflowSearchMatches( const protectedByLock = isWorkflowBlockProtected(block.id, workflow.blocks) const editable = !protectedByLock && !isReadOnly + if (mode !== 'resource' && query && typeof block.name === 'string' && block.name.length > 0) { + const blockNameRanges = findTextRanges(block.name, query, caseSensitive) + blockNameRanges.forEach((range, occurrenceIndex) => { + matches.push({ + id: createMatchId(['block-name', block.id, range.start, occurrenceIndex]), + blockId: block.id, + blockName: block.name, + blockType: block.type, + subBlockId: '', + canonicalSubBlockId: '', + subBlockType: 'short-input', + fieldTitle: 'Block name', + valuePath: [], + target: { kind: 'block-name' }, + kind: 'text', + rawValue: block.name.slice(range.start, range.end), + searchText: block.name, + range, + editable: false, + navigable: true, + protected: protectedByLock, + reason: 'Block names cannot be edited via replace', + }) + }) + } + if (mode !== 'resource') { for (const field of getWorkflowSearchSubflowFields(block)) { const fieldEditable = editable && field.editable diff --git a/apps/sim/lib/workflows/search-replace/types.ts b/apps/sim/lib/workflows/search-replace/types.ts index 835cf43d71d..9298430318d 100644 --- a/apps/sim/lib/workflows/search-replace/types.ts +++ b/apps/sim/lib/workflows/search-replace/types.ts @@ -45,6 +45,7 @@ export interface WorkflowSearchResourceMeta { export type WorkflowSearchTarget = | { kind: 'subblock' } | { kind: 'subflow'; fieldId: WorkflowSearchSubflowFieldId } + | { kind: 'block-name' } export interface WorkflowSearchMatch { id: string diff --git a/apps/sim/stores/panel/editor/store.ts b/apps/sim/stores/panel/editor/store.ts index d76019befea..9a0f6d1e8fd 100644 --- a/apps/sim/stores/panel/editor/store.ts +++ b/apps/sim/stores/panel/editor/store.ts @@ -2,11 +2,14 @@ import { create } from 'zustand' import { persist } from 'zustand/middleware' +import type { WorkflowSearchTarget } from '@/lib/workflows/search-replace/types' import { EDITOR_CONNECTIONS_HEIGHT } from '@/stores/constants' import { usePanelStore } from '../store' let renameCallback: (() => void) | null = null +export type ActiveSearchTargetKind = WorkflowSearchTarget['kind'] + export interface ActiveSearchTarget { matchId: string blockId: string @@ -14,6 +17,7 @@ export interface ActiveSearchTarget { canonicalSubBlockId: string valuePath: Array kind: string + targetKind: ActiveSearchTargetKind resourceGroupKey?: string } From 972ec5f2161355f305b1e26b6ffded1ad2f6f5e2 Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 19 May 2026 16:18:07 -0700 Subject: [PATCH 10/13] fix(branding): align auth and deploy UI colors (#4669) --- .../(auth)/components/auth-button-classes.ts | 4 + apps/sim/app/_styles/globals.css | 17 +- .../chat/components/auth/email/email-auth.tsx | 16 +- .../[identifier]/components/email-auth.tsx | 16 +- apps/sim/app/manifest.ts | 2 +- .../deploy-modal/components/a2a/a2a.tsx | 117 +--- .../deploy-modal/components/api/api.tsx | 2 - .../deploy-modal/components/chat/chat.tsx | 62 +- .../form/components/embed-code-generator.tsx | 61 -- .../form/components/form-builder.tsx | 356 ----------- .../deploy-modal/components/form/form.tsx | 563 ------------------ .../form/hooks/use-identifier-validation.ts | 89 --- .../general/components/api-info-modal.tsx | 25 +- .../components/version-description-modal.tsx | 18 +- .../general/components/versions.tsx | 69 +-- .../components/general/general.tsx | 47 +- .../deploy-modal/components/mcp/mcp.tsx | 94 ++- .../components/template/template.tsx | 483 --------------- .../components/deploy-modal/deploy-modal.tsx | 322 +++------- apps/sim/components/emails/_styles/base.ts | 4 +- .../components/whitelabeling-settings.tsx | 14 +- apps/sim/ee/whitelabeling/inject-theme.ts | 4 +- apps/sim/ee/whitelabeling/metadata.ts | 2 +- .../ee/whitelabeling/org-branding-utils.ts | 4 +- apps/sim/lib/api/contracts/organization.ts | 2 +- apps/sim/lib/branding/defaults.ts | 8 +- apps/sim/lib/branding/types.ts | 2 +- apps/sim/lib/core/config/env.ts | 2 +- apps/sim/tailwind.config.ts | 5 - 29 files changed, 292 insertions(+), 2118 deletions(-) delete mode 100644 apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/form/components/embed-code-generator.tsx delete mode 100644 apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/form/components/form-builder.tsx delete mode 100644 apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/form/form.tsx delete mode 100644 apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/form/hooks/use-identifier-validation.ts delete mode 100644 apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/template/template.tsx diff --git a/apps/sim/app/(auth)/components/auth-button-classes.ts b/apps/sim/app/(auth)/components/auth-button-classes.ts index a55f334ea8e..95a3592fe96 100644 --- a/apps/sim/app/(auth)/components/auth-button-classes.ts +++ b/apps/sim/app/(auth)/components/auth-button-classes.ts @@ -4,3 +4,7 @@ export const AUTH_PRIMARY_CTA_BASE = /** Full-width variant used for primary auth form submit buttons. */ export const AUTH_SUBMIT_BTN = `${AUTH_PRIMARY_CTA_BASE} w-full` as const + +/** Shared className for inline auth action links on dark auth surfaces. */ +export const AUTH_TEXT_LINK = + 'font-medium text-[var(--brand-accent)] underline-offset-4 transition hover:text-[var(--brand-accent-hover)] hover:underline disabled:cursor-not-allowed disabled:opacity-50' as const diff --git a/apps/sim/app/_styles/globals.css b/apps/sim/app/_styles/globals.css index 15fb1c30cf3..1555a0cc2ab 100644 --- a/apps/sim/app/_styles/globals.css +++ b/apps/sim/app/_styles/globals.css @@ -36,7 +36,6 @@ --shadow-overlay: 0 16px 48px rgba(0, 0, 0, 0.15); --shadow-kbd: 0 4px 0 0 rgba(48, 48, 48, 1); --shadow-kbd-sm: 0 2px 0 0 rgba(48, 48, 48, 1); - --shadow-brand-inset: inset 0 1.25px 2.5px 0 #9b77ff; --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.04); } @@ -762,12 +761,8 @@ input[type="search"]::-ms-clear { --card-text: 0 0% 3.9%; --card-hover: 0 0% 96.1%; --base-muted-foreground: #737373; - --gradient-primary: 263 85% 70%; - --gradient-secondary: 336 95% 65%; - --brand: #6f3dfa; - --brand-hover: #6338d9; - --brand-link: #6f3dfa; - --brand-link-hover: #6f3dfa; + --brand: #33c482; + --brand-hover: #2dac72; } .dark { @@ -799,12 +794,8 @@ input[type="search"]::-ms-clear { --card-text: 0 0% 98%; --card-hover: 0 0% 12.0%; --base-muted-foreground: #a3a3a3; - --gradient-primary: 263 90% 75%; - --gradient-secondary: 336 100% 72%; - --brand: #701ffc; - --brand-hover: #802fff; - --brand-link: #9d54ff; - --brand-link-hover: #a66fff; + --brand: #33c482; + --brand-hover: #2dac72; } } diff --git a/apps/sim/app/chat/components/auth/email/email-auth.tsx b/apps/sim/app/chat/components/auth/email/email-auth.tsx index 2515b92f4f4..3224e0bb4bb 100644 --- a/apps/sim/app/chat/components/auth/email/email-auth.tsx +++ b/apps/sim/app/chat/components/auth/email/email-auth.tsx @@ -7,7 +7,7 @@ import { Input, InputOTP, InputOTPGroup, InputOTPSlot, Label, Loader } from '@/c import { cn } from '@/lib/core/utils/cn' import { quickValidateEmail } from '@/lib/messaging/email/validation' import AuthBackground from '@/app/(auth)/components/auth-background' -import { AUTH_SUBMIT_BTN } from '@/app/(auth)/components/auth-button-classes' +import { AUTH_SUBMIT_BTN, AUTH_TEXT_LINK } from '@/app/(auth)/components/auth-button-classes' import { SupportFooter } from '@/app/(auth)/components/support-footer' import Navbar from '@/app/(landing)/components/navbar/navbar' import { useChatEmailOtpRequest, useChatEmailOtpVerify } from '@/hooks/queries/chats' @@ -123,7 +123,7 @@ export default function EmailAuth({ identifier }: EmailAuthProps) {
-

+

{showOtpVerification ? 'Verify Your Email' : 'Email Verification'}

@@ -159,11 +159,11 @@ export default function EmailAuth({ identifier }: EmailAuthProps) { className={cn( showEmailValidationError && emailErrors.length > 0 && - 'border-red-500 focus:border-red-500' + 'border-[var(--text-error)] focus:border-[var(--text-error)]' )} /> {showEmailValidationError && emailErrors.length > 0 && ( -

+
{emailErrors.map((error) => (

{error}

))} @@ -211,7 +211,7 @@ export default function EmailAuth({ identifier }: EmailAuthProps) { ))} @@ -219,7 +219,7 @@ export default function EmailAuth({ identifier }: EmailAuthProps) {
{authError && ( -
+

{authError}

)} @@ -251,7 +251,7 @@ export default function EmailAuth({ identifier }: EmailAuthProps) { ) : ( diff --git a/apps/sim/app/form/[identifier]/components/email-auth.tsx b/apps/sim/app/form/[identifier]/components/email-auth.tsx index b75cb159c3c..7fdc78b5aff 100644 --- a/apps/sim/app/form/[identifier]/components/email-auth.tsx +++ b/apps/sim/app/form/[identifier]/components/email-auth.tsx @@ -7,7 +7,7 @@ import { Input, InputOTP, InputOTPGroup, InputOTPSlot, Label, Loader } from '@/c import { cn } from '@/lib/core/utils/cn' import { quickValidateEmail } from '@/lib/messaging/email/validation' import AuthBackground from '@/app/(auth)/components/auth-background' -import { AUTH_SUBMIT_BTN } from '@/app/(auth)/components/auth-button-classes' +import { AUTH_SUBMIT_BTN, AUTH_TEXT_LINK } from '@/app/(auth)/components/auth-button-classes' import { SupportFooter } from '@/app/(auth)/components/support-footer' import Navbar from '@/app/(landing)/components/navbar/navbar' import { useFormEmailOtpRequest, useFormEmailOtpVerify } from '@/hooks/queries/forms' @@ -120,7 +120,7 @@ export function EmailAuth({ identifier, onAuthenticated }: EmailAuthProps) {
-

+

{showOtpVerification ? 'Verify Your Email' : 'Email Verification'}

@@ -154,11 +154,11 @@ export function EmailAuth({ identifier, onAuthenticated }: EmailAuthProps) { className={cn( showEmailValidationError && emailErrors.length > 0 && - 'border-red-500 focus:border-red-500' + 'border-[var(--text-error)] focus:border-[var(--text-error)]' )} /> {showEmailValidationError && emailErrors.length > 0 && ( -

+
{emailErrors.map((error) => (

{error}

))} @@ -206,7 +206,7 @@ export function EmailAuth({ identifier, onAuthenticated }: EmailAuthProps) { ))} @@ -214,7 +214,7 @@ export function EmailAuth({ identifier, onAuthenticated }: EmailAuthProps) {
{authError && ( -
+

{authError}

)} @@ -248,7 +248,7 @@ export function EmailAuth({ identifier, onAuthenticated }: EmailAuthProps) { ) : ( diff --git a/apps/sim/app/manifest.ts b/apps/sim/app/manifest.ts index cb91437f3c1..23e600614a0 100644 --- a/apps/sim/app/manifest.ts +++ b/apps/sim/app/manifest.ts @@ -18,7 +18,7 @@ export default function manifest(): MetadataRoute.Manifest { scope: '/', display: 'standalone', background_color: '#ffffff', - theme_color: brand.theme?.primaryColor || '#6F3DFA', + theme_color: brand.theme?.primaryColor || '#33C482', orientation: 'portrait-primary', icons: [ { diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/a2a/a2a.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/a2a/a2a.tsx index d2aae6bceb2..f5802447f10 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/a2a/a2a.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/a2a/a2a.tsx @@ -1,6 +1,6 @@ 'use client' -import { useCallback, useEffect, useMemo, useState } from 'react' +import { useEffect, useMemo, useState } from 'react' import { createLogger } from '@sim/logger' import { generateId } from '@sim/utils/id' import { Check, Clipboard } from 'lucide-react' @@ -81,7 +81,6 @@ interface A2aDeployProps { workflowNeedsRedeployment?: boolean onSubmittingChange?: (submitting: boolean) => void onCanSaveChange?: (canSave: boolean) => void - /** Callback for when republish status changes - depends on local form state */ onNeedsRepublishChange?: (needsRepublish: boolean) => void onDeployWorkflow?: () => Promise } @@ -147,13 +146,12 @@ export function A2aDeploy({ return missing }, [startBlockId, startBlockInputFormat]) - const handleAddA2AInputs = useCallback(() => { + const handleAddA2AInputs = () => { if (!startBlockId) return const normalizedExisting = normalizeInputFormatValue(startBlockInputFormat) const newFields: InputFormatField[] = [] - // Add input field if missing (for TextPart) if (missingFields.input) { newFields.push({ id: generateId(), @@ -164,7 +162,6 @@ export function A2aDeploy({ }) } - // Add data field if missing (for DataPart) if (missingFields.data) { newFields.push({ id: generateId(), @@ -175,7 +172,6 @@ export function A2aDeploy({ }) } - // Add files field if missing (for FilePart) if (missingFields.files) { newFields.push({ id: generateId(), @@ -193,7 +189,7 @@ export function A2aDeploy({ `Added A2A input fields to Start block: ${newFields.map((f) => f.name).join(', ')}` ) } - }, [startBlockId, startBlockInputFormat, missingFields, collaborativeSetSubblockValue]) + } const [name, setName] = useState('') const [description, setDescription] = useState('') @@ -258,10 +254,7 @@ export function A2aDeploy({ workflowName, ]) - const hasWorkflowChanges = useMemo(() => { - if (!existingAgent) return false - return !!workflowNeedsRedeployment - }, [existingAgent, workflowNeedsRedeployment]) + const hasWorkflowChanges = existingAgent ? !!workflowNeedsRedeployment : false const needsRepublish = existingAgent && (hasFormChanges || hasWorkflowChanges) @@ -284,7 +277,7 @@ export function A2aDeploy({ onSubmittingChange?.(isSubmitting) }, [isSubmitting, onSubmittingChange]) - const handleCreateOrUpdate = useCallback(async () => { + const handleCreateOrUpdate = async () => { const capabilities: AgentCapabilities = { streaming: true, pushNotifications: pushNotificationsEnabled, @@ -319,20 +312,9 @@ export function A2aDeploy({ } catch (error) { logger.error('Failed to save A2A agent:', error) } - }, [ - existingAgent, - name, - description, - pushNotificationsEnabled, - authScheme, - skillTags, - workspaceId, - workflowId, - createAgent, - updateAgent, - ]) + } - const handlePublish = useCallback(async () => { + const handlePublish = async () => { if (!existingAgent) return try { await publishAgent.mutateAsync({ @@ -343,9 +325,9 @@ export function A2aDeploy({ } catch (error) { logger.error('Failed to publish A2A agent:', error) } - }, [existingAgent, workspaceId, publishAgent]) + } - const handleUnpublish = useCallback(async () => { + const handleUnpublish = async () => { if (!existingAgent) return try { await publishAgent.mutateAsync({ @@ -356,9 +338,9 @@ export function A2aDeploy({ } catch (error) { logger.error('Failed to unpublish A2A agent:', error) } - }, [existingAgent, workspaceId, publishAgent]) + } - const handleDelete = useCallback(async () => { + const handleDelete = async () => { if (!existingAgent) return try { await deleteAgent.mutateAsync({ @@ -370,9 +352,9 @@ export function A2aDeploy({ } catch (error) { logger.error('Failed to delete A2A agent:', error) } - }, [existingAgent, workspaceId, deleteAgent, workflowName, workflowDescription]) + } - const handlePublishNewAgent = useCallback(async () => { + const handlePublishNewAgent = async () => { const capabilities: AgentCapabilities = { streaming: true, pushNotifications: pushNotificationsEnabled, @@ -406,21 +388,9 @@ export function A2aDeploy({ } catch (error) { logger.error('Failed to publish A2A agent:', error) } - }, [ - name, - description, - pushNotificationsEnabled, - authScheme, - skillTags, - workspaceId, - workflowId, - createAgent, - publishAgent, - isDeployed, - onDeployWorkflow, - ]) + } - const handleUpdateAndRepublish = useCallback(async () => { + const handleUpdateAndRepublish = async () => { if (!existingAgent) return const capabilities: AgentCapabilities = { @@ -455,20 +425,7 @@ export function A2aDeploy({ } catch (error) { logger.error('Failed to update and republish A2A agent:', error) } - }, [ - existingAgent, - isDeployed, - workflowNeedsRedeployment, - onDeployWorkflow, - name, - description, - pushNotificationsEnabled, - authScheme, - skillTags, - workspaceId, - updateAgent, - publishAgent, - ]) + } const baseUrl = getBaseUrl() const endpoint = existingAgent ? `${baseUrl}/api/a2a/serve/${existingAgent.id}` : null @@ -484,7 +441,7 @@ export function A2aDeploy({ ) }, [startBlockInputFormat]) - const getExampleInputData = useCallback((): Record => { + const getExampleInputData = (): Record => { const data: Record = {} for (const field of additionalInputFields) { switch (field.type) { @@ -508,13 +465,12 @@ export function A2aDeploy({ } } return data - }, [additionalInputFields]) + } - const getJsonRpcPayload = useCallback((): Record => { + const getJsonRpcPayload = (): Record => { const inputData = getExampleInputData() const hasAdditionalData = Object.keys(inputData).length > 0 - // Build parts array: TextPart for message text, DataPart for additional fields const parts: Array> = [{ kind: 'text', text: 'Hello, agent!' }] if (hasAdditionalData) { parts.push({ kind: 'data', data: inputData }) @@ -531,9 +487,9 @@ export function A2aDeploy({ }, }, } - }, [getExampleInputData, useStreamingExample]) + } - const getCurlCommand = useCallback((): string => { + const getCurlCommand = (): string => { if (!endpoint) return '' const payload = getJsonRpcPayload() const requiresAuth = authScheme !== 'none' @@ -623,13 +579,13 @@ console.log(data);` default: return '' } - }, [endpoint, language, getJsonRpcPayload, authScheme]) + } - const handleCopyCommand = useCallback(() => { + const handleCopyCommand = () => { navigator.clipboard.writeText(getCurlCommand()) setCodeCopied(true) setTimeout(() => setCodeCopied(false), 2000) - }, [getCurlCommand]) + } if (isLoading) { return ( @@ -664,7 +620,6 @@ console.log(data);` }} className='-mx-1 space-y-3 overflow-y-auto px-1 pb-4' > - {/* Endpoint URL (shown when agent exists) */} {existingAgent && endpoint && (
@@ -692,15 +647,15 @@ console.log(data);`
-
-
+
+
{baseUrl.replace(/^https?:\/\//, '')}/api/a2a/serve/
@@ -710,13 +665,12 @@ console.log(data);`
)} - {/* Agent Name */}
- {/* Description */}