@kolatts/pncli 1.10.1 → 1.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/copilot-instructions.md +34 -1
- package/dist/{chunk-O3LWAWSN.js → chunk-AWSXVWRN.js} +2 -1
- package/dist/{chunk-O3LWAWSN.js.map → chunk-AWSXVWRN.js.map} +1 -1
- package/dist/{chunk-3XHTRFRX.js → chunk-VPUWMP2M.js} +3 -2
- package/dist/chunk-VPUWMP2M.js.map +1 -0
- package/dist/cli.js +379 -8
- package/dist/cli.js.map +1 -1
- package/dist/{config-NCI2BTQG.js → config-OFLPO5DN.js} +4 -2
- package/dist/{http-L2P23H2D.js → http-LNDRNPP7.js} +2 -2
- package/package.json +5 -2
- package/skills/pncli/SKILL.md +92 -0
- package/skills/pncli/ado.md +33 -0
- package/skills/pncli/artifactory.md +35 -0
- package/skills/pncli/bitbucket.md +30 -0
- package/skills/pncli/checkmarx.md +31 -0
- package/skills/pncli/confluence.md +24 -0
- package/skills/pncli/contrast.md +39 -0
- package/skills/pncli/jenkins.md +29 -0
- package/skills/pncli/jira.md +35 -0
- package/skills/pncli/marketplace.md +41 -0
- package/skills/pncli/sde.md +29 -0
- package/skills/pncli/servicenow.md +33 -0
- package/skills/pncli/sonarqube.md +30 -0
- package/skills/pncli/sonatypeiq.md +39 -0
- package/skills/pncli/udeploy.md +48 -0
- package/dist/chunk-3XHTRFRX.js.map +0 -1
- package/skills/address-pr-feedback/SKILL.md +0 -87
- package/skills/code-review/SKILL.md +0 -82
- package/skills/local-setup/SKILL.md +0 -225
- package/skills/plan/SKILL.md +0 -120
- package/skills/security-review/SKILL.md +0 -108
- package/skills/ship/SKILL.md +0 -170
- /package/dist/{config-NCI2BTQG.js.map → config-OFLPO5DN.js.map} +0 -0
- /package/dist/{http-L2P23H2D.js.map → http-LNDRNPP7.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/http.ts","../src/lib/errors.ts","../src/lib/exitCodes.ts","../src/lib/output.ts","../src/lib/adoFetch.ts","../src/lib/checkmarxFetch.ts"],"sourcesContent":["import fs from 'fs';\nimport type { ResolvedConfig } from '../types/config.js';\nimport { PncliError } from './errors.js';\nimport { ExitCode } from './exitCodes.js';\nimport { log } from './output.js';\nimport { buildAdoFetcher } from './adoFetch.js';\nimport { buildCheckmarxFetcher } from './checkmarxFetch.js';\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface HttpRequestOptions {\n method?: HttpMethod;\n body?: unknown;\n params?: Record<string, string | number | boolean | undefined>;\n timeoutMs?: number;\n headers?: Record<string, string>;\n}\n\nexport interface HttpError {\n error: true;\n status: number;\n message: string;\n url: string;\n}\n\nfunction buildUrl(base: string, path: string, params?: Record<string, string | number | boolean | undefined>): string {\n const url = new URL(path, base.endsWith('/') ? base : base + '/');\n if (params) {\n for (const [key, val] of Object.entries(params)) {\n if (val !== undefined) {\n url.searchParams.set(key, String(val));\n }\n }\n }\n return url.toString();\n}\n\nasync function fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number, fetcher: typeof fetch = fetch): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await fetcher(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n}\n\nasync function request<T>(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n fetcher: typeof fetch = fetch\n): Promise<T> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n let response: Response;\n try {\n response = await fetchWithTimeout(url, init, timeoutMs, fetcher);\n } catch (err) {\n throw new PncliError(\n `Request failed: ${err instanceof Error ? err.message : String(err)}`,\n 0,\n url\n );\n }\n\n if (response.status === 429) {\n const retryAfter = response.headers.get('Retry-After');\n const waitMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : (attempt + 1) * 1000;\n log(`Rate limited. Retrying after ${waitMs}ms...`);\n await new Promise(resolve => setTimeout(resolve, waitMs));\n lastError = new PncliError('Rate limited', 429, url);\n continue;\n }\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const body = await response.text();\n const parsed = JSON.parse(body);\n const parts: string[] = [];\n // Jira: errorMessages is string[]\n if (Array.isArray(parsed.errorMessages)) {\n parts.push(...(parsed.errorMessages as string[]).filter(Boolean));\n }\n // errors as object map (Jira: Record<string, string>)\n if (parsed.errors && typeof parsed.errors === 'object' && !Array.isArray(parsed.errors)) {\n for (const [field, msg] of Object.entries(parsed.errors as Record<string, string>)) {\n parts.push(`${field}: ${msg}`);\n }\n }\n // errors as array of objects with message or msg field (SonarQube uses msg)\n if (Array.isArray(parsed.errors)) {\n for (const e of parsed.errors as Array<{ message?: string; msg?: string }>) {\n if (e?.message) parts.push(e.message);\n else if (e?.msg) parts.push(e.msg);\n }\n }\n // Generic APIs: { message: \"...\" }\n if (parts.length === 0 && parsed.message) {\n parts.push(String(parsed.message));\n }\n if (parts.length > 0) message = parts.join('; ');\n } catch {\n // ignore parse errors\n }\n throw new PncliError(message, response.status, url);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n const text = await response.text();\n if (!text) return undefined as T;\n return JSON.parse(text) as T;\n }\n\n throw lastError ?? new PncliError('Request failed after retries', 1, url);\n}\n\nexport class HttpClient {\n private config: ResolvedConfig;\n private dryRun: boolean;\n private adoFetcher: typeof fetch | null = null;\n private checkmarxFetcher: typeof fetch | null = null;\n\n constructor(config: ResolvedConfig, dryRun = false) {\n this.config = config;\n this.dryRun = dryRun;\n }\n\n private jiraHeaders(): Record<string, string> {\n const { apiToken } = this.config.jira;\n if (!apiToken) throw new PncliError('Jira credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${apiToken}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n private bitbucketHeaders(): Record<string, string> {\n const { pat } = this.config.bitbucket;\n if (!pat) throw new PncliError('Bitbucket credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${pat}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async jira<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.jira.baseUrl;\n if (!baseUrl) throw new PncliError('Jira baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.jiraHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async bitbucket<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.bitbucket.baseUrl;\n if (!baseUrl) throw new PncliError('Bitbucket baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.bitbucketHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private confluenceHeaders(): Record<string, string> {\n const { apiToken } = this.config.confluence;\n if (!apiToken) throw new PncliError('Confluence credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${apiToken}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async confluence<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.confluence.baseUrl;\n if (!baseUrl) throw new PncliError('Confluence baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.confluenceHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private sdeHeaders(): Record<string, string> {\n const { token } = this.config.sde;\n if (!token) throw new PncliError('SDElements credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Token ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async sde<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.sde.baseUrl;\n if (!baseUrl) throw new PncliError('SDElements baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.sdeHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async sdePaginate<T>(\n fetchPage: (page: number, pageSize: number) => Promise<{ count: number; results: T[] }>\n ): Promise<T[]> {\n const results: T[] = [];\n let page = 1;\n const pageSize = 100;\n\n while (true) {\n const response = await fetchPage(page, pageSize);\n results.push(...response.results);\n if (results.length >= response.count || response.results.length === 0) break;\n page++;\n }\n\n return results;\n }\n\n private async getAdoFetcher(): Promise<typeof fetch> {\n if (!this.adoFetcher) {\n this.adoFetcher = await buildAdoFetcher(this.config);\n }\n return this.adoFetcher;\n }\n\n async ado<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n const msg = `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const defaultHeaders: Record<string, string> = {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json',\n ...opts.headers\n };\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers: defaultHeaders,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n return request<T>(url, init, opts.timeoutMs ?? 30000, fetcher);\n }\n\n async adoText(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<string> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers: { 'Accept': 'text/plain', ...opts.headers }\n }, opts.timeoutMs ?? 30000, fetcher);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return response.text();\n }\n\n async adoRaw(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<{ data: unknown; headers: Headers }> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? 30000);\n let response: Response;\n try {\n response = await fetcher(url, {\n method: opts.method ?? 'GET',\n headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', ...opts.headers },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n const text = await response.text();\n const data = text ? JSON.parse(text) : undefined;\n return { data, headers: response.headers };\n }\n\n async adoPaginate<T>(\n fetchPage: (continuationToken?: string) => Promise<{ data: { value: T[] }; headers: Headers }>\n ): Promise<T[]> {\n const results: T[] = [];\n let token: string | undefined;\n\n while (true) {\n const { data, headers } = await fetchPage(token);\n results.push(...(data.value ?? []));\n const next = headers.get('x-ms-continuationtoken');\n if (!next) break;\n token = next;\n }\n\n return results;\n }\n\n private jenkinsHeaders(): Record<string, string> {\n const { username, apiToken } = this.config.jenkins;\n if (!username || !apiToken) throw new PncliError('Jenkins credentials not configured. Run: pncli config init');\n const creds = Buffer.from(`${username}:${apiToken}`).toString('base64');\n return {\n 'Authorization': `Basic ${creds}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n private artifactoryHeaders(): Record<string, string> {\n const { token } = this.config.artifactory;\n if (!token) throw new PncliError('Artifactory credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n private udeployHeaders(): Record<string, string> {\n const { pat, username, password } = this.config.udeploy;\n let encoded: string;\n if (username && password) {\n encoded = Buffer.from(`${username}:${password}`).toString('base64');\n } else if (username && pat) {\n encoded = Buffer.from(`${username}:${pat}`).toString('base64');\n } else if (pat) {\n encoded = Buffer.from(`PasswordIsAuthToken:${JSON.stringify({ token: pat })}`).toString('base64');\n } else {\n throw new PncliError('UDeploy credentials not configured. Run: pncli config init');\n }\n return {\n 'Authorization': `Basic ${encoded}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async jenkins<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.jenkins.baseUrl;\n if (!baseUrl) throw new PncliError('Jenkins baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.jenkinsHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async jenkinsRaw(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<{ status: number; headers: Headers; text: string }> {\n const baseUrl = this.config.jenkins.baseUrl;\n if (!baseUrl) throw new PncliError('Jenkins baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.jenkinsHeaders();\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${opts.method ?? 'GET'} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n }, opts.timeoutMs ?? 30000);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return { status: response.status, headers: response.headers, text: await response.text() };\n }\n\n async artifactory<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.artifactory.baseUrl;\n if (!baseUrl) throw new PncliError('Artifactory baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = { ...this.artifactoryHeaders(), ...opts.headers };\n\n // AQL search uses text/plain body — don't JSON-serialize it\n const body = opts.body !== undefined\n ? (typeof opts.body === 'string' ? opts.body : JSON.stringify(opts.body))\n : undefined;\n\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${typeof opts.body === 'string' ? opts.body : JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n\n async udeploy<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.udeploy.baseUrl;\n if (!baseUrl) throw new PncliError('UDeploy baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.udeployHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async artifactoryText(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<string> {\n const baseUrl = this.config.artifactory.baseUrl;\n if (!baseUrl) throw new PncliError('Artifactory baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = { ...this.artifactoryHeaders(), Accept: 'text/plain', ...opts.headers };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers\n }, opts.timeoutMs ?? 30000);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return response.text();\n }\n\n\n\n private sonarHeaders(): Record<string, string> {\n const { token } = this.config.sonar;\n if (!token) throw new PncliError('SonarQube credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async sonar<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.sonar.baseUrl;\n if (!baseUrl) throw new PncliError('SonarQube baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.sonarHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async sonarPaginate<T>(\n fetchPage: (page: number, pageSize: number) => Promise<{ total: number; p: number; ps: number; items: T[] }>\n ): Promise<T[]> {\n const results: T[] = [];\n let page = 1;\n const pageSize = 500;\n\n while (true) {\n const response = await fetchPage(page, pageSize);\n results.push(...response.items);\n if (results.length >= response.total || response.items.length === 0) break;\n page++;\n }\n\n return results;\n }\n\n async confluencePaginate<T>(\n fetchPage: (start: number, limit: number) => Promise<{ results: T[]; start: number; limit: number; size: number; _links: { next?: string } }>\n ): Promise<T[]> {\n const results: T[] = [];\n let start = 0;\n const limit = 25;\n\n while (true) {\n const page = await fetchPage(start, limit);\n results.push(...page.results);\n if (!page._links.next) break;\n start += page.size;\n }\n\n return results;\n }\n\n async paginate<T>(\n fetchPage: (start: number, limit: number) => Promise<{ values: T[]; isLastPage: boolean; nextPageStart?: number }>\n ): Promise<T[]> {\n const results: T[] = [];\n let start = 0;\n const limit = 100;\n\n while (true) {\n const page = await fetchPage(start, limit);\n results.push(...page.values);\n if (page.isLastPage) break;\n start = page.nextPageStart ?? start + limit;\n }\n\n return results;\n }\n\n async jiraPaginate<T>(\n fetchPage: (startAt: number, maxResults: number) => Promise<{ issues?: T[]; values?: T[]; total: number; startAt: number; maxResults: number }>\n ): Promise<T[]> {\n const results: T[] = [];\n let startAt = 0;\n const maxResults = 100;\n\n while (true) {\n const page = await fetchPage(startAt, maxResults);\n const items = (page.issues ?? page.values ?? []) as T[];\n results.push(...items);\n startAt += items.length;\n if (startAt >= page.total || items.length === 0) break;\n }\n\n return results;\n }\n\n private getCheckmarxFetcher(): typeof fetch {\n if (!this.checkmarxFetcher) {\n this.checkmarxFetcher = buildCheckmarxFetcher(this.config);\n }\n return this.checkmarxFetcher;\n }\n\n private servicenowHeaders(): Record<string, string> {\n const { username, password, apiToken } = this.config.servicenow;\n let encoded: string;\n if (username && apiToken) {\n encoded = Buffer.from(`${username}:${apiToken}`).toString('base64');\n } else if (username && password) {\n encoded = Buffer.from(`${username}:${password}`).toString('base64');\n } else {\n throw new PncliError('ServiceNow credentials not configured. Run: pncli config init');\n }\n return {\n 'Authorization': `Basic ${encoded}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async servicenow<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.servicenow.baseUrl;\n if (!baseUrl) throw new PncliError('ServiceNow baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.servicenowHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private contrastHeaders(): Record<string, string> {\n const { apiKey, serviceKey, username } = this.config.contrast;\n if (!apiKey || !serviceKey || !username) {\n throw new PncliError('Contrast credentials not configured. Run: pncli config init');\n }\n const authorization = Buffer.from(`${username}:${serviceKey}`).toString('base64');\n return {\n 'Authorization': authorization,\n 'API-Key': apiKey,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async contrast<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.contrast.baseUrl ?? 'https://app.contrastsecurity.com';\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.contrastHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]', 'API-Key': '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private sonatypeiqHeaders(): Record<string, string> {\n const { userCode, passcode } = this.config.sonatypeiq;\n if (!userCode || !passcode) throw new PncliError('Sonatype IQ credentials not configured. Run: pncli config init');\n const encoded = Buffer.from(`${userCode}:${passcode}`).toString('base64');\n return {\n 'Authorization': `Basic ${encoded}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async sonatypeiq<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.sonatypeiq.baseUrl;\n if (!baseUrl) throw new PncliError('Sonatype IQ Server baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.sonatypeiqHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async checkmarx<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.checkmarx.baseUrl;\n if (!baseUrl) throw new PncliError('Checkmarx baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n const msg = `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = this.getCheckmarxFetcher();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', ...opts.headers },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n return request<T>(url, init, opts.timeoutMs ?? 30000, fetcher);\n }\n}\n\nexport function createHttpClient(config: ResolvedConfig, dryRun = false): HttpClient {\n return new HttpClient(config, dryRun);\n}\n","export class PncliError extends Error {\n status: number;\n url?: string;\n\n constructor(message: string, status: number = 1, url?: string) {\n super(message);\n this.name = 'PncliError';\n this.status = status;\n this.url = url;\n }\n}\n","export const ExitCode = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n USAGE_ERROR: 2,\n NETWORK_ERROR: 69, // EX_UNAVAILABLE from sysexits.h\n AUTH_ERROR: 77, // EX_NOPERM from sysexits.h\n CONFIG_ERROR: 78, // EX_CONFIG from sysexits.h\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport function exitCodeFromStatus(httpStatus: number): ExitCode {\n if (httpStatus === 401 || httpStatus === 403) return ExitCode.AUTH_ERROR;\n if (httpStatus === 0) return ExitCode.NETWORK_ERROR;\n return ExitCode.GENERAL_ERROR;\n}\n","import fs from 'fs';\nimport chalk from 'chalk';\nimport type { Meta, SuccessEnvelope, ErrorEnvelope, ErrorDetail } from '../types/common.js';\nimport { PncliError } from './errors.js';\nimport { ExitCode, exitCodeFromStatus } from './exitCodes.js';\n\nlet globalOptions = { pretty: false, verbose: false };\nlet globalUser: { email: string | undefined; userId: string | undefined } = { email: undefined, userId: undefined };\nlet outputFile: string | undefined;\n\nexport function setGlobalOptions(opts: { pretty: boolean; verbose: boolean; outputFile?: string }): void {\n globalOptions = { pretty: opts.pretty, verbose: opts.verbose };\n outputFile = opts.outputFile;\n}\n\nexport function setGlobalUser(user: { email: string | undefined; userId: string | undefined }): void {\n globalUser = user;\n}\n\nfunction buildMeta(service: string, action: string, startTime: number): Meta {\n return {\n service,\n action,\n timestamp: new Date().toISOString(),\n duration_ms: Date.now() - startTime,\n user: (globalUser.email ?? globalUser.userId) ? globalUser : undefined\n };\n}\n\nfunction writeToFile(filePath: string, content: string): void {\n try {\n fs.writeFileSync(filePath, content, 'utf8');\n } catch (writeErr) {\n process.stderr.write(\n `Warning: could not write to output file \"${filePath}\": ${(writeErr as NodeJS.ErrnoException).message}\\n`\n );\n process.exitCode = ExitCode.GENERAL_ERROR;\n }\n}\n\nexport function success<T>(data: T, service: string, action: string, startTime: number): void {\n const envelope: SuccessEnvelope<T> = {\n ok: true,\n data,\n meta: buildMeta(service, action, startTime)\n };\n const out = (globalOptions.pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope)) + '\\n';\n if (outputFile) {\n writeToFile(outputFile, out);\n } else {\n process.stdout.write(out);\n }\n}\n\nexport function fail(\n err: unknown,\n service: string,\n action: string,\n startTime: number\n): never {\n const errorDetail: ErrorDetail = {\n status: err instanceof PncliError ? err.status : 1,\n message: err instanceof Error ? err.message : String(err),\n url: err instanceof PncliError ? (err.url ?? null) : null\n };\n\n const envelope: ErrorEnvelope = {\n ok: false,\n error: errorDetail,\n meta: buildMeta(service, action, startTime)\n };\n\n const msg = globalOptions.pretty\n ? chalk.red('✗ Error: ') + errorDetail.message\n : null;\n\n if (msg) process.stderr.write(msg + '\\n');\n\n const output = (globalOptions.pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope)) + '\\n';\n const exitCode = err instanceof PncliError ? exitCodeFromStatus(err.status) : ExitCode.GENERAL_ERROR;\n if (outputFile) {\n writeToFile(outputFile, output);\n } else {\n try {\n fs.writeSync(process.stdout.fd, output);\n } catch (writeErr) {\n if ((writeErr as NodeJS.ErrnoException).code !== 'EPIPE') throw writeErr;\n }\n }\n process.exitCode = exitCode;\n throw new PncliError(errorDetail.message, errorDetail.status);\n}\n\nexport function log(message: string): void {\n if (globalOptions.verbose) {\n process.stderr.write(\n (globalOptions.pretty ? chalk.gray('▸ ') : '') + message + '\\n'\n );\n }\n}\n\nexport function warn(message: string): void {\n process.stderr.write(\n (globalOptions.pretty ? chalk.yellow('⚠ ') : '') + message + '\\n'\n );\n}\n","import type { ResolvedConfig } from '../types/config.js';\nimport { PncliError } from './errors.js';\n\n/**\n * Returns a fetch-compatible function for Azure DevOps Server requests,\n * with Basic auth (PAT) injected into every call.\n */\nexport async function buildAdoFetcher(\n config: ResolvedConfig\n): Promise<typeof fetch> {\n const { pat, baseUrl } = config.ado;\n\n if (!baseUrl) {\n throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init', 1);\n }\n\n if (!pat) {\n throw new PncliError(\n 'Azure DevOps PAT not configured. Set a PAT via pncli config init or PNCLI_ADO_PAT env var.',\n 1\n );\n }\n\n const encoded = Buffer.from(':' + pat).toString('base64');\n const authHeader = `Basic ${encoded}`;\n return (url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]) =>\n fetch(url, {\n ...init,\n headers: {\n ...(init?.headers as Record<string, string> | undefined),\n 'Authorization': authHeader,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n }\n });\n}\n","import type { ResolvedConfig } from '../types/config.js';\nimport type { CheckmarxTokenResponse } from '../types/checkmarx.js';\nimport { PncliError } from './errors.js';\n\nconst CX_CLIENT_ID = 'resource_owner_client';\nconst CX_CLIENT_SECRET = '014DF517-39D1-4453-B7B3-9930C563627C';\nconst CX_SCOPE = 'sast_api offline_access';\n\ninterface TokenCache {\n value: string;\n expiresAt: number;\n}\n\n/**\n * Returns a fetch-compatible function for Checkmarx CxSAST 9.x requests,\n * with OAuth2 password-grant token exchange and bearer auth injected into every call.\n * The token is cached for the lifetime of the returned fetcher and refreshed\n * when within 60s of expiry.\n */\nexport function buildCheckmarxFetcher(config: ResolvedConfig): typeof fetch {\n const { baseUrl, username, password } = config.checkmarx;\n\n if (!baseUrl) throw new PncliError('Checkmarx baseUrl not configured. Run: pncli config init', 1);\n if (!username) throw new PncliError('Checkmarx username not configured. Run: pncli config init', 1);\n if (!password) throw new PncliError('Checkmarx password not configured. Run: pncli config init', 1);\n\n // Capture as definite strings for use inside the closure (TypeScript can't narrow across closures)\n const resolvedUsername: string = username;\n const resolvedPassword: string = password;\n const tokenUrl = `${baseUrl.replace(/\\/$/, '')}/cxrestapi/auth/identity/connect/token`;\n let cache: TokenCache | null = null;\n\n async function getToken(): Promise<string> {\n const now = Date.now();\n if (cache && cache.expiresAt - now > 60_000) {\n return cache.value;\n }\n\n const body = new URLSearchParams({\n grant_type: 'password',\n client_id: CX_CLIENT_ID,\n client_secret: CX_CLIENT_SECRET,\n scope: CX_SCOPE,\n username: resolvedUsername,\n password: resolvedPassword\n });\n\n const response = await fetch(tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString()\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new PncliError(\n `Checkmarx token exchange failed (${response.status}): ${text || response.statusText}`,\n response.status\n );\n }\n\n const data = await response.json() as CheckmarxTokenResponse;\n if (!data.access_token) {\n throw new PncliError('Checkmarx token endpoint returned no access_token', response.status);\n }\n cache = {\n value: data.access_token,\n expiresAt: now + data.expires_in * 1000\n };\n return cache.value;\n }\n\n // Intentionally synchronous (unlike buildAdoFetcher which is async): the token exchange\n // happens lazily inside getToken() on the first actual API call, not during construction.\n return async (url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]): Promise<Response> => {\n const token = await getToken();\n return fetch(url, {\n ...init,\n headers: {\n ...(init?.headers as Record<string, string> | undefined),\n 'Authorization': `Bearer ${token}`\n }\n });\n };\n}\n"],"mappings":";;;AAAA,OAAOA,SAAQ;;;ACAR,IAAM,aAAN,cAAyB,MAAM;AAAA,EACpC;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,SAAiB,GAAG,KAAc;AAC7D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,MAAM;AAAA,EACb;AACF;;;ACVO,IAAM,WAAW;AAAA,EACtB,SAAS;AAAA,EACT,eAAe;AAAA,EACf,aAAa;AAAA,EACb,eAAe;AAAA;AAAA,EACf,YAAY;AAAA;AAAA,EACZ,cAAc;AAAA;AAChB;AAIO,SAAS,mBAAmB,YAA8B;AAC/D,MAAI,eAAe,OAAO,eAAe,IAAK,QAAO,SAAS;AAC9D,MAAI,eAAe,EAAG,QAAO,SAAS;AACtC,SAAO,SAAS;AAClB;;;ACfA,OAAO,QAAQ;AACf,OAAO,WAAW;AAKlB,IAAI,gBAAgB,EAAE,QAAQ,OAAO,SAAS,MAAM;AACpD,IAAI,aAAwE,EAAE,OAAO,QAAW,QAAQ,OAAU;AAClH,IAAI;AAEG,SAAS,iBAAiB,MAAwE;AACvG,kBAAgB,EAAE,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ;AAC7D,eAAa,KAAK;AACpB;AAEO,SAAS,cAAc,MAAuE;AACnG,eAAa;AACf;AAEA,SAAS,UAAU,SAAiB,QAAgB,WAAyB;AAC3E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,aAAa,KAAK,IAAI,IAAI;AAAA,IAC1B,MAAO,WAAW,SAAS,WAAW,SAAU,aAAa;AAAA,EAC/D;AACF;AAEA,SAAS,YAAY,UAAkB,SAAuB;AAC5D,MAAI;AACF,OAAG,cAAc,UAAU,SAAS,MAAM;AAAA,EAC5C,SAAS,UAAU;AACjB,YAAQ,OAAO;AAAA,MACb,4CAA4C,QAAQ,MAAO,SAAmC,OAAO;AAAA;AAAA,IACvG;AACA,YAAQ,WAAW,SAAS;AAAA,EAC9B;AACF;AAEO,SAAS,QAAW,MAAS,SAAiB,QAAgB,WAAyB;AAC5F,QAAM,WAA+B;AAAA,IACnC,IAAI;AAAA,IACJ;AAAA,IACA,MAAM,UAAU,SAAS,QAAQ,SAAS;AAAA,EAC5C;AACA,QAAM,OAAO,cAAc,SAAS,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI,KAAK,UAAU,QAAQ,KAAK;AACpG,MAAI,YAAY;AACd,gBAAY,YAAY,GAAG;AAAA,EAC7B,OAAO;AACL,YAAQ,OAAO,MAAM,GAAG;AAAA,EAC1B;AACF;AAEO,SAAS,KACd,KACA,SACA,QACA,WACO;AACP,QAAM,cAA2B;AAAA,IAC/B,QAAQ,eAAe,aAAa,IAAI,SAAS;AAAA,IACjD,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACxD,KAAK,eAAe,aAAc,IAAI,OAAO,OAAQ;AAAA,EACvD;AAEA,QAAM,WAA0B;AAAA,IAC9B,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM,UAAU,SAAS,QAAQ,SAAS;AAAA,EAC5C;AAEA,QAAM,MAAM,cAAc,SACtB,MAAM,IAAI,gBAAW,IAAI,YAAY,UACrC;AAEJ,MAAI,IAAK,SAAQ,OAAO,MAAM,MAAM,IAAI;AAExC,QAAM,UAAU,cAAc,SAAS,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI,KAAK,UAAU,QAAQ,KAAK;AACvG,QAAM,WAAW,eAAe,aAAa,mBAAmB,IAAI,MAAM,IAAI,SAAS;AACvF,MAAI,YAAY;AACd,gBAAY,YAAY,MAAM;AAAA,EAChC,OAAO;AACL,QAAI;AACF,SAAG,UAAU,QAAQ,OAAO,IAAI,MAAM;AAAA,IACxC,SAAS,UAAU;AACjB,UAAK,SAAmC,SAAS,QAAS,OAAM;AAAA,IAClE;AAAA,EACF;AACA,UAAQ,WAAW;AACnB,QAAM,IAAI,WAAW,YAAY,SAAS,YAAY,MAAM;AAC9D;AAEO,SAAS,IAAI,SAAuB;AACzC,MAAI,cAAc,SAAS;AACzB,YAAQ,OAAO;AAAA,OACZ,cAAc,SAAS,MAAM,KAAK,SAAI,IAAI,MAAM,UAAU;AAAA,IAC7D;AAAA,EACF;AACF;AAEO,SAAS,KAAK,SAAuB;AAC1C,UAAQ,OAAO;AAAA,KACZ,cAAc,SAAS,MAAM,OAAO,SAAI,IAAI,MAAM,UAAU;AAAA,EAC/D;AACF;;;AClGA,eAAsB,gBACpB,QACuB;AACvB,QAAM,EAAE,KAAK,QAAQ,IAAI,OAAO;AAEhC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,WAAW,+DAA+D,CAAC;AAAA,EACvF;AAEA,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,KAAK,MAAM,GAAG,EAAE,SAAS,QAAQ;AACxD,QAAM,aAAa,SAAS,OAAO;AACnC,SAAO,CAAC,KAAkC,SACxC,MAAM,KAAK;AAAA,IACT,GAAG;AAAA,IACH,SAAS;AAAA,MACP,GAAI,MAAM;AAAA,MACV,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AACL;;;AC/BA,IAAM,eAAe;AACrB,IAAM,mBAAmB;AACzB,IAAM,WAAW;AAaV,SAAS,sBAAsB,QAAsC;AAC1E,QAAM,EAAE,SAAS,UAAU,SAAS,IAAI,OAAO;AAE/C,MAAI,CAAC,QAAS,OAAM,IAAI,WAAW,4DAA4D,CAAC;AAChG,MAAI,CAAC,SAAU,OAAM,IAAI,WAAW,6DAA6D,CAAC;AAClG,MAAI,CAAC,SAAU,OAAM,IAAI,WAAW,6DAA6D,CAAC;AAGlG,QAAM,mBAA2B;AACjC,QAAM,mBAA2B;AACjC,QAAM,WAAW,GAAG,QAAQ,QAAQ,OAAO,EAAE,CAAC;AAC9C,MAAI,QAA2B;AAE/B,iBAAe,WAA4B;AACzC,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,SAAS,MAAM,YAAY,MAAM,KAAQ;AAC3C,aAAO,MAAM;AAAA,IACf;AAEA,UAAM,OAAO,IAAI,gBAAgB;AAAA,MAC/B,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,eAAe;AAAA,MACf,OAAO;AAAA,MACP,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAED,UAAM,WAAW,MAAM,MAAM,UAAU;AAAA,MACrC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,oCAAoC;AAAA,MAC/D,MAAM,KAAK,SAAS;AAAA,IACtB,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,EAAE;AACjD,YAAM,IAAI;AAAA,QACR,oCAAoC,SAAS,MAAM,MAAM,QAAQ,SAAS,UAAU;AAAA,QACpF,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,WAAW,qDAAqD,SAAS,MAAM;AAAA,IAC3F;AACA,YAAQ;AAAA,MACN,OAAO,KAAK;AAAA,MACZ,WAAW,MAAM,KAAK,aAAa;AAAA,IACrC;AACA,WAAO,MAAM;AAAA,EACf;AAIA,SAAO,OAAO,KAAkC,SAA0D;AACxG,UAAM,QAAQ,MAAM,SAAS;AAC7B,WAAO,MAAM,KAAK;AAAA,MAChB,GAAG;AAAA,MACH,SAAS;AAAA,QACP,GAAI,MAAM;AAAA,QACV,iBAAiB,UAAU,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AL3DA,SAAS,SAAS,MAAc,MAAc,QAAwE;AACpH,QAAM,MAAM,IAAI,IAAI,MAAM,KAAK,SAAS,GAAG,IAAI,OAAO,OAAO,GAAG;AAChE,MAAI,QAAQ;AACV,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,UAAI,QAAQ,QAAW;AACrB,YAAI,aAAa,IAAI,KAAK,OAAO,GAAG,CAAC;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACA,SAAO,IAAI,SAAS;AACtB;AAEA,eAAe,iBAAiB,KAAa,MAAmB,WAAmB,UAAwB,OAA0B;AACnI,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS;AAC5D,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK,EAAE,GAAG,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EAClE,UAAE;AACA,iBAAa,KAAK;AAAA,EACpB;AACF;AAEA,eAAe,QACb,KACA,MACA,WACA,UAAwB,OACZ;AACZ,MAAI;AAEJ,WAAS,UAAU,GAAG,UAAU,GAAG,WAAW;AAC5C,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,iBAAiB,KAAK,MAAM,WAAW,OAAO;AAAA,IACjE,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,mBAAmB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACnE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,aAAa,SAAS,QAAQ,IAAI,aAAa;AACrD,YAAM,SAAS,aAAa,SAAS,YAAY,EAAE,IAAI,OAAQ,UAAU,KAAK;AAC9E,UAAI,gCAAgC,MAAM,OAAO;AACjD,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,MAAM,CAAC;AACxD,kBAAY,IAAI,WAAW,gBAAgB,KAAK,GAAG;AACnD;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,UAAU,QAAQ,SAAS,MAAM,IAAI,SAAS,UAAU;AAC5D,UAAI;AACF,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,cAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,cAAM,QAAkB,CAAC;AAEzB,YAAI,MAAM,QAAQ,OAAO,aAAa,GAAG;AACvC,gBAAM,KAAK,GAAI,OAAO,cAA2B,OAAO,OAAO,CAAC;AAAA,QAClE;AAEA,YAAI,OAAO,UAAU,OAAO,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,OAAO,MAAM,GAAG;AACvF,qBAAW,CAAC,OAAO,GAAG,KAAK,OAAO,QAAQ,OAAO,MAAgC,GAAG;AAClF,kBAAM,KAAK,GAAG,KAAK,KAAK,GAAG,EAAE;AAAA,UAC/B;AAAA,QACF;AAEA,YAAI,MAAM,QAAQ,OAAO,MAAM,GAAG;AAChC,qBAAW,KAAK,OAAO,QAAqD;AAC1E,gBAAI,GAAG,QAAS,OAAM,KAAK,EAAE,OAAO;AAAA,qBAC3B,GAAG,IAAK,OAAM,KAAK,EAAE,GAAG;AAAA,UACnC;AAAA,QACF;AAEA,YAAI,MAAM,WAAW,KAAK,OAAO,SAAS;AACxC,gBAAM,KAAK,OAAO,OAAO,OAAO,CAAC;AAAA,QACnC;AACA,YAAI,MAAM,SAAS,EAAG,WAAU,MAAM,KAAK,IAAI;AAAA,MACjD,QAAQ;AAAA,MAER;AACA,YAAM,IAAI,WAAW,SAAS,SAAS,QAAQ,GAAG;AAAA,IACpD;AAEA,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAEA,QAAM,aAAa,IAAI,WAAW,gCAAgC,GAAG,GAAG;AAC1E;AAEO,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EACA;AAAA,EACA,aAAkC;AAAA,EAClC,mBAAwC;AAAA,EAEhD,YAAY,QAAwB,SAAS,OAAO;AAClD,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAChB;AAAA,EAEQ,cAAsC;AAC5C,UAAM,EAAE,SAAS,IAAI,KAAK,OAAO;AACjC,QAAI,CAAC,SAAU,OAAM,IAAI,WAAW,yDAAyD;AAC7F,WAAO;AAAA,MACL,iBAAiB,UAAU,QAAQ;AAAA,MACnC,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEQ,mBAA2C;AACjD,UAAM,EAAE,IAAI,IAAI,KAAK,OAAO;AAC5B,QAAI,CAAC,IAAK,OAAM,IAAI,WAAW,8DAA8D;AAC7F,WAAO;AAAA,MACL,iBAAiB,UAAU,GAAG;AAAA,MAC9B,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,KACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,KAAK;AACjC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,qDAAqD;AAExF,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,YAAY;AACjC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAC,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAEA,MAAM,UACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,UAAU;AACtC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,0DAA0D;AAE7F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,iBAAiB;AACtC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAEQ,oBAA4C;AAClD,UAAM,EAAE,SAAS,IAAI,KAAK,OAAO;AACjC,QAAI,CAAC,SAAU,OAAM,IAAI,WAAW,+DAA+D;AACnG,WAAO;AAAA,MACL,iBAAiB,UAAU,QAAQ;AAAA,MACnC,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,WACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,WAAW;AACvC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,2DAA2D;AAE9F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,kBAAkB;AACvC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAEQ,aAAqC;AAC3C,UAAM,EAAE,MAAM,IAAI,KAAK,OAAO;AAC9B,QAAI,CAAC,MAAO,OAAM,IAAI,WAAW,+DAA+D;AAChG,WAAO;AAAA,MACL,iBAAiB,SAAS,KAAK;AAAA,MAC/B,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,IACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,IAAI;AAChC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,2DAA2D;AAE9F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,WAAW;AAChC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAEA,MAAM,YACJ,WACc;AACd,UAAM,UAAe,CAAC;AACtB,QAAI,OAAO;AACX,UAAM,WAAW;AAEjB,WAAO,MAAM;AACX,YAAM,WAAW,MAAM,UAAU,MAAM,QAAQ;AAC/C,cAAQ,KAAK,GAAG,SAAS,OAAO;AAChC,UAAI,QAAQ,UAAU,SAAS,SAAS,SAAS,QAAQ,WAAW,EAAG;AACvE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,gBAAuC;AACnD,QAAI,CAAC,KAAK,YAAY;AACpB,WAAK,aAAa,MAAM,gBAAgB,KAAK,MAAM;AAAA,IACrD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,IACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,IAAI;AAChC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,6DAA6D;AAEhG,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAE/C,QAAI,KAAK,QAAQ;AACf,YAAM,MAAM,YAAY,KAAK,UAAU,KAAK,IAAI,GAAG;AAAA,KAC9C,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,UAAM,UAAU,MAAM,KAAK,cAAc;AACzC,UAAM,iBAAyC;AAAA,MAC7C,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,GAAG,KAAK;AAAA,IACV;AACA,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB,SAAS;AAAA,MACT,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,KAAO,OAAO;AAAA,EAC/D;AAAA,EAEA,MAAM,QACJ,MACA,OAA2B,CAAC,GACX;AACjB,UAAM,UAAU,KAAK,OAAO,IAAI;AAChC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,6DAA6D;AAEhG,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAE/C,QAAI,KAAK,QAAQ;AACf,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,YAAY,KAAK,UAAU,KAAK,IAAI,GAAG;AAAA,CAAI;AAC3E,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,UAAM,UAAU,MAAM,KAAK,cAAc;AACzC,UAAM,WAAW,MAAM,iBAAiB,KAAK;AAAA,MAC3C,QAAQ,KAAK,UAAU;AAAA,MACvB,SAAS,EAAE,UAAU,cAAc,GAAG,KAAK,QAAQ;AAAA,IACrD,GAAG,KAAK,aAAa,KAAO,OAAO;AAEnC,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,UAAU,QAAQ,SAAS,MAAM,IAAI,SAAS,UAAU;AAC5D,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,MAAM,SAAS,KAAK,CAAC;AAC/C,YAAI,OAAO,QAAS,WAAU,OAAO,OAAO,OAAO;AAAA,MACrD,QAAQ;AAAA,MAAe;AACvB,YAAM,IAAI,WAAW,SAAS,SAAS,QAAQ,GAAG;AAAA,IACpD;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA,EAEA,MAAM,OACJ,MACA,OAA2B,CAAC,GACkB;AAC9C,UAAM,UAAU,KAAK,OAAO,IAAI;AAChC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,6DAA6D;AAEhG,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAE/C,QAAI,KAAK,QAAQ;AACf,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,YAAY,KAAK,UAAU,KAAK,IAAI,GAAG;AAAA,CAAI;AAC3E,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,UAAM,UAAU,MAAM,KAAK,cAAc;AACzC,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,aAAa,GAAK;AAC1E,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,QAAQ,KAAK;AAAA,QAC5B,QAAQ,KAAK,UAAU;AAAA,QACvB,SAAS,EAAE,UAAU,oBAAoB,gBAAgB,oBAAoB,GAAG,KAAK,QAAQ;AAAA,QAC7F,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,QAC5D,QAAQ,WAAW;AAAA,MACrB,CAAC;AAAA,IACH,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,UAAU,QAAQ,SAAS,MAAM,IAAI,SAAS,UAAU;AAC5D,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,MAAM,SAAS,KAAK,CAAC;AAC/C,YAAI,OAAO,QAAS,WAAU,OAAO,OAAO,OAAO;AAAA,MACrD,QAAQ;AAAA,MAAe;AACvB,YAAM,IAAI,WAAW,SAAS,SAAS,QAAQ,GAAG;AAAA,IACpD;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,OAAO,OAAO,KAAK,MAAM,IAAI,IAAI;AACvC,WAAO,EAAE,MAAM,SAAS,SAAS,QAAQ;AAAA,EAC3C;AAAA,EAEA,MAAM,YACJ,WACc;AACd,UAAM,UAAe,CAAC;AACtB,QAAI;AAEJ,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,QAAQ,IAAI,MAAM,UAAU,KAAK;AAC/C,cAAQ,KAAK,GAAI,KAAK,SAAS,CAAC,CAAE;AAClC,YAAM,OAAO,QAAQ,IAAI,wBAAwB;AACjD,UAAI,CAAC,KAAM;AACX,cAAQ;AAAA,IACV;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAyC;AAC/C,UAAM,EAAE,UAAU,SAAS,IAAI,KAAK,OAAO;AAC3C,QAAI,CAAC,YAAY,CAAC,SAAU,OAAM,IAAI,WAAW,4DAA4D;AAC7G,UAAM,QAAQ,OAAO,KAAK,GAAG,QAAQ,IAAI,QAAQ,EAAE,EAAE,SAAS,QAAQ;AACtE,WAAO;AAAA,MACL,iBAAiB,SAAS,KAAK;AAAA,MAC/B,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEQ,qBAA6C;AACnD,UAAM,EAAE,MAAM,IAAI,KAAK,OAAO;AAC9B,QAAI,CAAC,MAAO,OAAM,IAAI,WAAW,gEAAgE;AACjG,WAAO;AAAA,MACL,iBAAiB,UAAU,KAAK;AAAA,MAChC,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEQ,iBAAyC;AAC/C,UAAM,EAAE,KAAK,UAAU,SAAS,IAAI,KAAK,OAAO;AAChD,QAAI;AACJ,QAAI,YAAY,UAAU;AACxB,gBAAU,OAAO,KAAK,GAAG,QAAQ,IAAI,QAAQ,EAAE,EAAE,SAAS,QAAQ;AAAA,IACpE,WAAW,YAAY,KAAK;AAC1B,gBAAU,OAAO,KAAK,GAAG,QAAQ,IAAI,GAAG,EAAE,EAAE,SAAS,QAAQ;AAAA,IAC/D,WAAW,KAAK;AACd,gBAAU,OAAO,KAAK,uBAAuB,KAAK,UAAU,EAAE,OAAO,IAAI,CAAC,CAAC,EAAE,EAAE,SAAS,QAAQ;AAAA,IAClG,OAAO;AACL,YAAM,IAAI,WAAW,4DAA4D;AAAA,IACnF;AACA,WAAO;AAAA,MACL,iBAAiB,SAAS,OAAO;AAAA,MACjC,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,QACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,QAAQ;AACpC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,wDAAwD;AAE3F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,eAAe;AACpC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAEA,MAAM,WACJ,MACA,OAA2B,CAAC,GACiC;AAC7D,UAAM,UAAU,KAAK,OAAO,QAAQ;AACpC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,wDAAwD;AAE3F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,eAAe;AAEpC,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,UAAU,KAAK,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KAChG,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,UAAM,WAAW,MAAM,iBAAiB,KAAK;AAAA,MAC3C,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D,GAAG,KAAK,aAAa,GAAK;AAE1B,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,UAAU,QAAQ,SAAS,MAAM,IAAI,SAAS,UAAU;AAC5D,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,MAAM,SAAS,KAAK,CAAC;AAC/C,YAAI,OAAO,QAAS,WAAU,OAAO,OAAO,OAAO;AAAA,MACrD,QAAQ;AAAA,MAAe;AACvB,YAAM,IAAI,WAAW,SAAS,SAAS,QAAQ,GAAG;AAAA,IACpD;AAEA,WAAO,EAAE,QAAQ,SAAS,QAAQ,SAAS,SAAS,SAAS,MAAM,MAAM,SAAS,KAAK,EAAE;AAAA,EAC3F;AAAA,EAEA,MAAM,YACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,YAAY;AACxC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,4DAA4D;AAE/F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,EAAE,GAAG,KAAK,mBAAmB,GAAG,GAAG,KAAK,QAAQ;AAGhE,UAAM,OAAO,KAAK,SAAS,SACtB,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,KAAK,UAAU,KAAK,IAAI,IACrE;AAEJ,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA;AAAA,IACF;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AAC/G,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAGA,MAAM,QACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,QAAQ;AACpC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,wDAAwD;AAE3F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,eAAe;AACpC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAEA,MAAM,gBACJ,MACA,OAA2B,CAAC,GACX;AACjB,UAAM,UAAU,KAAK,OAAO,YAAY;AACxC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,4DAA4D;AAE/F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,EAAE,GAAG,KAAK,mBAAmB,GAAG,QAAQ,cAAc,GAAG,KAAK,QAAQ;AAEtF,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,YAAY,KAAK,UAAU,KAAK,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,CAAI;AAC7H,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,UAAM,WAAW,MAAM,iBAAiB,KAAK;AAAA,MAC3C,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,IACF,GAAG,KAAK,aAAa,GAAK;AAE1B,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,UAAU,QAAQ,SAAS,MAAM,IAAI,SAAS,UAAU;AAC5D,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,MAAM,SAAS,KAAK,CAAC;AAC/C,YAAI,OAAO,QAAS,WAAU,OAAO,OAAO,OAAO;AAAA,MACrD,QAAQ;AAAA,MAAe;AACvB,YAAM,IAAI,WAAW,SAAS,SAAS,QAAQ,GAAG;AAAA,IACpD;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA,EAIQ,eAAuC;AAC7C,UAAM,EAAE,MAAM,IAAI,KAAK,OAAO;AAC9B,QAAI,CAAC,MAAO,OAAM,IAAI,WAAW,8DAA8D;AAC/F,WAAO;AAAA,MACL,iBAAiB,UAAU,KAAK;AAAA,MAChC,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,MACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,MAAM;AAClC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,0DAA0D;AAE7F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,aAAa;AAClC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAEA,MAAM,cACJ,WACc;AACd,UAAM,UAAe,CAAC;AACtB,QAAI,OAAO;AACX,UAAM,WAAW;AAEjB,WAAO,MAAM;AACX,YAAM,WAAW,MAAM,UAAU,MAAM,QAAQ;AAC/C,cAAQ,KAAK,GAAG,SAAS,KAAK;AAC9B,UAAI,QAAQ,UAAU,SAAS,SAAS,SAAS,MAAM,WAAW,EAAG;AACrE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,mBACJ,WACc;AACd,UAAM,UAAe,CAAC;AACtB,QAAI,QAAQ;AACZ,UAAM,QAAQ;AAEd,WAAO,MAAM;AACX,YAAM,OAAO,MAAM,UAAU,OAAO,KAAK;AACzC,cAAQ,KAAK,GAAG,KAAK,OAAO;AAC5B,UAAI,CAAC,KAAK,OAAO,KAAM;AACvB,eAAS,KAAK;AAAA,IAChB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SACJ,WACc;AACd,UAAM,UAAe,CAAC;AACtB,QAAI,QAAQ;AACZ,UAAM,QAAQ;AAEd,WAAO,MAAM;AACX,YAAM,OAAO,MAAM,UAAU,OAAO,KAAK;AACzC,cAAQ,KAAK,GAAG,KAAK,MAAM;AAC3B,UAAI,KAAK,WAAY;AACrB,cAAQ,KAAK,iBAAiB,QAAQ;AAAA,IACxC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aACJ,WACc;AACd,UAAM,UAAe,CAAC;AACtB,QAAI,UAAU;AACd,UAAM,aAAa;AAEnB,WAAO,MAAM;AACX,YAAM,OAAO,MAAM,UAAU,SAAS,UAAU;AAChD,YAAM,QAAS,KAAK,UAAU,KAAK,UAAU,CAAC;AAC9C,cAAQ,KAAK,GAAG,KAAK;AACrB,iBAAW,MAAM;AACjB,UAAI,WAAW,KAAK,SAAS,MAAM,WAAW,EAAG;AAAA,IACnD;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAoC;AAC1C,QAAI,CAAC,KAAK,kBAAkB;AAC1B,WAAK,mBAAmB,sBAAsB,KAAK,MAAM;AAAA,IAC3D;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,oBAA4C;AAClD,UAAM,EAAE,UAAU,UAAU,SAAS,IAAI,KAAK,OAAO;AACrD,QAAI;AACJ,QAAI,YAAY,UAAU;AACxB,gBAAU,OAAO,KAAK,GAAG,QAAQ,IAAI,QAAQ,EAAE,EAAE,SAAS,QAAQ;AAAA,IACpE,WAAW,YAAY,UAAU;AAC/B,gBAAU,OAAO,KAAK,GAAG,QAAQ,IAAI,QAAQ,EAAE,EAAE,SAAS,QAAQ;AAAA,IACpE,OAAO;AACL,YAAM,IAAI,WAAW,+DAA+D;AAAA,IACtF;AACA,WAAO;AAAA,MACL,iBAAiB,SAAS,OAAO;AAAA,MACjC,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,WACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,WAAW;AACvC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,2DAA2D;AAE9F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,kBAAkB;AACvC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAEQ,kBAA0C;AAChD,UAAM,EAAE,QAAQ,YAAY,SAAS,IAAI,KAAK,OAAO;AACrD,QAAI,CAAC,UAAU,CAAC,cAAc,CAAC,UAAU;AACvC,YAAM,IAAI,WAAW,6DAA6D;AAAA,IACpF;AACA,UAAM,gBAAgB,OAAO,KAAK,GAAG,QAAQ,IAAI,UAAU,EAAE,EAAE,SAAS,QAAQ;AAChF,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,SACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,SAAS,WAAW;AAEhD,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,gBAAgB;AACrC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,cAAc,WAAW,aAAa;AACvF,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAEQ,oBAA4C;AAClD,UAAM,EAAE,UAAU,SAAS,IAAI,KAAK,OAAO;AAC3C,QAAI,CAAC,YAAY,CAAC,SAAU,OAAM,IAAI,WAAW,gEAAgE;AACjH,UAAM,UAAU,OAAO,KAAK,GAAG,QAAQ,IAAI,QAAQ,EAAE,EAAE,SAAS,QAAQ;AACxE,WAAO;AAAA,MACL,iBAAiB,SAAS,OAAO;AAAA,MACjC,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,WACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,WAAW;AACvC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,mEAAmE;AAEtG,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAC/C,UAAM,UAAU,KAAK,kBAAkB;AACvC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB;AAAA,MACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,cAAc,EAAE,GAAG,SAAS,eAAe,aAAa;AAC9D,YAAM,MAAM,YAAY,KAAK,MAAM,IAAI,GAAG;AAAA,WAAc,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAAA,KACvF,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,GAAK;AAAA,EACtD;AAAA,EAEA,MAAM,UACJ,MACA,OAA2B,CAAC,GAChB;AACZ,UAAM,UAAU,KAAK,OAAO,UAAU;AACtC,QAAI,CAAC,QAAS,OAAM,IAAI,WAAW,0DAA0D;AAE7F,UAAM,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM;AAE/C,QAAI,KAAK,QAAQ;AACf,YAAM,MAAM,YAAY,KAAK,UAAU,KAAK,IAAI,GAAG;AAAA,KAC9C,KAAK,OAAO,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IAAO;AACnE,MAAAA,IAAG,UAAU,QAAQ,OAAO,IAAI,GAAG;AACnC,cAAQ,WAAW,SAAS;AAC5B,YAAM,IAAI,WAAW,WAAW,CAAC;AAAA,IACnC;AAEA,UAAM,UAAU,KAAK,oBAAoB;AACzC,UAAM,OAAoB;AAAA,MACxB,QAAQ,KAAK,UAAU;AAAA,MACvB,SAAS,EAAE,UAAU,oBAAoB,gBAAgB,oBAAoB,GAAG,KAAK,QAAQ;AAAA,MAC7F,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC9D;AAEA,WAAO,QAAW,KAAK,MAAM,KAAK,aAAa,KAAO,OAAO;AAAA,EAC/D;AACF;AAEO,SAAS,iBAAiB,QAAwB,SAAS,OAAmB;AACnF,SAAO,IAAI,WAAW,QAAQ,MAAM;AACtC;","names":["fs","fs"]}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: address-pr-feedback
|
|
3
|
-
description: Work through all open review comments and SonarQube issues on the current branch's PR. Auto-fixes linting and SonarQube findings; applies AI judgment to reviewer comments. Shows a summary table, then asks user to commit and push before marking threads resolved. Use when asked to address feedback, resolve PR comments, or respond to change requests.
|
|
4
|
-
compatibility: Designed for Claude Code. Requires pncli configured with Bitbucket or Azure DevOps and optionally SonarQube.
|
|
5
|
-
user-invocable: true
|
|
6
|
-
metadata:
|
|
7
|
-
category: pr-workflow
|
|
8
|
-
providers: both
|
|
9
|
-
services: git, bitbucket, ado, sonar
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Step 1 — Detect provider
|
|
13
|
-
|
|
14
|
-
Run `git remote -v`. `/_git/` in the URL → Azure DevOps. `/scm/` → Bitbucket.
|
|
15
|
-
|
|
16
|
-
## Step 2 — RESEARCH: Gather all open feedback (parallel)
|
|
17
|
-
|
|
18
|
-
Launch three tasks simultaneously:
|
|
19
|
-
|
|
20
|
-
**Task A — Open PR comments**
|
|
21
|
-
|
|
22
|
-
Bitbucket: `pncli bitbucket get-pr` to get the PR id, then `pncli bitbucket list-comments --pr <id>` filtered to `resolved: false`.
|
|
23
|
-
ADO: `pncli ado repo list-prs --state active` filtered by current branch to get PR id, then `pncli ado repo list-comments --pr <id>` filtered to threads where `status` is not `fixed`.
|
|
24
|
-
|
|
25
|
-
**Task B — SonarQube issues**
|
|
26
|
-
|
|
27
|
-
Get current branch: `git rev-parse --abbrev-ref HEAD`
|
|
28
|
-
Run `pncli sonar issues --statuses OPEN --branch <branch>`
|
|
29
|
-
Report: rule key, severity, file, line, message for each open issue.
|
|
30
|
-
|
|
31
|
-
**Task C — Source context**
|
|
32
|
-
|
|
33
|
-
For every comment in Task A that references a file path, read that file in full from the working tree.
|
|
34
|
-
|
|
35
|
-
Wait for all three tasks.
|
|
36
|
-
|
|
37
|
-
## Step 3 — PLAN: Classify each item
|
|
38
|
-
|
|
39
|
-
For every comment and SonarQube issue, assign one action:
|
|
40
|
-
|
|
41
|
-
- **AUTO-FIX** — SonarQube issues; comments explicitly about linting, formatting, or code style rules
|
|
42
|
-
- **AGREED-FIX** — Reviewer threads where a reply from the PR author (or submitter) contains an agreement signal: "sounds good", "will fix", "done", "agreed", "fixed", "+1", "yep", "sure"
|
|
43
|
-
- **AI-JUDGMENT** — Everything else. Apply best judgment to determine the correct fix. Do not skip.
|
|
44
|
-
|
|
45
|
-
## Step 4 — IMPLEMENT: Apply all fixes
|
|
46
|
-
|
|
47
|
-
Process AUTO-FIX and AGREED-FIX items first, then AI-JUDGMENT items.
|
|
48
|
-
|
|
49
|
-
For each item: edit the referenced file(s) directly to resolve the finding.
|
|
50
|
-
Track as you go: `(comment id or sonar key) → (action taken) → (file:line changed)`.
|
|
51
|
-
|
|
52
|
-
## Step 5 — Show summary table
|
|
53
|
-
|
|
54
|
-
Print a Markdown table of everything addressed:
|
|
55
|
-
|
|
56
|
-
| Comment / Finding | Author | Action | File Changed |
|
|
57
|
-
|---|---|---|---|
|
|
58
|
-
| ... | ... | ... | ... |
|
|
59
|
-
|
|
60
|
-
## Step 6 — Ask user to commit and push
|
|
61
|
-
|
|
62
|
-
Do NOT auto-commit or auto-push. Print:
|
|
63
|
-
|
|
64
|
-
```
|
|
65
|
-
All fixes applied. Review the changes above, then:
|
|
66
|
-
git add <changed files>
|
|
67
|
-
git commit -m "fix: address PR review feedback"
|
|
68
|
-
git push
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Wait for the user to confirm they have pushed before proceeding to Step 7.
|
|
72
|
-
|
|
73
|
-
## Step 7 — Reply to and resolve each thread
|
|
74
|
-
|
|
75
|
-
After the user confirms the push, for each addressed item:
|
|
76
|
-
|
|
77
|
-
**Bitbucket:**
|
|
78
|
-
```
|
|
79
|
-
pncli bitbucket reply-comment --pr <id> --comment-id <cid> --body "Fixed — <one-line description>"
|
|
80
|
-
pncli bitbucket resolve-comment --pr <id> --comment-id <cid>
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
**ADO:**
|
|
84
|
-
```
|
|
85
|
-
pncli ado repo reply-comment --pr <id> --thread-id <tid> --body "Fixed — <one-line description>"
|
|
86
|
-
pncli ado repo resolve-comment --pr <id> --thread-id <tid>
|
|
87
|
-
```
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: code-review
|
|
3
|
-
description: Review the PR for the current branch. Reads the full diff, existing comments, and referenced source files, then posts categorized inline comments (Blocking / Suggestion / Nit) via pncli. Offers to approve or request changes at the end. Works with Bitbucket and Azure DevOps. Use when asked to review a PR, check the diff, or add code review comments.
|
|
4
|
-
compatibility: Designed for Claude Code. Requires pncli configured with Bitbucket or Azure DevOps.
|
|
5
|
-
user-invocable: true
|
|
6
|
-
metadata:
|
|
7
|
-
category: pr-workflow
|
|
8
|
-
providers: both
|
|
9
|
-
services: git, bitbucket, ado
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Step 1 — Detect provider
|
|
13
|
-
|
|
14
|
-
Run `git remote -v`. `/_git/` → Azure DevOps. `/scm/` → Bitbucket.
|
|
15
|
-
|
|
16
|
-
## Step 2 — Find the PR for the current branch
|
|
17
|
-
|
|
18
|
-
Get current branch: `git rev-parse --abbrev-ref HEAD`
|
|
19
|
-
|
|
20
|
-
**Bitbucket:** `pncli git current-pr` → returns PR id.
|
|
21
|
-
**ADO:** `pncli ado repo list-prs --state active`, filter entries where `sourceRefName` ends with the current branch name.
|
|
22
|
-
|
|
23
|
-
## Step 3 — RESEARCH: Read diff, comments, and source files (parallel)
|
|
24
|
-
|
|
25
|
-
Launch three agents simultaneously:
|
|
26
|
-
|
|
27
|
-
**Agent A — Full diff**
|
|
28
|
-
Bitbucket: `pncli bitbucket diff --pr <id>`
|
|
29
|
-
ADO: `pncli ado repo diff --pr <id>`
|
|
30
|
-
Parse: file paths, change type (add/edit/delete), added and removed line numbers.
|
|
31
|
-
|
|
32
|
-
**Agent B — Existing comments**
|
|
33
|
-
Bitbucket: `pncli bitbucket list-comments --pr <id>`
|
|
34
|
-
ADO: `pncli ado repo list-comments --pr <id>`
|
|
35
|
-
Note which file+line combinations already have comments — do not duplicate them.
|
|
36
|
-
|
|
37
|
-
**Agent C — Source context**
|
|
38
|
-
For each file that appears in the diff: read the full file from the working tree.
|
|
39
|
-
Also read `CLAUDE.md` (or any repo conventions file) if present in the repo root.
|
|
40
|
-
|
|
41
|
-
Wait for all three agents.
|
|
42
|
-
|
|
43
|
-
## Step 4 — PLAN: Classify each finding
|
|
44
|
-
|
|
45
|
-
Analyze the diff against the full source context and existing comments.
|
|
46
|
-
For each issue found, assign a category:
|
|
47
|
-
|
|
48
|
-
- **Blocking** — correctness bug, security vulnerability, broken contract, data loss risk, undefined behavior
|
|
49
|
-
- **Suggestion** — better approach available, missing test coverage, unclear naming, performance concern, missing error handling at a boundary
|
|
50
|
-
- **Nit** — style preference, whitespace, minor naming, cosmetic
|
|
51
|
-
|
|
52
|
-
Skip any finding already covered by an existing comment on the same line.
|
|
53
|
-
|
|
54
|
-
## Step 5 — IMPLEMENT: Post inline comments
|
|
55
|
-
|
|
56
|
-
Post findings in order: Blocking first, then Suggestion, then Nit.
|
|
57
|
-
|
|
58
|
-
**Bitbucket:**
|
|
59
|
-
```
|
|
60
|
-
pncli bitbucket add-inline-comment --pr <id> --file <path> --line <n> \
|
|
61
|
-
--body "[Blocking|Suggestion|Nit] <finding>"
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
**ADO:**
|
|
65
|
-
```
|
|
66
|
-
pncli ado repo add-inline-comment --pr <id> --file <path> --line <n> \
|
|
67
|
-
--line-type right --body "[Blocking|Suggestion|Nit] <finding>"
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
(Use `--line-type left` for lines that were removed.)
|
|
71
|
-
|
|
72
|
-
## Step 6 — Approve or request changes
|
|
73
|
-
|
|
74
|
-
**If any Blocking findings were posted:**
|
|
75
|
-
Bitbucket: `pncli bitbucket needs-work --pr <id>`
|
|
76
|
-
ADO: `pncli ado repo wait-for-author --pr <id>`
|
|
77
|
-
|
|
78
|
-
**If no Blocking findings:** Ask the user: "No blocking issues found. Approve this PR? (y/n)"
|
|
79
|
-
On yes — Bitbucket: `pncli bitbucket approve --pr <id>` / ADO: `pncli ado repo approve --pr <id>`
|
|
80
|
-
On no — leave without approving.
|
|
81
|
-
|
|
82
|
-
Report: N Blocking, N Suggestion, N Nit. Overall decision.
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: local-setup
|
|
3
|
-
description: Use when asked to set up pncli for the first time, configure services, or initialize a repo. Walks through identity, work item tracking, source control, and optional services using non-interactive pncli config commands.
|
|
4
|
-
compatibility: Designed for Claude Code. Requires pncli installed and accessible in PATH.
|
|
5
|
-
user-invocable: true
|
|
6
|
-
metadata:
|
|
7
|
-
category: setup
|
|
8
|
-
providers: both
|
|
9
|
-
services: config
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
Walk the user through a complete pncli setup — global config and repo-level defaults — using non-interactive commands. Ask the user questions and use their answers to run `pncli config set` commands.
|
|
13
|
-
|
|
14
|
-
**Step 1 — Ask about identity.**
|
|
15
|
-
|
|
16
|
-
Ask the user:
|
|
17
|
-
- "What is your email address? (used across Jira, Bitbucket, etc.)"
|
|
18
|
-
- "What is your username or user ID?"
|
|
19
|
-
|
|
20
|
-
Then set the values:
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
pncli config set user.email <their-email>
|
|
24
|
-
pncli config set user.userId <their-username>
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
**Step 2 — Ask about work item tracking.**
|
|
28
|
-
|
|
29
|
-
Ask the user: "Does this organization use **Jira** or **Azure DevOps** for work items and tickets?"
|
|
30
|
-
|
|
31
|
-
If **Jira**:
|
|
32
|
-
- Ask for their Jira base URL (e.g. `https://jira.company.com`)
|
|
33
|
-
- Ask for their Jira personal access token
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
pncli config set jira.baseUrl <url>
|
|
37
|
-
pncli config set jira.apiToken <token>
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
If **Azure DevOps**:
|
|
41
|
-
- Ask for their Azure DevOps Server base URL (e.g. `https://tfs.company.com`)
|
|
42
|
-
- Ask for their ADO personal access token
|
|
43
|
-
- Ask for their default collection name (e.g. `DefaultCollection`)
|
|
44
|
-
- Ask for their default project name
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
pncli config set ado.baseUrl <url>
|
|
48
|
-
pncli config set ado.pat <token>
|
|
49
|
-
pncli config set defaults.ado.collection <collection>
|
|
50
|
-
pncli config set defaults.ado.project <project>
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
**Step 3 — Ask about source control.**
|
|
54
|
-
|
|
55
|
-
Ask the user: "Does this organization use **Bitbucket** or **Azure DevOps** for pull requests and code review?"
|
|
56
|
-
|
|
57
|
-
If **Bitbucket**:
|
|
58
|
-
- Ask for their Bitbucket Server base URL
|
|
59
|
-
- Ask for their Bitbucket personal access token
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
pncli config set bitbucket.baseUrl <url>
|
|
63
|
-
pncli config set bitbucket.pat <token>
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
If **Azure DevOps** and not already configured in step 2, ask for the ADO credentials now.
|
|
67
|
-
|
|
68
|
-
**Step 4 — Ask about optional services.**
|
|
69
|
-
|
|
70
|
-
Ask the user about each of these. Skip any they don't use:
|
|
71
|
-
|
|
72
|
-
**Confluence** — "Do you use Confluence for documentation?"
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
pncli config set confluence.baseUrl <url>
|
|
76
|
-
pncli config set confluence.apiToken <token>
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**SonarQube** — "Do you use SonarQube for code quality and security scanning?"
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
pncli config set sonar.baseUrl <url>
|
|
83
|
-
pncli config set sonar.token <token>
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
**SDElements** — "Do you use SDElements for threat modeling?" If yes, ask for their connection string (format: `token@hostname`):
|
|
87
|
-
|
|
88
|
-
```
|
|
89
|
-
pncli config set sde.connection <token@hostname>
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
**Checkmarx** — "Do you use Checkmarx CxSAST for vulnerability scanning?"
|
|
93
|
-
|
|
94
|
-
```
|
|
95
|
-
pncli config set checkmarx.baseUrl <url>
|
|
96
|
-
pncli config set checkmarx.username <username>
|
|
97
|
-
pncli config set checkmarx.password <password>
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
The base URL is your CxSAST server root, e.g. `https://cx.company.com`. pncli handles the OAuth2 token exchange using your username and password — no other tools required.
|
|
101
|
-
|
|
102
|
-
**IBM UrbanCode Deploy** — "Do you use IBM UrbanCode Deploy for component imports or deployment processes?"
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
pncli config set udeploy.baseUrl <url>
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Ask whether they authenticate with a PAT or username/password:
|
|
109
|
-
|
|
110
|
-
- If **PAT**: `pncli config set udeploy.pat <token>`
|
|
111
|
-
- If **username/password**:
|
|
112
|
-
```
|
|
113
|
-
pncli config set udeploy.username <username>
|
|
114
|
-
pncli config set udeploy.password <password>
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
Optionally set defaults to avoid repeating flags on every command:
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
pncli config set defaults.udeploy.application <app-name>
|
|
121
|
-
pncli config set defaults.udeploy.environment <env-name>
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
**Jenkins** — "Do you use Jenkins for CI/CD pipelines?"
|
|
125
|
-
|
|
126
|
-
```
|
|
127
|
-
pncli config set jenkins.baseUrl <url>
|
|
128
|
-
pncli config set jenkins.username <username>
|
|
129
|
-
pncli config set jenkins.apiToken <token>
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
The base URL is your Jenkins root, e.g. `https://jenkins.company.com`. pncli authenticates using HTTP Basic (username + API token).
|
|
133
|
-
|
|
134
|
-
**Artifactory** — "Do you use Artifactory for package management?"
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
pncli config set artifactory.baseUrl <url>
|
|
138
|
-
pncli config set artifactory.token <token>
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Then ask which package ecosystems they proxy through Artifactory (npm, NuGet, Maven). Set whichever apply:
|
|
142
|
-
|
|
143
|
-
```
|
|
144
|
-
pncli config set artifactory.npmRepo <virtual-repo-name>
|
|
145
|
-
pncli config set artifactory.nugetRepo <virtual-repo-name>
|
|
146
|
-
pncli config set artifactory.mavenRepo <virtual-repo-name>
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
**Jenkins** — "Do you use Jenkins for CI/CD pipelines?"
|
|
150
|
-
|
|
151
|
-
```
|
|
152
|
-
pncli config set jenkins.baseUrl <url>
|
|
153
|
-
pncli config set jenkins.username <username>
|
|
154
|
-
pncli config set jenkins.apiToken <token>
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
**ServiceNow** — "Do you use ServiceNow for change management?"
|
|
158
|
-
|
|
159
|
-
```
|
|
160
|
-
pncli config set servicenow.baseUrl <url>
|
|
161
|
-
pncli config set servicenow.username <username>
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Ask whether they authenticate with a password or API token:
|
|
165
|
-
|
|
166
|
-
- If **password**: `pncli config set servicenow.password <password>`
|
|
167
|
-
- If **API token**: `pncli config set servicenow.apiToken <token>`
|
|
168
|
-
|
|
169
|
-
The base URL is your ServiceNow instance root, e.g. `https://mycompany.service-now.com`.
|
|
170
|
-
|
|
171
|
-
**Contrast IAST** — "Do you use Contrast Security for interactive application security testing?"
|
|
172
|
-
|
|
173
|
-
```
|
|
174
|
-
pncli config set contrast.orgUuid <org-uuid>
|
|
175
|
-
pncli config set contrast.username <username>
|
|
176
|
-
pncli config set contrast.apiKey <api-key>
|
|
177
|
-
pncli config set contrast.serviceKey <service-key>
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
Optionally set the base URL if using an on-premise instance (defaults to `https://app.contrastsecurity.com`):
|
|
181
|
-
|
|
182
|
-
```
|
|
183
|
-
pncli config set contrast.baseUrl <url>
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
All four credentials (org UUID, username, API key, service key) are found in your Contrast account under **User Settings → Your Keys**.
|
|
187
|
-
|
|
188
|
-
**Sonatype IQ Server** — "Do you use Sonatype IQ Server for dependency security policy enforcement?"
|
|
189
|
-
|
|
190
|
-
```
|
|
191
|
-
pncli config set sonatypeiq.baseUrl <url>
|
|
192
|
-
pncli config set sonatypeiq.userCode <user-code>
|
|
193
|
-
pncli config set sonatypeiq.passcode <passcode>
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
The `userCode` and `passcode` are User Token credentials generated in your IQ Server profile under **User Menu → User Token**. The base URL is your IQ Server instance root, e.g. `https://iq.your-company.com`.
|
|
197
|
-
|
|
198
|
-
Once configured, use `pncli sonatypeiq applications list` to discover application IDs, then run `pncli deps frisk --source sonatypeiq --application-id <id>` to scan dependencies against your IQ Server policies.
|
|
199
|
-
|
|
200
|
-
**Step 5 — Set repo-level defaults.**
|
|
201
|
-
|
|
202
|
-
Ask the user for project-specific defaults:
|
|
203
|
-
- "What is the default Jira project key for this repo?" (e.g. `ACME`)
|
|
204
|
-
- "What is the default target branch for PRs?" (e.g. `main`)
|
|
205
|
-
- If SonarQube is configured: "What is the SonarQube project key?"
|
|
206
|
-
- If SDElements is configured: "What is the SDElements project ID?"
|
|
207
|
-
|
|
208
|
-
```
|
|
209
|
-
pncli config set --repo defaults.jira.project <key>
|
|
210
|
-
pncli config set --repo defaults.bitbucket.targetBranch <branch>
|
|
211
|
-
pncli config set --repo defaults.sonar.project <key>
|
|
212
|
-
pncli config set --repo defaults.sde.project <id>
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
The `--repo` flag writes to `.pncli.json` in the repo root, keeping project-specific defaults scoped to the repo and shareable via version control.
|
|
216
|
-
|
|
217
|
-
**Step 6 — Test connectivity.**
|
|
218
|
-
|
|
219
|
-
```
|
|
220
|
-
pncli config test
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Review the results. If any service shows `ok: false`, help the user troubleshoot the URL or credentials.
|
|
224
|
-
|
|
225
|
-
Run `pncli config show` to confirm the final configuration.
|