UNPKG

@credo-ts/core

Version:

<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1

1 lines • 24.8 kB
{"version":3,"file":"W3cV2CredentialService.mjs","names":[],"sources":["../../../src/modules/vc/W3cV2CredentialService.ts"],"sourcesContent":["import type { AgentContext } from '../../agent/context'\nimport { CredoError } from '../../error'\nimport { injectable } from '../../plugins'\nimport type { Query, QueryOptions } from '../../storage/StorageService'\nimport { asArray } from '../../utils/array'\nimport {\n W3cV2DataIntegrityCredentialService,\n type W3cV2DataIntegrityResolvedPresentation,\n W3cV2DataIntegrityVerifiableCredential,\n W3cV2DataIntegrityVerifiablePresentation,\n} from './data-integrity'\nimport { getSignerForDataIntegrityProof } from './data-integrity/v2-di-utils'\nimport { W3cV2JwtVerifiableCredential, W3cV2JwtVerifiablePresentation } from './jwt-vc'\nimport { W3cV2JwtCredentialService } from './jwt-vc/W3cV2JwtCredentialService'\nimport type {\n W3cV2PresentationCredentialEntry,\n W3cV2PresentationCredentialEntryResult,\n W3cV2VerifiableCredential,\n W3cV2VerifiablePresentation,\n W3cV2VerifyCredentialResult,\n W3cV2VerifyPresentationResult,\n} from './models'\nimport {\n ClaimFormat,\n decodeW3cV2VerifiablePresentation,\n W3cV2EnvelopedVerifiableCredential,\n W3cV2EnvelopedVerifiablePresentation,\n} from './models'\nimport { decodeW3cV2VerifiableCredential } from './models/credential/W3cV2VerifiableCredential'\nimport type { W3cV2Presentation } from './models/presentation/W3cV2Presentation'\nimport { W3cV2CredentialRecord, W3cV2CredentialRepository } from './repository'\nimport {\n W3cV2SdJwtCredentialService,\n W3cV2SdJwtVerifiableCredential,\n W3cV2SdJwtVerifiablePresentation,\n} from './sd-jwt-vc'\nimport { getVerificationMethodForJwt } from './v2-jwt-utils'\nimport type {\n W3cV2DiSignCredentialOptions,\n W3cV2DiSignPresentationOptions,\n W3cV2DiVerifyCredentialOptions,\n W3cV2DiVerifyPresentationOptions,\n W3cV2JwtVerifyCredentialOptions,\n W3cV2JwtVerifyPresentationOptions,\n W3cV2SdJwtVerifyCredentialOptions,\n W3cV2SdJwtVerifyPresentationOptions,\n W3cV2SignCredentialOptions,\n W3cV2SignPresentationOptions,\n W3cV2StoreCredentialOptions,\n W3cV2VerifyCredentialOptions,\n W3cV2VerifyPresentationOptions,\n} from './W3cV2CredentialServiceOptions'\n\n@injectable()\nexport class W3cV2CredentialService {\n private w3cV2CredentialRepository: W3cV2CredentialRepository\n private w3cV2SdJwtCredentialService: W3cV2SdJwtCredentialService\n private w3cV2JwtCredentialService: W3cV2JwtCredentialService\n private w3cV2DataIntegrityCredentialService: W3cV2DataIntegrityCredentialService\n\n public constructor(\n w3cV2CredentialRepository: W3cV2CredentialRepository,\n w3cV2SdJwtCredentialService: W3cV2SdJwtCredentialService,\n w3cV2JwtCredentialService: W3cV2JwtCredentialService,\n w3cV2DataIntegrityCredentialService: W3cV2DataIntegrityCredentialService\n ) {\n this.w3cV2CredentialRepository = w3cV2CredentialRepository\n this.w3cV2SdJwtCredentialService = w3cV2SdJwtCredentialService\n this.w3cV2JwtCredentialService = w3cV2JwtCredentialService\n this.w3cV2DataIntegrityCredentialService = w3cV2DataIntegrityCredentialService\n }\n\n /**\n * Signs a credential\n *\n * @param credential the credential to be signed\n * @returns the signed credential\n */\n public async signCredential<Format extends ClaimFormat.JwtW3cVc | ClaimFormat.SdJwtW3cVc | ClaimFormat.DiVc>(\n agentContext: AgentContext,\n options: W3cV2SignCredentialOptions<Format>\n ): Promise<W3cV2VerifiableCredential<Format>> {\n if (options.format === ClaimFormat.JwtW3cVc) {\n const signed = await this.w3cV2JwtCredentialService.signCredential(agentContext, options)\n return signed as W3cV2VerifiableCredential<Format>\n }\n if (options.format === ClaimFormat.SdJwtW3cVc) {\n const signed = await this.w3cV2SdJwtCredentialService.signCredential(agentContext, options)\n return signed as W3cV2VerifiableCredential<Format>\n }\n if (options.format === ClaimFormat.DiVc) {\n const signed = await this.w3cV2DataIntegrityCredentialService.signCredential(\n agentContext,\n options as W3cV2DiSignCredentialOptions\n )\n return signed as W3cV2VerifiableCredential<Format>\n }\n throw new CredoError(`Unsupported format in options. Format must be either 'vc+jwt', 'vc+sd-jwt', or 'di_vc'`)\n }\n\n /**\n * Verifies the signature(s) of a credential\n */\n public async verifyCredential(\n agentContext: AgentContext,\n options: W3cV2VerifyCredentialOptions\n ): Promise<W3cV2VerifyCredentialResult> {\n const credential =\n typeof options.credential === 'string' ? decodeW3cV2VerifiableCredential(options.credential) : options.credential\n\n if (credential instanceof W3cV2JwtVerifiableCredential) {\n return this.w3cV2JwtCredentialService.verifyCredential(agentContext, {\n ...options,\n credential,\n } as W3cV2JwtVerifyCredentialOptions)\n }\n\n if (credential instanceof W3cV2SdJwtVerifiableCredential) {\n return this.w3cV2SdJwtCredentialService.verifyCredential(agentContext, {\n ...options,\n credential,\n } as W3cV2SdJwtVerifyCredentialOptions)\n }\n\n if (credential instanceof W3cV2DataIntegrityVerifiableCredential) {\n return this.w3cV2DataIntegrityCredentialService.verifyCredential(agentContext, {\n ...options,\n credential,\n } as W3cV2DiVerifyCredentialOptions)\n }\n\n throw new CredoError(\n 'Unsupported credential type in options. Credential must be either a W3cV2JwtVerifiableCredential, a W3cV2SdJwtVerifiableCredential, or a W3cV2DataIntegrityVerifiableCredential'\n )\n }\n\n /**\n * Signs a presentation including the credentials it includes\n *\n * @param presentation the presentation to be signed\n * @returns the signed presentation\n */\n public async signPresentation<Format extends ClaimFormat.JwtW3cVp | ClaimFormat.SdJwtW3cVp | ClaimFormat.DiVp>(\n agentContext: AgentContext,\n options: W3cV2SignPresentationOptions<Format>\n ): Promise<W3cV2VerifiablePresentation<Format>> {\n if (options.format === ClaimFormat.JwtW3cVp) {\n const signed = await this.w3cV2JwtCredentialService.signPresentation(agentContext, options)\n return signed as W3cV2VerifiablePresentation<Format>\n }\n if (options.format === ClaimFormat.SdJwtW3cVp) {\n const signed = await this.w3cV2SdJwtCredentialService.signPresentation(agentContext, options)\n return signed as W3cV2VerifiablePresentation<Format>\n }\n if (options.format === ClaimFormat.DiVp) {\n const signed = await this.w3cV2DataIntegrityCredentialService.signPresentation(\n agentContext,\n options as W3cV2DiSignPresentationOptions\n )\n return signed as W3cV2VerifiablePresentation<Format>\n }\n throw new CredoError(`Unsupported format in options. Format must be either 'vp+jwt', 'vp+sd-jwt', or 'di_vp'`)\n }\n\n /**\n * Verifies a W3C V2 verifiable presentation and each enclosed credential entry.\n *\n * Flow:\n * 1. Verifies the outer VP using the format-specific service (`vp+jwt` or `vp+sd-jwt`).\n * 2. Derives the presenter identifier (holder id, or JWT verification method controller fallback).\n * 3. Recursively walks enclosed entries and verifies each credential entry with the matching\n * credential verifier (`vc+jwt` or `vc+sd-jwt`) based on the actual enclosed format.\n * 4. Adds `credentialSubjectAuthentication` validation to each credential result by checking\n * whether the authenticated presenter matches at least one credentialSubject id.\n *\n * Current support and constraints:\n * - Compact string presentations are accepted for `vp+jwt` and `vp+sd-jwt` and normalized\n * to typed presentation instances before routing.\n * - `di_vp` routes through the DI credential service for outer-VP verification.\n * - `di_vc` entries route through the DI credential service for entry verification.\n * - Nested VP entries are treated as invalid. VC 2.0 verifiable presentations support VC entries,\n * not VP-within-VP entries.\n *\n * Return semantics:\n * - `presentation` contains the outer VP verification result.\n * - `credentialEntries` contains one result per traversed credential entry, including unsupported\n * entries as invalid results.\n * - Top-level `isValid` is true only if the outer VP and all credential entry validations are valid.\n *\n * @param agentContext The framework agent context used for resolution and cryptographic checks.\n * @param options Verification input containing the presentation to verify.\n * @returns Aggregated presentation and credential-entry verification result.\n */\n public async verifyPresentation(\n agentContext: AgentContext,\n options: W3cV2VerifyPresentationOptions\n ): Promise<W3cV2VerifyPresentationResult> {\n const presentation =\n typeof options.presentation === 'string'\n ? decodeW3cV2VerifiablePresentation(options.presentation)\n : options.presentation\n\n const validationResults: W3cV2VerifyPresentationResult = {\n isValid: false,\n presentation: {\n isValid: false,\n validations: {},\n },\n credentialEntries: [],\n }\n\n let entries: W3cV2PresentationCredentialEntry[] = []\n let signerId: string | undefined\n\n // Phase 1: verify the outer secured VP envelope and derive the authenticated presenter.\n if (presentation instanceof W3cV2JwtVerifiablePresentation) {\n const presentationResult = await this.w3cV2JwtCredentialService.verifyPresentation(agentContext, {\n ...options,\n presentation,\n } as W3cV2JwtVerifyPresentationOptions)\n validationResults.presentation = presentationResult.presentation\n\n if (!presentationResult.presentation.isValid) {\n validationResults.isValid = false\n return validationResults\n }\n\n const holderId = presentation.resolvedPresentation.holderId\n if (holderId) {\n signerId = holderId\n } else {\n try {\n const verificationMethod = await getVerificationMethodForJwt(agentContext, presentation, ['authentication'])\n signerId = verificationMethod.controller\n } catch (error) {\n validationResults.isValid = false\n validationResults.error = error\n return validationResults\n }\n }\n entries = this.extractCredentialEntriesFromPresentation(presentation)\n } else if (presentation instanceof W3cV2SdJwtVerifiablePresentation) {\n const presentationResult = await this.w3cV2SdJwtCredentialService.verifyPresentation(agentContext, {\n ...options,\n presentation,\n } as W3cV2SdJwtVerifyPresentationOptions)\n validationResults.presentation = presentationResult.presentation\n\n if (!presentationResult.presentation.isValid) {\n validationResults.isValid = false\n return validationResults\n }\n\n const holderId = presentation.resolvedPresentation.holderId\n if (holderId) {\n signerId = holderId\n } else {\n try {\n const verificationMethod = await getVerificationMethodForJwt(agentContext, presentation, ['authentication'])\n signerId = verificationMethod.controller\n } catch (error) {\n validationResults.isValid = false\n validationResults.error = error\n return validationResults\n }\n }\n entries = this.extractCredentialEntriesFromPresentation(presentation)\n } else if (presentation instanceof W3cV2DataIntegrityVerifiablePresentation) {\n const presentationResult = await this.w3cV2DataIntegrityCredentialService.verifyPresentation(agentContext, {\n ...options,\n presentation,\n } as W3cV2DiVerifyPresentationOptions)\n validationResults.presentation = presentationResult.presentation\n\n if (!presentationResult.presentation.isValid) {\n validationResults.isValid = false\n return validationResults\n }\n\n signerId = presentation.resolvedPresentation.holderId\n if (!signerId) {\n try {\n // The holder is optional in VCDM 2.0, so fall back to the identity that authenticated the\n // presentation, mirroring how the JWT and SD-JWT branches above derive their signer.\n // No expected controller is passed: with no declared holder there is nothing to\n // disambiguate against, so an ambiguous proof set is rejected rather than guessed at.\n signerId = await getSignerForDataIntegrityProof(\n agentContext,\n presentation.securedPresentation,\n 'authentication'\n )\n } catch (error) {\n validationResults.isValid = false\n validationResults.error = error\n return validationResults\n }\n }\n\n entries = this.extractCredentialEntriesFromPresentation(presentation)\n } else {\n throw new CredoError(\n 'Unsupported credential type in options. Presentation must be either a W3cV2JwtVerifiablePresentation, a W3cV2SdJwtVerifiablePresentation, or a W3cV2DataIntegrityVerifiablePresentation'\n )\n }\n\n // Phase 2: walk enclosed credential entries and verify recursively by entry format.\n validationResults.credentialEntries = (\n await Promise.all(entries.map((entry) => this.verifyPresentationEntry(agentContext, entry, signerId)))\n ).flat()\n\n validationResults.isValid =\n validationResults.presentation.isValid && validationResults.credentialEntries.every((entry) => entry.isValid)\n\n return validationResults\n }\n\n private async verifyPresentationEntry(\n agentContext: AgentContext,\n entry: W3cV2PresentationCredentialEntry,\n signerId: string\n ): Promise<W3cV2PresentationCredentialEntryResult[]> {\n if (entry instanceof W3cV2DataIntegrityVerifiablePresentation) {\n return [\n this.createInvalidCredentialEntryResult(\n new CredoError('Nested verifiable presentation entries are not supported in VC 2.0 presentations.')\n ),\n ]\n }\n\n if (entry instanceof W3cV2DataIntegrityVerifiableCredential) {\n const credentialResult = await this.w3cV2DataIntegrityCredentialService.verifyCredential(agentContext, {\n credential: entry,\n } as W3cV2DiVerifyCredentialOptions)\n\n return [\n this.mergeCredentialSubjectAuthenticationValidation(\n credentialResult,\n signerId,\n entry.resolvedCredential?.credentialSubjectIds ?? []\n ),\n ]\n }\n\n if (entry instanceof W3cV2EnvelopedVerifiablePresentation) {\n return [\n this.createInvalidCredentialEntryResult(\n new CredoError('Nested verifiable presentation entries are not supported in VC 2.0 presentations.')\n ),\n ]\n }\n\n if (!(entry instanceof W3cV2EnvelopedVerifiableCredential)) {\n return [\n this.createInvalidCredentialEntryResult(new CredoError('Unsupported credential entry type in presentation.')),\n ]\n }\n\n const enclosed = entry.envelopedCredential\n let credentialResult: W3cV2VerifyCredentialResult\n\n if (enclosed instanceof W3cV2JwtVerifiableCredential) {\n credentialResult = await this.w3cV2JwtCredentialService.verifyCredential(agentContext, {\n credential: enclosed,\n } as W3cV2JwtVerifyCredentialOptions)\n } else if (enclosed instanceof W3cV2SdJwtVerifiableCredential) {\n credentialResult = await this.w3cV2SdJwtCredentialService.verifyCredential(agentContext, {\n credential: enclosed,\n } as W3cV2SdJwtVerifyCredentialOptions)\n } else {\n return [\n this.createInvalidCredentialEntryResult(\n new CredoError(\n `Credential entry uses '${this.getClaimFormat(enclosed) ?? 'an unsupported enclosed credential format'}'.`\n )\n ),\n ]\n }\n\n return [\n this.mergeCredentialSubjectAuthenticationValidation(\n credentialResult,\n signerId,\n entry.resolvedCredential.credentialSubjectIds\n ),\n ]\n }\n\n private extractCredentialEntriesFromPresentation(\n presentation:\n | W3cV2JwtVerifiablePresentation\n | W3cV2SdJwtVerifiablePresentation\n | W3cV2DataIntegrityVerifiablePresentation\n ): W3cV2PresentationCredentialEntry[] {\n return this.extractCredentialEntriesFromResolvedPresentation(presentation.resolvedPresentation)\n }\n\n private extractCredentialEntriesFromResolvedPresentation(\n resolvedPresentation: Pick<W3cV2Presentation, 'verifiableCredential'> | W3cV2DataIntegrityResolvedPresentation\n ): W3cV2PresentationCredentialEntry[] {\n return asArray(resolvedPresentation.verifiableCredential) as W3cV2PresentationCredentialEntry[]\n }\n\n private createInvalidCredentialEntryResult(error: Error): W3cV2PresentationCredentialEntryResult {\n return {\n isValid: false,\n error,\n validations: {},\n }\n }\n\n private getClaimFormat(value: unknown): string | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined\n\n const candidate = value as { claimFormat?: unknown }\n return typeof candidate.claimFormat === 'string' ? candidate.claimFormat : undefined\n }\n\n private mergeCredentialSubjectAuthenticationValidation(\n credentialResult: W3cV2VerifyCredentialResult,\n signerId: string,\n credentialSubjectIds: string[]\n ) {\n const presentationAuthenticatesCredentialSubject = credentialSubjectIds.some((subjectId) => signerId === subjectId)\n\n const credentialSubjectAuthentication =\n credentialSubjectIds.length > 0 && !presentationAuthenticatesCredentialSubject\n ? {\n isValid: false,\n error: new CredoError(\n 'Credential has one or more credentialSubject ids, but presentation does not authenticate credential subject'\n ),\n }\n : {\n isValid: true,\n }\n\n return {\n ...credentialResult,\n isValid: credentialResult.isValid && credentialSubjectAuthentication.isValid,\n validations: {\n ...credentialResult.validations,\n credentialSubjectAuthentication,\n },\n }\n }\n\n /**\n * Writes a credential to storage\n *\n * @param record the credential to be stored\n * @returns the credential record that was written to storage\n */\n public async storeCredential(\n agentContext: AgentContext,\n options: W3cV2StoreCredentialOptions\n ): Promise<W3cV2CredentialRecord> {\n // Store the w3cV2 credential record\n await this.w3cV2CredentialRepository.save(agentContext, options.record)\n\n return options.record\n }\n\n public async removeCredentialRecord(agentContext: AgentContext, id: string) {\n await this.w3cV2CredentialRepository.deleteById(agentContext, id)\n }\n\n public async getAllCredentialRecords(agentContext: AgentContext): Promise<W3cV2CredentialRecord[]> {\n return await this.w3cV2CredentialRepository.getAll(agentContext)\n }\n\n public async getCredentialRecordById(agentContext: AgentContext, id: string): Promise<W3cV2CredentialRecord> {\n return await this.w3cV2CredentialRepository.getById(agentContext, id)\n }\n\n public async findCredentialsByQuery(\n agentContext: AgentContext,\n query: Query<W3cV2CredentialRecord>,\n queryOptions?: QueryOptions\n ): Promise<W3cV2VerifiableCredential[]> {\n const result = await this.w3cV2CredentialRepository.findByQuery(agentContext, query, queryOptions)\n return result.map((record) => record.firstCredential)\n }\n\n public async findCredentialRecordByQuery(\n agentContext: AgentContext,\n query: Query<W3cV2CredentialRecord>\n ): Promise<W3cV2VerifiableCredential | undefined> {\n const result = await this.w3cV2CredentialRepository.findSingleByQuery(agentContext, query)\n return result?.firstCredential\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDO,IAAM,yBAAN,MAAM,uBAAuB;CAMlC,YACE,2BACA,6BACA,2BACA,qCACA;EACA,KAAK,4BAA4B;EACjC,KAAK,8BAA8B;EACnC,KAAK,4BAA4B;EACjC,KAAK,sCAAsC;CAC7C;;;;;;;CAQA,MAAa,eACX,cACA,SAC4C;EAC5C,IAAI,QAAQ,WAAA,UAEV,OAAO,MADc,KAAK,0BAA0B,eAAe,cAAc,OAAO;EAG1F,IAAI,QAAQ,WAAA,aAEV,OAAO,MADc,KAAK,4BAA4B,eAAe,cAAc,OAAO;EAG5F,IAAI,QAAQ,WAAA,SAKV,OAAO,MAJc,KAAK,oCAAoC,eAC5D,cACA,OACF;EAGF,MAAM,IAAI,WAAW,wFAAwF;CAC/G;;;;CAKA,MAAa,iBACX,cACA,SACsC;EACtC,MAAM,aACJ,OAAO,QAAQ,eAAe,WAAW,gCAAgC,QAAQ,UAAU,IAAI,QAAQ;EAEzG,IAAI,sBAAsB,8BACxB,OAAO,KAAK,0BAA0B,iBAAiB,cAAc;GACnE,GAAG;GACH;EACF,CAAoC;EAGtC,IAAI,sBAAsB,gCACxB,OAAO,KAAK,4BAA4B,iBAAiB,cAAc;GACrE,GAAG;GACH;EACF,CAAsC;EAGxC,IAAI,sBAAsB,wCACxB,OAAO,KAAK,oCAAoC,iBAAiB,cAAc;GAC7E,GAAG;GACH;EACF,CAAmC;EAGrC,MAAM,IAAI,WACR,iLACF;CACF;;;;;;;CAQA,MAAa,iBACX,cACA,SAC8C;EAC9C,IAAI,QAAQ,WAAA,UAEV,OAAO,MADc,KAAK,0BAA0B,iBAAiB,cAAc,OAAO;EAG5F,IAAI,QAAQ,WAAA,aAEV,OAAO,MADc,KAAK,4BAA4B,iBAAiB,cAAc,OAAO;EAG9F,IAAI,QAAQ,WAAA,SAKV,OAAO,MAJc,KAAK,oCAAoC,iBAC5D,cACA,OACF;EAGF,MAAM,IAAI,WAAW,wFAAwF;CAC/G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BA,MAAa,mBACX,cACA,SACwC;EACxC,MAAM,eACJ,OAAO,QAAQ,iBAAiB,WAC5B,kCAAkC,QAAQ,YAAY,IACtD,QAAQ;EAEd,MAAM,oBAAmD;GACvD,SAAS;GACT,cAAc;IACZ,SAAS;IACT,aAAa,CAAC;GAChB;GACA,mBAAmB,CAAC;EACtB;EAEA,IAAI,UAA8C,CAAC;EACnD,IAAI;EAGJ,IAAI,wBAAwB,gCAAgC;GAC1D,MAAM,qBAAqB,MAAM,KAAK,0BAA0B,mBAAmB,cAAc;IAC/F,GAAG;IACH;GACF,CAAsC;GACtC,kBAAkB,eAAe,mBAAmB;GAEpD,IAAI,CAAC,mBAAmB,aAAa,SAAS;IAC5C,kBAAkB,UAAU;IAC5B,OAAO;GACT;GAEA,MAAM,WAAW,aAAa,qBAAqB;GACnD,IAAI,UACF,WAAW;QAEX,IAAI;IAEF,YAAW,MADsB,4BAA4B,cAAc,cAAc,CAAC,gBAAgB,CAAC,EAAA,CAC7E;GAChC,SAAS,OAAO;IACd,kBAAkB,UAAU;IAC5B,kBAAkB,QAAQ;IAC1B,OAAO;GACT;GAEF,UAAU,KAAK,yCAAyC,YAAY;EACtE,OAAO,IAAI,wBAAwB,kCAAkC;GACnE,MAAM,qBAAqB,MAAM,KAAK,4BAA4B,mBAAmB,cAAc;IACjG,GAAG;IACH;GACF,CAAwC;GACxC,kBAAkB,eAAe,mBAAmB;GAEpD,IAAI,CAAC,mBAAmB,aAAa,SAAS;IAC5C,kBAAkB,UAAU;IAC5B,OAAO;GACT;GAEA,MAAM,WAAW,aAAa,qBAAqB;GACnD,IAAI,UACF,WAAW;QAEX,IAAI;IAEF,YAAW,MADsB,4BAA4B,cAAc,cAAc,CAAC,gBAAgB,CAAC,EAAA,CAC7E;GAChC,SAAS,OAAO;IACd,kBAAkB,UAAU;IAC5B,kBAAkB,QAAQ;IAC1B,OAAO;GACT;GAEF,UAAU,KAAK,yCAAyC,YAAY;EACtE,OAAO,IAAI,wBAAwB,0CAA0C;GAC3E,MAAM,qBAAqB,MAAM,KAAK,oCAAoC,mBAAmB,cAAc;IACzG,GAAG;IACH;GACF,CAAqC;GACrC,kBAAkB,eAAe,mBAAmB;GAEpD,IAAI,CAAC,mBAAmB,aAAa,SAAS;IAC5C,kBAAkB,UAAU;IAC5B,OAAO;GACT;GAEA,WAAW,aAAa,qBAAqB;GAC7C,IAAI,CAAC,UACH,IAAI;IAKF,WAAW,MAAM,+BACf,cACA,aAAa,qBACb,gBACF;GACF,SAAS,OAAO;IACd,kBAAkB,UAAU;IAC5B,kBAAkB,QAAQ;IAC1B,OAAO;GACT;GAGF,UAAU,KAAK,yCAAyC,YAAY;EACtE,OACE,MAAM,IAAI,WACR,yLACF;EAIF,kBAAkB,qBAChB,MAAM,QAAQ,IAAI,QAAQ,KAAK,UAAU,KAAK,wBAAwB,cAAc,OAAO,QAAQ,CAAC,CAAC,EAAA,CACrG,KAAK;EAEP,kBAAkB,UAChB,kBAAkB,aAAa,WAAW,kBAAkB,kBAAkB,OAAO,UAAU,MAAM,OAAO;EAE9G,OAAO;CACT;CAEA,MAAc,wBACZ,cACA,OACA,UACmD;EACnD,IAAI,iBAAiB,0CACnB,OAAO,CACL,KAAK,mCACH,IAAI,WAAW,mFAAmF,CACpG,CACF;EAGF,IAAI,iBAAiB,wCAAwC;GAC3D,MAAM,mBAAmB,MAAM,KAAK,oCAAoC,iBAAiB,cAAc,EACrG,YAAY,MACd,CAAmC;GAEnC,OAAO,CACL,KAAK,+CACH,kBACA,UACA,MAAM,oBAAoB,wBAAwB,CAAC,CACrD,CACF;EACF;EAEA,IAAI,iBAAiB,sCACnB,OAAO,CACL,KAAK,mCACH,IAAI,WAAW,mFAAmF,CACpG,CACF;EAGF,IAAI,EAAE,iBAAiB,qCACrB,OAAO,CACL,KAAK,mCAAmC,IAAI,WAAW,oDAAoD,CAAC,CAC9G;EAGF,MAAM,WAAW,MAAM;EACvB,IAAI;EAEJ,IAAI,oBAAoB,8BACtB,mBAAmB,MAAM,KAAK,0BAA0B,iBAAiB,cAAc,EACrF,YAAY,SACd,CAAoC;OAC/B,IAAI,oBAAoB,gCAC7B,mBAAmB,MAAM,KAAK,4BAA4B,iBAAiB,cAAc,EACvF,YAAY,SACd,CAAsC;OAEtC,OAAO,CACL,KAAK,mCACH,IAAI,WACF,0BAA0B,KAAK,eAAe,QAAQ,KAAK,4CAA4C,GACzG,CACF,CACF;EAGF,OAAO,CACL,KAAK,+CACH,kBACA,UACA,MAAM,mBAAmB,oBAC3B,CACF;CACF;CAEA,yCACE,cAIoC;EACpC,OAAO,KAAK,iDAAiD,aAAa,oBAAoB;CAChG;CAEA,iDACE,sBACoC;EACpC,OAAO,QAAQ,qBAAqB,oBAAoB;CAC1D;CAEA,mCAA2C,OAAsD;EAC/F,OAAO;GACL,SAAS;GACT;GACA,aAAa,CAAC;EAChB;CACF;CAEA,eAAuB,OAAoC;EACzD,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAA;EAExE,MAAM,YAAY;EAClB,OAAO,OAAO,UAAU,gBAAgB,WAAW,UAAU,cAAc,KAAA;CAC7E;CAEA,+CACE,kBACA,UACA,sBACA;EACA,MAAM,6CAA6C,qBAAqB,MAAM,cAAc,aAAa,SAAS;EAElH,MAAM,kCACJ,qBAAqB,SAAS,KAAK,CAAC,6CAChC;GACE,SAAS;GACT,OAAO,IAAI,WACT,6GACF;EACF,IACA,EACE,SAAS,KACX;EAEN,OAAO;GACL,GAAG;GACH,SAAS,iBAAiB,WAAW,gCAAgC;GACrE,aAAa;IACX,GAAG,iBAAiB;IACpB;GACF;EACF;CACF;;;;;;;CAQA,MAAa,gBACX,cACA,SACgC;EAEhC,MAAM,KAAK,0BAA0B,KAAK,cAAc,QAAQ,MAAM;EAEtE,OAAO,QAAQ;CACjB;CAEA,MAAa,uBAAuB,cAA4B,IAAY;EAC1E,MAAM,KAAK,0BAA0B,WAAW,cAAc,EAAE;CAClE;CAEA,MAAa,wBAAwB,cAA8D;EACjG,OAAO,MAAM,KAAK,0BAA0B,OAAO,YAAY;CACjE;CAEA,MAAa,wBAAwB,cAA4B,IAA4C;EAC3G,OAAO,MAAM,KAAK,0BAA0B,QAAQ,cAAc,EAAE;CACtE;CAEA,MAAa,uBACX,cACA,OACA,cACsC;EAEtC,QAAO,MADc,KAAK,0BAA0B,YAAY,cAAc,OAAO,YAAY,EAAA,CACnF,KAAK,WAAW,OAAO,eAAe;CACtD;CAEA,MAAa,4BACX,cACA,OACgD;EAEhD,QAAO,MADc,KAAK,0BAA0B,kBAAkB,cAAc,KAAK,EAAA,EAC1E;CACjB;AACF;AArbC,yBAAA,WAAA,CAAA,WAAW,GAAA,mBAAA,qBAAA"}