diff --git a/.claude/agents/README.md b/.claude/agents/README.md new file mode 100644 index 00000000..834b0ce2 --- /dev/null +++ b/.claude/agents/README.md @@ -0,0 +1,154 @@ +# Agentes del Proyecto CFDI + +Guia para invocar agentes especializados durante el desarrollo. + +## Equipo disponible + +| Agente | Archivo | Rol | Modelo | +|--------|---------|-----|--------| +| `cfdi-developer` | `cfdi-developer.md` | Desarrollador de facturacion mexicana | sonnet | +| `pdf-developer` | `pdf-developer.md` | Desarrollador de PDF y plantillas | sonnet | +| `code-reviewer` | `code-reviewer.md` | Revisor de codigo y seguridad | sonnet | +| `test-runner` | `test-runner.md` | Ejecutor de tests | haiku | + +## Uso basico (un agente) + +Desde Claude Code, invoca un agente con lenguaje natural: + +``` +Usa el cfdi-developer para agregar soporte del complemento de nomina 1.2 +``` + +``` +Usa el code-reviewer para revisar los cambios del branch actual +``` + +``` +Usa el pdf-developer para crear un nuevo diseño de factura con carta porte +``` + +``` +Usa el test-runner para verificar que todo pase +``` + +## Uso multi-agente (desarrollo de features) + +### Flujo recomendado para un feature nuevo + +**Paso 1: Implementacion** +``` +Usa el cfdi-developer para implementar [feature] +``` + +**Paso 2: Tests** +``` +Usa el test-runner para verificar que los tests pasen +``` + +**Paso 3: Revision** +``` +Usa el code-reviewer para revisar los cambios +``` + +### Trabajo en paralelo (multiples terminales) + +Abre varias terminales con worktrees aislados para que cada agente trabaje sin conflictos: + +```bash +# Terminal 1 - Desarrollo CFDI +claude --worktree feature-nomina +> Usa el cfdi-developer para implementar el complemento de nomina 1.2 + +# Terminal 2 - Desarrollo PDF (en paralelo) +claude --worktree feature-pdf-nomina +> Usa el pdf-developer para crear la plantilla PDF de nomina + +# Terminal 3 - Revision continua +claude --worktree review +> Usa el code-reviewer para revisar los cambios en el branch feature-nomina +``` + +### Orquestar agentes en una sola sesion + +Puedes pedir que se ejecuten agentes en secuencia o en paralelo dentro de una misma sesion: + +``` +Necesito implementar el complemento de pagos 2.0: + +1. Primero usa el cfdi-developer para crear la estructura XML del complemento +2. Luego usa el pdf-developer para agregar el diseño PDF del complemento de pagos +3. Despues usa el test-runner para verificar que todo compile y pase +4. Finalmente usa el code-reviewer para revisar todo +``` + +O en paralelo: + +``` +En paralelo: +- Usa el cfdi-developer para implementar la validacion de carta porte 3.1 +- Usa el pdf-developer para crear el diseño PDF de carta porte +Cuando ambos terminen, usa el test-runner para validar +``` + +## Ejemplos por tipo de tarea + +### Nuevo complemento fiscal + +``` +Usa el cfdi-developer para: +1. Crear la clase del complemento en packages/cfdi/complementos/ +2. Agregar los tipos en packages/cfdi/types/ +3. Agregar el elemento en packages/cfdi/elements/ +4. Actualizar los exports en cada index.ts +5. Crear tests basicos +``` + +### Corregir bug en XML + +``` +Usa el cfdi-developer para investigar y corregir el bug: +[descripcion del bug] + +Despues usa el test-runner para verificar que no se rompio nada +``` + +### Nuevo diseño de factura PDF + +``` +Usa el pdf-developer para crear un nuevo diseño de factura: +- Nombre: PDF224 +- Estilo: moderno con tabla de conceptos compacta +- Debe incluir: logo, QR, desglose de impuestos, total en letras +``` + +### Code review antes de merge + +``` +Usa el code-reviewer para revisar todos los cambios del branch actual +comparados con main. Enfocate en: +- Seguridad en manejo de certificados +- Compliance con esquema CFDI 4.0 +- Cobertura de tests +``` + +### Validar CI completo + +``` +Usa el test-runner para: +1. Correr rush test:ci +2. Si hay fallos, reportar que paquete fallo y por que +3. Sugerir la solucion +``` + +## Reglas automaticas + +Las reglas en `.claude/rules/` se cargan automaticamente segun los archivos que se esten editando: + +| Regla | Se activa cuando editas | +|-------|------------------------| +| `cfdi-domain.md` | `packages/cfdi/**/*.ts` | +| `coding-standards.md` | Cualquier `.ts` o `.tsx` | +| `testing.md` | Archivos `*.test.ts`, `*.spec.ts` | +| `security.md` | Archivos de certificados, llaves, openssl | + +No necesitas invocarlas manualmente, se aplican solas. diff --git a/.claude/agents/cfdi-developer.md b/.claude/agents/cfdi-developer.md new file mode 100644 index 00000000..7866a5e7 --- /dev/null +++ b/.claude/agents/cfdi-developer.md @@ -0,0 +1,56 @@ +--- +name: cfdi-developer +description: Desarrollador especialista en facturacion electronica mexicana (CFDI 4.0). Usa este agente para implementar features de XML, validacion, complementos, certificados y todo lo relacionado con el SAT. +tools: Read, Edit, Write, Grep, Glob, Bash +model: sonnet +--- + +Eres un desarrollador senior especializado en facturacion electronica mexicana (CFDI). + +## Tu dominio + +- Estandar CFDI 4.0 del SAT +- Esquemas XSD oficiales del SAT (Anexo 20) +- Certificados de Sello Digital (CSD) - archivos .cer y .key +- Cadena original via XSLT +- Sello digital SHA-256 +- Complementos fiscales (pagos, nomina, carta porte, comercio exterior, etc.) +- Catalogos del SAT (formas de pago, regimenes fiscales, usos CFDI, etc.) +- Validacion de RFC y CURP +- Expresiones impresas y codigos QR + +## Paquetes bajo tu responsabilidad + +- `packages/cfdi/xml/` - Generacion y sellado XML +- `packages/cfdi/csd/` - Certificados digitales +- `packages/cfdi/catalogos/` - Catalogos SAT +- `packages/cfdi/complementos/` - Complementos fiscales +- `packages/cfdi/elements/` - Elementos del comprobante +- `packages/cfdi/types/` - Tipos TypeScript +- `packages/cfdi/schema/` - Procesamiento XSD +- `packages/cfdi/xsd/` - Validacion XSD +- `packages/cfdi/transform/` - Transformacion de datos +- `packages/cfdi/expresiones/` - Expresiones impresas +- `packages/cfdi/xml2json/` - Conversion XML a JSON +- `packages/cfdi/csf/` - Constancia de Situacion Fiscal +- `packages/cfdi/curp/` - Validacion CURP +- `packages/cfdi/rfc/` - Validacion RFC +- `packages/clir/openssl/` - Wrapper OpenSSL +- `packages/clir/saxon-he/` - Wrapper Saxon-HE + +## Reglas + +- Todo XML generado DEBE validar contra el esquema XSD oficial del SAT +- Los namespaces deben ser correctos: `cfdi:`, `tfd:`, `pago20:`, etc. +- Nunca hardcodear valores de catalogos, usar los enums de `@cfdi/catalogos` +- Los tests deben cubrir al menos: generacion XML, sellado, validacion de estructura +- Usar `@cfdi/types` para todas las interfaces +- Documentar cambios en el esquema o catalogo del SAT que motiven la modificacion + +## Cuando te invoquen + +1. Lee el codigo existente antes de modificar +2. Verifica contra la especificacion del SAT +3. Implementa con tipos estrictos +4. Agrega o actualiza tests +5. Valida que `rush test:ci` pase diff --git a/.claude/agents/code-reviewer.md b/.claude/agents/code-reviewer.md new file mode 100644 index 00000000..196d01a0 --- /dev/null +++ b/.claude/agents/code-reviewer.md @@ -0,0 +1,55 @@ +--- +name: code-reviewer +description: Revisor de codigo. Usa este agente para revisar PRs, calidad de codigo, seguridad y cumplimiento de estandares del proyecto. +tools: Read, Grep, Glob, Bash +model: sonnet +--- + +Eres un revisor de codigo senior para un proyecto de facturacion electronica mexicana. + +## Tu rol + +Revisas codigo para garantizar calidad, seguridad y cumplimiento con los estandares del proyecto. No escribes codigo, solo identificas problemas y sugieres mejoras. + +## Areas de revision + +### Seguridad +- Manejo de certificados y llaves privadas (.cer, .key) - nunca en logs ni en respuestas +- Contraseñas no hardcodeadas +- Validacion de inputs (RFC, CURP, montos) +- Sin inyeccion de comandos en wrappers CLI (openssl, saxon) +- Datos sensibles no expuestos en errores + +### Calidad TypeScript +- Tipos estrictos, sin `any` injustificado +- Interfaces bien definidas usando `@cfdi/types` +- Manejo de errores especifico, no generico +- Funciones con responsabilidad unica +- Sin codigo duplicado entre paquetes + +### CFDI compliance +- XML valido contra esquema XSD del SAT +- Namespaces correctos +- Catalogos del SAT actualizados +- Cadena original con el orden correcto de atributos +- Sello digital generado correctamente + +### Tests +- Cobertura de casos criticos (sellado, validacion, generacion XML) +- Tests de error (certificado invalido, llave incorrecta, XML malformado) +- Sin tests que dependan de servicios externos sin mock + +## Formato de reporte + +Organiza tus hallazgos por prioridad: + +**CRITICO** - Debe corregirse antes de merge (seguridad, datos incorrectos) +**ADVERTENCIA** - Deberia corregirse (calidad, mantenibilidad) +**SUGERENCIA** - Considerar mejorar (estilo, optimizacion) + +## Cuando te invoquen + +1. Ejecuta `git diff` o `git log` para entender los cambios +2. Lee los archivos modificados completos (no solo el diff) +3. Verifica que los tests pasen: `rush test:ci` +4. Genera reporte estructurado diff --git a/.claude/agents/pdf-developer.md b/.claude/agents/pdf-developer.md new file mode 100644 index 00000000..84446bdb --- /dev/null +++ b/.claude/agents/pdf-developer.md @@ -0,0 +1,41 @@ +--- +name: pdf-developer +description: Desarrollador de generacion PDF. Usa este agente para diseños de facturas, plantillas PDF, renderizado y exportacion de documentos CFDI. +tools: Read, Edit, Write, Grep, Glob, Bash +model: sonnet +--- + +Eres un desarrollador especializado en generacion de PDF para facturas electronicas mexicanas. + +## Tu dominio + +- Generacion de PDF con pdfmake +- Diseño de plantillas de facturas +- Renderizado de tablas de conceptos e impuestos +- Codigos QR para expresiones impresas del CFDI +- Conversion de numeros a letras (totales) +- Manejo de logos e imagenes +- Fuentes tipograficas personalizadas + +## Paquetes bajo tu responsabilidad + +- `packages/cfdi/pdf/` - Opciones y configuracion PDF +- `packages/cfdi/designs/` - Plantillas y diseños de facturas +- `packages/cfdi/utils/` - Utilidades (NumeroALetras, Logo) + +## Reglas + +- Los diseños deben usar las clases utilitarias: PDF, Row, Column, Table, Cell, Text, Image, Style +- Nuevos diseños deben extender `GeneradorPdf` +- El QR debe cumplir con la especificacion del SAT (minimo 2.75cm) +- Los totales siempre en letras usando `NumeroALetras` +- Soportar logos en base64 con dimensiones configurables +- Los PDF deben ser legibles en impresion y pantalla +- Fuentes debe soportar caracteres especiales del español (ñ, acentos) + +## Cuando te invoquen + +1. Lee el diseño existente antes de crear uno nuevo +2. Usa las clases utilitarias, no pdfmake directo +3. Verifica que el PDF generado contenga todos los datos fiscales requeridos +4. Prueba con datos reales de CFDI diff --git a/.claude/agents/test-runner.md b/.claude/agents/test-runner.md new file mode 100644 index 00000000..f2034dfd --- /dev/null +++ b/.claude/agents/test-runner.md @@ -0,0 +1,33 @@ +--- +name: test-runner +description: Ejecuta tests y valida que el proyecto compile correctamente. Usa este agente despues de hacer cambios para verificar que nada se rompio. +tools: Read, Grep, Glob, Bash +model: haiku +--- + +Eres un agente de CI que ejecuta tests y reporta resultados. + +## Cuando te invoquen + +1. Ejecuta `rush test:ci` para correr todos los tests +2. Si hay fallos, analiza el error y reporta: + - Que test fallo + - En que paquete + - El mensaje de error + - Posible causa raiz +3. Si todos pasan, confirma con un resumen + +## Formato de reporte + +``` +Estado: PASS / FAIL +Paquetes: X de Y pasaron +Tiempo: Xs + +[Si hay fallos] +FALLO: @cfdi/paquete + Test: nombre del test + Error: mensaje + Archivo: ruta:linea + Causa probable: explicacion breve +``` diff --git a/.claude/rules/cfdi-domain.md b/.claude/rules/cfdi-domain.md new file mode 100644 index 00000000..abec3058 --- /dev/null +++ b/.claude/rules/cfdi-domain.md @@ -0,0 +1,16 @@ +--- +globs: + - "packages/cfdi/**/*.ts" + - "packages/cfdi/**/*.tsx" +--- + +# Reglas de dominio CFDI + +- Todo XML debe validar contra el esquema XSD oficial del SAT (CFDI 4.0 / Anexo 20) +- Los namespaces obligatorios: `cfdi:`, `tfd:`, `xsi:` +- RFC: 12 caracteres (PM) o 13 (PF) con digito verificador +- CURP: 18 caracteres con validacion de entidad y digito +- Catalogos: siempre usar enums de `@cfdi/catalogos`, no strings literales +- Montos: siempre con 2 decimales minimo, sin redondeo incorrecto +- Fechas: formato ISO 8601 `YYYY-MM-DDTHH:mm:ss` +- Los paquetes se consumen desde `src/`, NO compilar para uso interno diff --git a/.claude/rules/coding-standards.md b/.claude/rules/coding-standards.md new file mode 100644 index 00000000..342838b8 --- /dev/null +++ b/.claude/rules/coding-standards.md @@ -0,0 +1,126 @@ +--- +globs: + - "**/*.ts" + - "**/*.tsx" +--- + +# Estandares de codificacion + +## Formato + +- Prettier: singleQuote, trailingComma 'es5', printWidth 80, arrowParens 'avoid' +- Indentacion: 2 espacios +- Fin de linea: auto + +## Nombres + +- **Clases**: PascalCase (`Comprobante`, `BaseImpuestos`, `CfdiSchema`) +- **Funciones/variables**: camelCase (`setFile`, `getPem`, `validateLocal`) +- **Constantes**: UPPER_SNAKE_CASE (`COMPROBANTE`, `EMISOR`, `RECEPTOR`) +- **Archivos de clases**: PascalCase (`Comprobante.ts`, `Elemento.ts`) +- **Archivos utilitarios**: camelCase (`checkDigit.ts`, `number.utils.ts`) +- **Interfaces**: sufijo `.interface.ts` o en carpeta `types/` +- **Propiedades privadas**: prefijo underscore (`_cadenaOriginal`, `_attributes`) + +## TypeScript + +- `strict: true` habilitado +- Preferir tipos explicitos en parametros y retornos de funciones publicas +- `any` permitido solo cuando es necesario, preferir tipos especificos +- Usar `type` para unions y aliases, `interface` para estructuras de objetos +- Generics cuando el tipo varia (`Elemento`, `Complemento`) +- Type assertions con `as` solo cuando sea necesario +- Preferir `Omit`, `Pick`, `Partial` sobre crear interfaces duplicadas + +## Patrones de clases + +- **Singleton**: factory method estatico `of()` con constructor privado +- **Clases base abstractas**: prefijo `Base` (`BaseImpuestos`, `BaseXSDProcessor`) +- **Fluent interface**: metodos que retornan `this` para encadenar (`return this`) +- **Herencia**: para elementos XML que comparten comportamiento + +```typescript +// Singleton +export class Schema { + private static instance: Schema; + private constructor() {} + public static of(): Schema { + if (!Schema.instance) Schema.instance = new Schema(); + return Schema.instance; + } +} + +// Fluent interface +setReceptor(data: XmlReceptor): this { + this.xml['cfdi:Receptor'] = { _attributes: data }; + return this; +} +``` + +## Importaciones + +Orden: +1. Librerias externas (`node-forge`, `xml-js`, `ajv`) +2. Paquetes del monorepo (`@cfdi/types`, `@cfdi/catalogos`) +3. Imports relativos (`./cer`, `../types`) + +```typescript +import pkg from 'node-forge'; +import { XmlComprobante } from '@cfdi/types'; +import { MetodoPago } from '@cfdi/catalogos'; +import { Comprobante } from './Comprobante'; +``` + +## Exportaciones + +- Barrel files (`index.ts`) con `export * from './modulo'` +- Exportaciones nombradas sobre default +- Agrupar re-exports por categoria + +```typescript +// index.ts +export * from './FormaPago'; +export * from './MetodoPago'; +export { Concepto as Concepts } from './elements/Concepto'; +export type { LoaderOptions } from './loader.xsd'; +``` + +## Manejo de errores + +- Clases de error custom que extienden `Error` +- Factory function `CFDIError()` para errores con contexto +- Propiedades: `code`, `message`, `name`, `method` +- Logging condicional con `debug` + +```typescript +export class BadCurpFormat extends Error { + constructor(curp: string) { + super(`'${curp}' is an invalid curp`); + } +} +``` + +## Async + +- Tipo `Promise` explicito en retornos +- Try-catch en metodos async con rethrow usando `CFDIError` +- Separar metodos sincronos de asincronos claramente + +## Organizacion de archivos + +``` +src/ + index.ts # Barrel file + [Clase].ts # Clases principales (PascalCase) + elements/ # Componentes XML + Base[Nombre].ts # Clases base + [Nombre].ts # Implementaciones + types/ # Interfaces y tipos + index.ts + [nombre].interface.ts + common/ # Codigo compartido + constants.ts + error.ts + utils/ # Funciones utilitarias + [nombre].utils.ts +``` diff --git a/.claude/rules/security.md b/.claude/rules/security.md new file mode 100644 index 00000000..d386726e --- /dev/null +++ b/.claude/rules/security.md @@ -0,0 +1,17 @@ +--- +globs: + - "packages/cfdi/csd/**/*.ts" + - "packages/clir/openssl/**/*.ts" + - "**/*key*" + - "**/*cer*" + - "**/*certificate*" +--- + +# Reglas de seguridad para certificados + +- NUNCA loguear contenido de llaves privadas (.key) +- NUNCA incluir contraseñas en logs o respuestas de error +- Sanitizar inputs antes de pasarlos a CLI de OpenSSL (prevenir inyeccion de comandos) +- Los archivos .cer y .key de prueba del SAT son publicos, OK usarlos en tests +- Las firmas digitales deben usar SHA-256 +- Validar que el certificado no este expirado antes de firmar diff --git a/.claude/rules/testing.md b/.claude/rules/testing.md new file mode 100644 index 00000000..c6f5b0ab --- /dev/null +++ b/.claude/rules/testing.md @@ -0,0 +1,16 @@ +--- +globs: + - "**/*.test.ts" + - "**/*.spec.ts" + - "**/vitest.config.*" +--- + +# Reglas de testing + +- Framework: Vitest +- Ejecutar tests: `rush test:ci` +- Tests de XML deben validar estructura completa, no solo fragmentos +- Tests de certificados usan archivos de prueba del SAT en `packages/files/` +- No mockear la base de datos ni el filesystem para tests de integracion +- Los warnings en stderr durante tests de error son comportamiento esperado +- Cada paquete tiene su propio `vitest.config.mts` que extiende del rig diff --git a/.github/actions/cfdi/action.yml b/.github/actions/cfdi/action.yml index add8f244..ec44807e 100644 --- a/.github/actions/cfdi/action.yml +++ b/.github/actions/cfdi/action.yml @@ -9,13 +9,20 @@ inputs: runs: using: 'composite' steps: - - name: Schema - uses: actions/checkout@v4 - with: - repository: MisaelMa/cfdi-schema - branch: main - path: packages/cfdi/schema - token: ${{ inputs.token }} + # - name: Schema + # uses: actions/checkout@v4 + # with: + # repository: MisaelMa/cfdi-schema + # branch: main + # path: packages/cfdi/schema + # token: ${{ inputs.token }} + # - name: Desings + # uses: actions/checkout@v4 + # with: + # repository: MisaelMa/designs + # branch: main + # path: packages/cfdi/designs + # token: ${{ inputs.token }} - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 diff --git a/.github/workflows/semantic.yml b/.github/workflows/semantic.yml index bcfda152..dd4ae070 100644 --- a/.github/workflows/semantic.yml +++ b/.github/workflows/semantic.yml @@ -17,7 +17,7 @@ jobs: - name: Platform label uses: agilepathway/label-checker@v1.0.104 with: - any_of: config,core,catalogs,csd,csf,curp,pdf,rfc,utils,xml,xsd,complementos,openssl,saxon,schema,transform,types,elements,2json,expresiones,publish + any_of: config,core,catalogs,csd,csf,curp,pdf,rfc,utils,xml,xsd,complementos,openssl,saxon,schema,transform,types,elements,2json,expresiones,publish,sat,estado,descarga,validador,cleaner,auth repo_token: ${{ secrets.GITHUB_TOKEN }} check-title: @@ -53,3 +53,9 @@ jobs: elements expresiones 2json + sat + estado + descarga + validador + cleaner + auth diff --git a/.gitignore b/.gitignore index 6f51bfd3..a41042e7 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,8 @@ build/Release # Dependency directories node_modules/ jspm_packages/ -packages/cfdi/schema/ +# packages/cfdi/schema +# packages/cfdi/designs # Optional npm cache directory .npm diff --git a/.nvmrc b/.nvmrc index 7950a445..33206cba 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18.17.0 +v22.0.0 diff --git a/.vscode/settings.json b/.vscode/settings.json index 25e84d51..6b0f34b1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,7 @@ { "cSpell.words": [ - "recreando" + "cfdi", + "recreando", + "Trasladados" ] } diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..c20721d1 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,68 @@ +# CFDI - Proyecto + +Ecosistema de paquetes Node.js/TypeScript para generacion, validacion, firma y procesamiento de CFDI (Comprobantes Fiscales Digitales por Internet) en Mexico. + +## Stack + +- **Monorepo**: Rush + pnpm +- **Lenguaje**: TypeScript +- **Build**: Vite (migrando desde tsdx) +- **Tests**: Vitest +- **Node**: >= 22 + +## Comandos + +```bash +rush install # Instalar dependencias +rush update # Actualizar dependencias +rush build # Compilar todos los paquetes +rush test:ci # Ejecutar tests +``` + +## Estructura + +``` +packages/ + cfdi/ # Paquetes core de facturacion + xml/ # Generacion y sellado de XML CFDI 4.0 + csd/ # Certificados de Sello Digital (.cer/.key) + catalogos/ # Catalogos del SAT (enums, tipos) + complementos/ # Complementos fiscales (pagos, nomina, etc.) + elements/ # Elementos estructurales del comprobante + types/ # Interfaces TypeScript para CFDI + schema/ # Procesamiento de esquemas XSD + xsd/ # Validacion XSD con JSON Schema + transform/ # Transformacion de datos CFDI + expresiones/ # Expresiones impresas (QR) + xml2json/ # Conversion XML a JSON + csf/ # Lectura de Constancia de Situacion Fiscal + rfc/ # Validacion de RFC + pdf/ # Opciones de generacion PDF + designs/ # Plantillas y disenos PDF + utils/ # Utilidades (numeros a letras, logos) + sat/ # Paquetes de integracion con el SAT + auth/ # Autenticacion con webservices del SAT (FIEL) + recursos/ # Descarga de recursos XSD/XSLT del SAT + renapo/ # Paquetes de integracion con RENAPO + curp/ # Validacion y consulta de CURP + clir/ # CLI wrappers + openssl/ # Wrapper OpenSSL + saxon-he/ # Wrapper Saxon-HE (XSLT) + server/ # Aplicacion web Next.js +``` + +## Reglas del proyecto + +- Los paquetes workspace se consumen desde `src/` directamente, NO desde `dist/` +- No compilar para compartir entre paquetes internos +- Los campos `main`/`module` en package.json apuntan a `src/index.ts` para desarrollo +- XML debe validar contra el esquema oficial CFDI 4.0 del SAT +- RFC: 12 caracteres (persona moral) o 13 (persona fisica) +- CURP: 18 caracteres +- Firmas digitales usan SHA-256 +- Tests deben pasar antes de cualquier merge + +## Dependencias del sistema + +- OpenSSL (certificados digitales) +- Java JDK + Saxon-HE >= 9.9 (transformaciones XSLT para cadena original) diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..8fdabe57 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-present Amir Misael Marin Coh + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 65892bb7..f81a6956 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,139 @@ -rush version --version-policy tooling --bump -rush publish --publish --version-policy tooling --include-all --set-access-level public --npm-auth-token -rush version --bump --version-polic cfdiUtils +# CFDI - Comprobantes Fiscales Digitales por Internet -patch => 1.0.1 -minor => 1.1.0 -prerelease => 1.2.1-0 -major => 1.0.0 +Ecosistema completo de paquetes Node.js/TypeScript para la generación, validación, firma y procesamiento de CFDI en México. -##saxon cli => https://github.com/MisaelMa/saxon-he npm i @saxon/cli -##saxon => https://www.npmjs.com/package/xslt3 npm i xslt3 -![Captura de pantalla_área-de-selección_20220827161829](https://user-images.githubusercontent.com/19777772/187048312-4cc9d079-8431-4029-9b32-83912fa3e9f7.png) +## Paquetes -colaboracion +### Core Fiscal +| Paquete | Descripcion | +| ------------------------------------------------ | -------------------------------------------------------- | +| [@cfdi/xml](packages/cfdi/xml) | Generacion y sellado de XML CFDI 4.0 | +| [@cfdi/complementos](packages/cfdi/complementos) | Complementos fiscales (pagos, nomina, carta porte, etc.) | +| [@cfdi/elements](packages/cfdi/elements) | Elementos estructurales del comprobante | +| [@cfdi/types](packages/cfdi/types) | Definiciones de tipos TypeScript para CFDI | +| [@cfdi/catalogos](packages/cfdi/catalogos) | Catalogos del SAT (formas de pago, regimenes, etc.) | + +### Validacion + +| Paquete | Descripcion | +| ------------------------------------ | ------------------------------------- | +| [@cfdi/xsd](packages/cfdi/xsd) | Validacion XSD con JSON Schema | +| [@cfdi/schema](packages/cfdi/schema) | Procesamiento de esquemas XSD del SAT | + +### Identidades y Certificados + +| Paquete | Descripcion | +| -------------------------------------- | --------------------------------------------------- | +| [@cfdi/csd](packages/cfdi/csd) | Manejo de Certificados de Sello Digital (.cer/.key) | +| [@cfdi/csf](packages/cfdi/csf) | Lectura de Constancia de Situacion Fiscal (PDF) | +| [@cfdi/rfc](packages/cfdi/rfc) | Validacion de RFC | +| [@renapo/curp](packages/renapo/curp) | Validacion y consulta de CURP | +| [@sat/auth](packages/sat/auth) | Autenticacion con webservices del SAT (FIEL) | +| [@sat/recursos](packages/sat/recursos) | Descarga de recursos XSD/XSLT del SAT | + +### Transformacion + +| Paquete | Descripcion | +| ---------------------------------------------- | ----------------------------- | +| [@cfdi/2json](packages/cfdi/xml2json) | Conversion de XML CFDI a JSON | +| [@cfdi/transform](packages/cfdi/transform) | Transformacion de datos CFDI | +| [@cfdi/expresiones](packages/cfdi/expresiones) | Expresiones impresas del CFDI | + +### PDF + +| Paquete | Descripcion | +| -------------------------------------- | ---------------------------------------------- | +| [@cfdi/designs](packages/cfdi/designs) | Disenos y plantillas PDF para facturas | +| [@cfdi/pdf](packages/cfdi/pdf) | Opciones de generacion PDF | +| [@cfdi/utils](packages/cfdi/utils) | Utilidades (numeros a letras, logos, archivos) | + +### CLI Tools + +| Paquete | Descripcion | +| --------------------------------------- | ------------------------------------ | +| [@clir/openssl](packages/clir/openssl) | Wrapper de OpenSSL para certificados | +| [@saxon-he/cli](packages/clir/saxon-he) | Wrapper de Saxon-HE para XSLT/XPath | + +## Requisitos del sistema + +- **Node.js** >= 22 +- **Java JDK** (para Saxon-HE) +- **OpenSSL** (para operaciones con certificados) +- **Saxon-HE** >= 9.9 (para cadena original) + +### Instalacion de dependencias del sistema + +```bash +# Java JDK +sudo apt install default-jre default-jdk + +# OpenSSL +# Debian/Ubuntu +sudo apt-get install openssl +# CentOS/Red Hat +yum install openssl +# macOS +brew install openssl + +# Saxon-HE +# Ver: https://github.com/MisaelMa/saxon-he +``` + +## Inicio rapido + +```bash +# Instalar Rush y pnpm npm install -g @microsoft/rush npm install -g pnpm -rush install o rush update + +# Clonar e instalar +git clone https://github.com/MisaelMa/cfdi.git +cd cfdi +rush install + +# Compilar todos los paquetes +rush build + +# Ejecutar tests +rush test:ci +``` + +## Uso basico + +```bash +npm install @cfdi/xml @cfdi/csd +``` + +```typescript +import { CFDI } from '@cfdi/xml'; + +const cfdi = new CFDI({ xslt: 'path/to/cadenaoriginal.xslt' }); + +cfdi.certificar('path/to/certificado.cer'); +cfdi.setEmisor({ + Rfc: 'AAA010101AAA', + Nombre: 'Empresa SA', + RegimenFiscal: '601', +}); +cfdi.setReceptor({ + Rfc: 'XAXX010101000', + Nombre: 'Publico General', + UsoCFDI: 'S01', +}); +cfdi.addConcepto({ + ClaveProdServ: '01010101', + Cantidad: '1', + ClaveUnidad: 'ACT', + Descripcion: 'Servicio profesional', + ValorUnitario: '1000.00', + Importe: '1000.00', +}); + +await cfdi.sellar('path/to/llave.key', 'password'); +const xml = cfdi.getXmlCdfi(); +``` + +## Licencia + +[MIT](LICENSE) - Amir Misael Marin Coh diff --git a/commitlint.config.js b/commitlint.config.js index 11c94109..6ab2a268 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -32,7 +32,12 @@ module.exports = { 'types', 'elements', 'expresiones', - '2json' + '2json', + 'sat', + 'estado', + 'descarga', + 'validador', + 'cleaner' ] ], 'type-enum': [ diff --git a/common/changes/@cfdi/curp/beta_2022-08-09-18-04.json b/common/changes/@renapo/curp/beta_2022-08-09-18-04.json similarity index 61% rename from common/changes/@cfdi/curp/beta_2022-08-09-18-04.json rename to common/changes/@renapo/curp/beta_2022-08-09-18-04.json index 42723e50..354baee3 100644 --- a/common/changes/@cfdi/curp/beta_2022-08-09-18-04.json +++ b/common/changes/@renapo/curp/beta_2022-08-09-18-04.json @@ -1,10 +1,10 @@ { "changes": [ { - "packageName": "@cfdi/curp", + "packageName": "@renapo/curp", "comment": "aclarse a los servicios de renapo", "type": "none" } ], - "packageName": "@cfdi/curp" + "packageName": "@renapo/curp" } \ No newline at end of file diff --git a/common/config/rush/browser-approved-packages.json b/common/config/rush/browser-approved-packages.json index ec78b037..da8a8957 100644 --- a/common/config/rush/browser-approved-packages.json +++ b/common/config/rush/browser-approved-packages.json @@ -28,11 +28,11 @@ }, { "name": "@cfdi/2json", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@cfdi/catalogos", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@cfdi/complementos", @@ -47,9 +47,41 @@ "allowedCategories": [ "libraries" ] }, { - "name": "@cfdi/curp", + "name": "@renapo/curp", + "allowedCategories": [ "libraries" ] + }, + { + "name": "@sat/auth", + "allowedCategories": [ "libraries" ] + }, + { + "name": "@sat/recursos", + "allowedCategories": [ "libraries" ] + }, + { + "name": "@sat/scraper", + "allowedCategories": [ "libraries" ] + }, + { + "name": "@sat/opinion", + "allowedCategories": [ "libraries" ] + }, + { + "name": "@sat/contabilidad", + "allowedCategories": [ "libraries" ] + }, + { + "name": "@sat/captcha", + "allowedCategories": [ "libraries" ] + }, + { + "name": "@cfdi/cancelacion", "allowedCategories": [ "libraries" ] }, + { + "name": "@cfdi/designs", + "allowedCategories": [ "private" ] + }, { "name": "@cfdi/elements", "allowedCategories": [ "libraries" ] @@ -60,11 +92,11 @@ }, { "name": "@cfdi/pdf", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@cfdi/schema", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@cfdi/types", @@ -72,12 +104,16 @@ }, { "name": "@cfdi/utils", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@cfdi/xml", "allowedCategories": [ "libraries", "production" ] }, + { + "name": "@cfdi/xml2json", + "allowedCategories": [ "libraries" ] + }, { "name": "@cfdi/xsd", "allowedCategories": [ "libraries" ] @@ -102,6 +138,10 @@ "name": "@emotion/styled", "allowedCategories": [ "libraries" ] }, + { + "name": "@eslint/eslintrc", + "allowedCategories": [ "private" ] + }, { "name": "@esm2cjs/execa", "allowedCategories": [ "libraries" ] @@ -152,11 +192,11 @@ }, { "name": "@nestjs/cli", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@nestjs/common", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@nestjs/config", @@ -164,7 +204,7 @@ }, { "name": "@nestjs/core", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@nestjs/jwt", @@ -176,7 +216,7 @@ }, { "name": "@nestjs/platform-express", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@nestjs/schedule", @@ -184,7 +224,7 @@ }, { "name": "@nestjs/schematics", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@nestjs/swagger", @@ -192,7 +232,7 @@ }, { "name": "@nestjs/testing", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@nestjs/typeorm", @@ -230,6 +270,14 @@ "name": "@reduxjs/toolkit", "allowedCategories": [ "libraries" ] }, + { + "name": "@rollup/plugin-terser", + "allowedCategories": [ "libraries" ] + }, + { + "name": "@rollup/plugin-url", + "allowedCategories": [ "libraries" ] + }, { "name": "@rushstack/eslint-config", "allowedCategories": [ "libraries", "private", "production" ] @@ -256,7 +304,7 @@ }, { "name": "@swc/core", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@swc/helpers", @@ -270,6 +318,10 @@ "name": "@swc/register", "allowedCategories": [ "libraries" ] }, + { + "name": "@tailwindcss/postcss", + "allowedCategories": [ "private" ] + }, { "name": "@testing-library/dom", "allowedCategories": [ "libraries", "private", "production" ] @@ -288,11 +340,11 @@ }, { "name": "@typescript-eslint/eslint-plugin", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@typescript-eslint/parser", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "@vitest/coverage-v8", @@ -340,11 +392,11 @@ }, { "name": "class-transformer", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "class-validator", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "cookie", @@ -380,11 +432,11 @@ }, { "name": "eslint-config-next", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "eslint-config-prettier", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "eslint-import-resolver-typescript", @@ -412,7 +464,7 @@ }, { "name": "eslint-plugin-prettier", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "eslint-plugin-react", @@ -528,7 +580,7 @@ }, { "name": "next", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "next-redux-wrapper", @@ -576,7 +628,7 @@ }, { "name": "pdfmake", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "pg", @@ -584,7 +636,7 @@ }, { "name": "prettier", - "allowedCategories": [ "libraries", "production" ] + "allowedCategories": [ "libraries", "private", "production" ] }, { "name": "puppeteer", @@ -604,11 +656,11 @@ }, { "name": "react", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "react-dom", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "react-is", @@ -632,7 +684,7 @@ }, { "name": "reflect-metadata", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "rimraf", @@ -648,7 +700,7 @@ }, { "name": "rxjs", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "save-file", @@ -664,7 +716,7 @@ }, { "name": "source-map-support", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "styled-components", @@ -692,23 +744,27 @@ }, { "name": "supertest", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] + }, + { + "name": "tailwindcss", + "allowedCategories": [ "private" ] }, { "name": "ts-jest", - "allowedCategories": [ "libraries", "production" ] + "allowedCategories": [ "libraries", "private", "production" ] }, { "name": "ts-loader", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "ts-node", - "allowedCategories": [ "libraries", "production" ] + "allowedCategories": [ "libraries", "private", "production" ] }, { "name": "tsconfig-paths", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "tsconfig-paths-webpack-plugin", @@ -730,6 +786,10 @@ "name": "tslint-config-prettier", "allowedCategories": [ "libraries", "production" ] }, + { + "name": "tsx", + "allowedCategories": [ "libraries" ] + }, { "name": "typeorm", "allowedCategories": [ "libraries" ] @@ -748,11 +808,15 @@ }, { "name": "vite", + "allowedCategories": [ "libraries", "private" ] + }, + { + "name": "vite-plugin-dts", "allowedCategories": [ "libraries" ] }, { "name": "vite-plugin-node", - "allowedCategories": [ "libraries" ] + "allowedCategories": [ "libraries", "private" ] }, { "name": "vite-tsconfig-paths", diff --git a/common/config/rush/command-line.json b/common/config/rush/command-line.json index 17a9a6e9..796625f2 100644 --- a/common/config/rush/command-line.json +++ b/common/config/rush/command-line.json @@ -10,6 +10,16 @@ "autoinstallerName": "rush-commitlint", "shellCommand": "commitlint" }, + { + "commandKind": "bulk", + "name": "sat:download", + "summary": "Descarga recursos del SAT (XSD, XSLT, complementos)", + "enableParallelism": false, + "ignoreMissingScript": true, + "safeForSimultaneousRushProcesses": false, + "ignoreDependencyOrder": true, + "allowWarningsInSuccessfulBuild": true + }, { "commandKind": "bulk", "name": "test:ci", diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index d96c02fa..73531362 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -4,92 +4,110 @@ settings: autoInstallPeers: false excludeLinksFromLockfile: false -pnpmfileChecksum: avk5jcsa6uxo2n5cahoirjiuw4 +pnpmfileChecksum: 55gco67a3joh63apcdosyflxfe importers: .: {} - ../../packages/cfdi/catalogos: + ../../packages/cfdi/cancelacion: devDependencies: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite + '@types/node': + specifier: ^22 + version: 22.19.15 + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/cfdi/catalogos: + devDependencies: + '@recreando/eslint-settings': specifier: workspace:* - version: link:../../../rigs/jest + version: link:../../../rigs/eslint '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/cfdi/cleaner: + devDependencies: + '@recreando/eslint-settings': + specifier: workspace:* + version: link:../../../rigs/eslint + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite + '@types/node': + specifier: ^22 + version: 22.19.15 + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/complementos: dependencies: @@ -100,187 +118,79 @@ importers: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/csd: dependencies: '@clir/openssl': specifier: workspace:* version: link:../../clir/openssl - curp: - specifier: ^1.2.0 - version: 1.2.3 moment: specifier: ^2.29.4 version: 2.30.1 node-forge: specifier: ^1.3.1 version: 1.3.1 - validate-rfc: - specifier: ^2.0.2 - version: 2.0.3 devDependencies: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 + specifier: ^22 + version: 22.19.15 '@types/node-forge': specifier: ^1.0.4 version: 1.3.11 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/csf: dependencies: @@ -300,139 +210,94 @@ importers: '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) '@types/node': - specifier: ^18.11.3 - version: 18.19.57 + specifier: ^22 + version: 22.19.15 '@types/pdf-parse': specifier: ^1.1.4 version: 1.1.4 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) eslint: specifier: ^8.57.0 version: 8.57.1 - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) - ../../packages/cfdi/curp: - dependencies: - 2captcha: - specifier: ^3.0.5 - version: 3.0.7 - axios: - specifier: ^0.27.2 - version: 0.27.2 + ../../packages/cfdi/descarga: devDependencies: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 - version: 5.6.3 + version: 5.8.2 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/cfdi/designs: + dependencies: + '@cfdi/2json': + specifier: workspace:* + version: link:../xml2json + '@cfdi/utils': + specifier: workspace:* + version: link:../utils + pdfmake: + specifier: ^0.2.20 + version: 0.2.23 + devDependencies: + '@rollup/plugin-terser': + specifier: ^0.4.4 + version: 0.4.4(rollup@4.59.0) + '@rollup/plugin-url': + specifier: ^8.0.2 + version: 8.0.2(rollup@4.59.0) + '@types/pdfmake': + specifier: ^0.2.11 + version: 0.2.11 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite: + specifier: ^7.0.0 + version: 7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0) + vite-plugin-dts: + specifier: ^4.5.3 + version: 4.5.3(@types/node@22.19.15)(rollup@4.59.0)(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) ../../packages/cfdi/elements: dependencies: @@ -464,48 +329,60 @@ importers: '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) '@types/node': - specifier: ^18.11.3 - version: 18.19.57 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) eslint: specifier: ^8.57.0 version: 8.57.1 - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/cfdi/estado: + devDependencies: + '@recreando/eslint-settings': + specifier: workspace:* + version: link:../../../rigs/eslint + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite + '@types/node': + specifier: ^22 + version: 22.19.15 + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/expresiones: dependencies: @@ -516,84 +393,33 @@ importers: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/pdf: dependencies: @@ -612,24 +438,9 @@ importers: '@cfdi/xml': specifier: workspace:* version: link:../xml - immutable: - specifier: ^4.0.0-rc.12 - version: 4.3.7 - moment: - specifier: ^2.29.4 - version: 2.30.1 - moment-timezone: - specifier: ^0.5.27 - version: 0.5.46 pdfmake: - specifier: ^0.1.65 - version: 0.1.72 - qrcode: - specifier: ^1.4.4 - version: 1.5.4 - save-file: - specifier: ^2.3.1 - version: 2.3.1 + specifier: ^0.2.20 + version: 0.2.23 xml-js: specifier: ^1.6.11 version: 1.6.11 @@ -637,165 +448,69 @@ importers: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 + specifier: ^22 + version: 22.19.15 '@types/pdfmake': - specifier: ^0.1.13 - version: 0.1.21 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^0.2.11 + version: 0.2.11 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/rfc: devDependencies: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/schema: dependencies: @@ -808,94 +523,40 @@ importers: xsd2jsonschema: specifier: ^0.3.7 version: 0.3.7 - xslt: - specifier: ^0.9.1 - version: 0.9.1 - xslt-processor: - specifier: ^0.11.7 - version: 0.11.7 devDependencies: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/transform: dependencies: - '@cfdi/2json': - specifier: workspace:* - version: link:../xml2json xml-js: specifier: ^1.6.11 version: 1.6.11 @@ -903,87 +564,33 @@ importers: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@saxon-he/cli': - specifier: workspace:* - version: link:../../clir/saxon-he - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/types: dependencies: @@ -1015,48 +622,27 @@ importers: '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) '@types/node': - specifier: ^18.11.3 - version: 18.19.57 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) eslint: specifier: ^8.57.0 version: 8.57.1 - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/utils: dependencies: @@ -1067,84 +653,70 @@ importers: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/cfdi/validador: + dependencies: + xml-js: + specifier: ^1.6.11 + version: 1.6.11 + devDependencies: + '@recreando/eslint-settings': + specifier: workspace:* + version: link:../../../rigs/eslint + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite + '@types/node': + specifier: ^22 + version: 22.19.15 + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/xml: dependencies: @@ -1176,48 +748,27 @@ importers: '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) '@types/node': - specifier: ^18.11.3 - version: 18.19.57 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) eslint: specifier: ^8.57.0 version: 8.57.1 - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/xml2json: dependencies: @@ -1237,84 +788,33 @@ importers: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/cfdi/xsd: dependencies: @@ -1324,103 +824,43 @@ importers: xml-js: specifier: ^1.6.11 version: 1.6.11 - xslt: - specifier: ^0.9.1 - version: 0.9.1 - xslt-processor: - specifier: ^0.11.7 - version: 0.11.7 devDependencies: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript '@recreando/vite': specifier: workspace:* version: link:../../../rigs/vite - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - rimraf: - specifier: ^6.0.1 - version: 6.0.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/clir/openssl: dependencies: '@esm2cjs/execa': specifier: ^6.1.1-cjs.1 version: 6.1.1-cjs.1 - moment: - specifier: ^2.29.4 - version: 2.30.1 node-forge: specifier: ^1.3.1 version: 1.3.1 @@ -1428,81 +868,36 @@ importers: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) - '@testing-library/dom': - specifier: ^8.19.0 - version: 8.20.1 - '@testing-library/jest-dom': - specifier: ^5.16.1 - version: 5.17.0 - '@types/deep-freeze': - specifier: ^0.1.2 - version: 0.1.5 - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite '@types/node': - specifier: ^18.11.3 - version: 18.19.57 + specifier: ^22 + version: 22.19.15 '@types/node-forge': specifier: ^1.0.4 version: 1.3.11 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) - chalk: - specifier: ^4.0.0 - version: 4.1.2 - chokidar: - specifier: ^3.5.2 - version: 3.6.0 eslint: specifier: ^8.57.0 version: 8.57.1 - husky: - specifier: ^8.0.1 - version: 8.0.3 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) ../../packages/clir/saxon-he: dependencies: @@ -1513,214 +908,490 @@ importers: '@recreando/eslint-settings': specifier: workspace:* version: link:../../../rigs/eslint - '@recreando/jest': - specifier: workspace:* - version: link:../../../rigs/jest '@recreando/typescript-settings': specifier: workspace:* version: link:../../../rigs/typescript - '@rushstack/eslint-config': - specifier: ^4.0.2 - version: 4.0.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@size-limit/preset-small-lib': - specifier: ^7.0.8 - version: 7.0.8(size-limit@7.0.8) + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite '@types/node': - specifier: ^18.11.3 - version: 18.19.57 + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) eslint: specifier: ^8.57.0 version: 8.57.1 - size-limit: - specifier: ^7.0.8 - version: 7.0.8 - tsdx: - specifier: ^0.14.1 - version: 0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57) - tslib: - specifier: ^2.4.0 - version: 2.8.0 typescript: specifier: ^5.6.3 version: 5.6.3 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) - ../../rigs/eslint: + ../../packages/renapo/curp: dependencies: - '@typescript-eslint/eslint-plugin': - specifier: ^8.13.0 - version: 8.13.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/parser': - specifier: ^8.13.0 - version: 8.13.0(eslint@8.57.1)(typescript@5.6.3) - eslint-config-prettier: - specifier: ^8.5.0 - version: 8.10.0(eslint@8.57.1) - eslint-import-resolver-typescript: - specifier: ^2.7.1 - version: 2.7.1(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: - specifier: ^2.26.0 - version: 2.31.0(eslint@8.57.1) - eslint-plugin-jest: - specifier: ^28.9.0 - version: 28.9.0(@typescript-eslint/eslint-plugin@8.13.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@28.1.3)(typescript@5.6.3) - eslint-plugin-jsdoc: - specifier: ^39.2.6 - version: 39.9.1(eslint@8.57.1) - eslint-plugin-jsx-a11y: - specifier: ^6.5.1 - version: 6.10.0(eslint@8.57.1) - eslint-plugin-prettier: - specifier: ^4.0.0 - version: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) - eslint-plugin-sort-destructure-keys: - specifier: ^1.4.0 - version: 1.6.0(eslint@8.57.1) - prettier: - specifier: ^2.6.2 - version: 2.8.8 - stylelint: - specifier: ^13.13.1 - version: 13.13.1 - stylelint-config-recommended: - specifier: ^5.0.0 - version: 5.0.0(stylelint@13.13.1) - stylelint-order: - specifier: ^4.1.0 - version: 4.1.0(stylelint@13.13.1) - devDependencies: - eslint: - specifier: ^8.57.0 - version: 8.57.1 - typescript: - specifier: ^5.6.3 - version: 5.6.3 - - ../../rigs/jest: + 2captcha: + specifier: ^3.0.5 + version: 3.0.7 + axios: + specifier: ^0.27.2 + version: 0.27.2 devDependencies: - '@babel/core': - specifier: ^7.17.9 - version: 7.25.8(supports-color@9.4.0) - '@babel/preset-env': - specifier: ^7.17.10 - version: 7.25.8(@babel/core@7.25.8) + '@recreando/eslint-settings': + specifier: workspace:* + version: link:../../../rigs/eslint '@recreando/typescript-settings': specifier: workspace:* - version: link:../typescript - '@types/jest': - specifier: ^27.5.0 - version: 27.5.2 + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite '@types/node': - specifier: ^18.11.3 - version: 18.19.57 - '@types/testing-library__jest-dom': - specifier: ^5.9.1 - version: 5.14.9 - babel-jest: - specifier: ^28.1.0 - version: 28.1.3(@babel/core@7.25.8) - babel-plugin-transform-import-meta: - specifier: ^2.1.1 - version: 2.2.1(@babel/core@7.25.8) - fetch-mock-jest: - specifier: ^1.5.1 - version: 1.5.1(node-fetch@2.7.0) - identity-obj-proxy: - specifier: ^3.0.0 - version: 3.0.0 - jest: - specifier: ^28.1.2 - version: 28.1.3(@types/node@18.19.57) - jest-environment-jsdom: - specifier: ^28.1.0 - version: 28.1.3 - jest-light-runner: - specifier: ^0.2.1 - version: 0.2.2(jest@28.1.3(@types/node@18.19.57)) - jest-watch-typeahead: - specifier: ^1.0.0 - version: 1.1.0(jest@28.1.3(@types/node@18.19.57)) - ts-jest: - specifier: ^28.0.3 - version: 28.0.8(@babel/core@7.25.8)(@jest/types@28.1.3)(babel-jest@28.1.3(@babel/core@7.25.8))(jest@28.1.3(@types/node@18.19.57))(typescript@5.6.3) - ts-loader: - specifier: 9.2.6 - version: 9.2.6(typescript@5.6.3)(webpack@5.95.0) - tsconfig-paths-webpack-plugin: - specifier: ^3.5.2 - version: 3.5.2 - typescript: - specifier: ^5.6.3 - version: 5.6.3 - webpack: - specifier: ^5.72.0 - version: 5.95.0 - - ../../rigs/typescript: - dependencies: - '@rushstack/heft': - specifier: ^0.68.6 - version: 0.68.6(@types/node@18.19.57) - '@rushstack/heft-jest-plugin': - specifier: ^0.12.18 - version: 0.12.18(@rushstack/heft@0.68.6(@types/node@18.19.57))(@types/node@18.19.57)(jest-environment-node@29.7.0) - eslint: - specifier: ^8.57.0 - version: 8.57.1 - jest-environment-node: - specifier: ^29.5.0 - version: 29.7.0 - tsconfig-paths: - specifier: ^4.0.0 - version: 4.2.0 - typescript: - specifier: ^5.6.3 - version: 5.6.3 - - ../../rigs/vite: - dependencies: - vite: - specifier: ^4.0.0 - version: 4.5.5(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0) - devDependencies: + specifier: ^22 + version: 22.19.15 '@vitest/coverage-v8': specifier: 2.1.3 - version: 2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0)) + version: 2.1.3(vitest@2.1.3) '@vitest/ui': specifier: 2.1.3 version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 typescript: specifier: ^5.6.3 - version: 5.6.3 + version: 5.8.2 vite-tsconfig-paths: specifier: ~4.2.1 - version: 4.2.3(typescript@5.6.3)(vite@4.5.5(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) -packages: - - 2captcha@3.0.7: - resolution: {integrity: sha512-i7iswxBsNzzFxQCebgdowHW61UK34+o8KaDonJxRH+gDDeQsiN/3uK0X/fo4AmMTE26c4VSHVe0X8b8CVVNZiw==} + ../../packages/sat/auth: + devDependencies: + '@cfdi/csd': + specifier: workspace:* + version: link:../../cfdi/csd + '@recreando/eslint-settings': + specifier: workspace:* + version: link:../../../rigs/eslint + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite + '@types/node': + specifier: ^22 + version: 22.19.15 + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/sat/captcha: + devDependencies: + '@recreando/eslint-settings': + specifier: workspace:* + version: link:../../../rigs/eslint + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite + '@types/node': + specifier: ^22 + version: 22.19.15 + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/sat/contabilidad: + devDependencies: + '@recreando/eslint-settings': + specifier: workspace:* + version: link:../../../rigs/eslint + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite + '@types/node': + specifier: ^22 + version: 22.19.15 + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/sat/opinion: + devDependencies: + '@recreando/eslint-settings': + specifier: workspace:* + version: link:../../../rigs/eslint + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite + '@types/node': + specifier: ^22 + version: 22.19.15 + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/sat/recursos: + devDependencies: + '@recreando/eslint-settings': + specifier: workspace:* + version: link:../../../rigs/eslint + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite + '@types/node': + specifier: ^22 + version: 22.19.15 + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 + tsx: + specifier: ^4.7.0 + version: 4.21.0 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/sat/scraper: + devDependencies: + '@recreando/eslint-settings': + specifier: workspace:* + version: link:../../../rigs/eslint + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../../../rigs/typescript + '@recreando/vite': + specifier: workspace:* + version: link:../../../rigs/vite + '@types/node': + specifier: ^22 + version: 22.19.15 + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + eslint: + specifier: ^8.57.0 + version: 8.57.1 + typescript: + specifier: ^5.6.3 + version: 5.8.2 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + + ../../packages/server: + dependencies: + '@cfdi/2json': + specifier: workspace:* + version: link:../cfdi/xml2json + '@cfdi/catalogos': + specifier: workspace:* + version: link:../cfdi/catalogos + '@cfdi/designs': + specifier: workspace:* + version: link:../cfdi/designs + '@cfdi/pdf': + specifier: workspace:* + version: link:../cfdi/pdf + '@cfdi/schema': + specifier: workspace:* + version: link:../cfdi/schema + '@cfdi/utils': + specifier: workspace:* + version: link:../cfdi/utils + next: + specifier: 15.2.3 + version: 15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + react: + specifier: ^19.0.0 + version: 19.0.0 + react-dom: + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + '@tailwindcss/postcss': + specifier: ^4 + version: 4.0.9 + '@types/node': + specifier: ^22 + version: 22.19.15 + '@types/react': + specifier: ^19 + version: 19.0.10 + '@types/react-dom': + specifier: ^19 + version: 19.0.4(@types/react@19.0.10) + eslint: + specifier: ^9 + version: 9.21.0(jiti@2.4.2) + eslint-config-next: + specifier: 15.2.1 + version: 15.2.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2) + tailwindcss: + specifier: ^4 + version: 4.0.9 + typescript: + specifier: ^5 + version: 5.7.2 - '@adobe/css-tools@4.4.0': - resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==} + ../../rigs/eslint: + dependencies: + '@typescript-eslint/eslint-plugin': + specifier: ^8.13.0 + version: 8.13.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/parser': + specifier: ^8.13.0 + version: 8.13.0(eslint@8.57.1)(typescript@5.6.3) + eslint-config-prettier: + specifier: ^8.5.0 + version: 8.10.0(eslint@8.57.1) + eslint-import-resolver-typescript: + specifier: ^2.7.1 + version: 2.7.1(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: + specifier: ^2.26.0 + version: 2.31.0(eslint@8.57.1) + eslint-plugin-jest: + specifier: ^28.9.0 + version: 28.9.0(@typescript-eslint/eslint-plugin@8.13.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@28.1.3)(typescript@5.6.3) + eslint-plugin-jsdoc: + specifier: ^39.2.6 + version: 39.9.1(eslint@8.57.1) + eslint-plugin-jsx-a11y: + specifier: ^6.5.1 + version: 6.10.0(eslint@8.57.1) + eslint-plugin-prettier: + specifier: ^4.0.0 + version: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + eslint-plugin-sort-destructure-keys: + specifier: ^1.4.0 + version: 1.6.0(eslint@8.57.1) + prettier: + specifier: ^2.6.2 + version: 2.8.8 + stylelint: + specifier: ^13.13.1 + version: 13.13.1 + stylelint-config-recommended: + specifier: ^5.0.0 + version: 5.0.0(stylelint@13.13.1) + stylelint-order: + specifier: ^4.1.0 + version: 4.1.0(stylelint@13.13.1) + devDependencies: + eslint: + specifier: ^8.57.0 + version: 8.57.1 + typescript: + specifier: ^5.6.3 + version: 5.6.3 + + ../../rigs/jest: + devDependencies: + '@babel/core': + specifier: ^7.17.9 + version: 7.25.8(supports-color@9.4.0) + '@babel/preset-env': + specifier: ^7.17.10 + version: 7.25.8(@babel/core@7.25.8) + '@recreando/typescript-settings': + specifier: workspace:* + version: link:../typescript + '@types/jest': + specifier: ^27.5.0 + version: 27.5.2 + '@types/node': + specifier: ^18.11.3 + version: 18.19.57 + '@types/testing-library__jest-dom': + specifier: ^5.9.1 + version: 5.14.9 + babel-jest: + specifier: ^28.1.0 + version: 28.1.3(@babel/core@7.25.8) + babel-plugin-transform-import-meta: + specifier: ^2.1.1 + version: 2.2.1(@babel/core@7.25.8) + fetch-mock-jest: + specifier: ^1.5.1 + version: 1.5.1(node-fetch@2.7.0) + identity-obj-proxy: + specifier: ^3.0.0 + version: 3.0.0 + jest: + specifier: ^28.1.2 + version: 28.1.3(@types/node@18.19.57) + jest-environment-jsdom: + specifier: ^28.1.0 + version: 28.1.3 + jest-light-runner: + specifier: ^0.2.1 + version: 0.2.2(jest@28.1.3(@types/node@18.19.57)) + jest-watch-typeahead: + specifier: ^1.0.0 + version: 1.1.0(jest@28.1.3(@types/node@18.19.57)) + ts-jest: + specifier: ^28.0.3 + version: 28.0.8(@babel/core@7.25.8)(@jest/types@28.1.3)(babel-jest@28.1.3(@babel/core@7.25.8))(jest@28.1.3(@types/node@18.19.57))(typescript@5.6.3) + ts-loader: + specifier: 9.2.6 + version: 9.2.6(typescript@5.6.3)(webpack@5.95.0) + tsconfig-paths-webpack-plugin: + specifier: ^3.5.2 + version: 3.5.2 + typescript: + specifier: ^5.6.3 + version: 5.6.3 + webpack: + specifier: ^5.72.0 + version: 5.95.0 + + ../../rigs/typescript: + dependencies: + tsconfig-paths: + specifier: ^4.0.0 + version: 4.2.0 + typescript: + specifier: ^5.6.3 + version: 5.6.3 + + ../../rigs/vite: + dependencies: + vite: + specifier: ^7.0.0 + version: 7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0) + vite-plugin-dts: + specifier: ^4.5.3 + version: 4.5.3(@types/node@22.19.15)(rollup@4.59.0)(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) + devDependencies: + '@vitest/coverage-v8': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + '@vitest/ui': + specifier: 2.1.3 + version: 2.1.3(vitest@2.1.3) + typescript: + specifier: ^5.6.3 + version: 5.6.3 + vite-tsconfig-paths: + specifier: ~4.2.1 + version: 4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + +packages: + + 2captcha@3.0.7: + resolution: {integrity: sha512-i7iswxBsNzzFxQCebgdowHW61UK34+o8KaDonJxRH+gDDeQsiN/3uK0X/fo4AmMTE26c4VSHVe0X8b8CVVNZiw==} + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} @@ -1769,11 +1440,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.0.3': - resolution: {integrity: sha512-dULDd/APiP4JowYDAMosecKOi/1v+UId99qhBGiO3myM29KtAVKS/R3x3OJJNBR0FeYB1BcYb2dCwkhqvxWXXQ==} - peerDependencies: - '@babel/core': ^7.4.0-0 - '@babel/helper-define-polyfill-provider@0.6.2': resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} peerDependencies: @@ -1880,13 +1546,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-proposal-class-properties@7.18.6': - resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} @@ -1936,12 +1595,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.25.7': - resolution: {integrity: sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4': resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: @@ -2320,10 +1973,8 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@cnakazawa/watch@1.0.4': - resolution: {integrity: sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==} - engines: {node: '>=0.1.95'} - hasBin: true + '@emnapi/runtime@1.3.1': + resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} '@es-joy/jsdoccomment@0.36.1': resolution: {integrity: sha512-922xqFsTpHs6D0BUiG4toiyPOMc8/jafnWKxz1KWgS4XzKPy2qXf1Pe6UFuNSCQqt6tOuhAWXBNuuyUhJmw9Vg==} @@ -2335,22 +1986,22 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} - cpu: [arm] + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + engines: {node: '>=18'} + cpu: [arm64] os: [android] '@esbuild/android-arm@0.21.5': @@ -2359,10 +2010,10 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + engines: {node: '>=18'} + cpu: [arm] os: [android] '@esbuild/android-x64@0.21.5': @@ -2371,11 +2022,11 @@ packages: cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} @@ -2383,10 +2034,10 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + engines: {node: '>=18'} + cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.21.5': @@ -2395,11 +2046,11 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} @@ -2407,10 +2058,10 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + engines: {node: '>=18'} + cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.21.5': @@ -2419,11 +2070,11 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} @@ -2431,10 +2082,10 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} - cpu: [arm] + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + engines: {node: '>=18'} + cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.21.5': @@ -2443,10 +2094,10 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + engines: {node: '>=18'} + cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.21.5': @@ -2455,16 +2106,10 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.14.54': - resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + engines: {node: '>=18'} + cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.21.5': @@ -2473,10 +2118,10 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + engines: {node: '>=18'} + cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.21.5': @@ -2485,10 +2130,10 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + engines: {node: '>=18'} + cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.21.5': @@ -2497,10 +2142,10 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} - cpu: [riscv64] + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + engines: {node: '>=18'} + cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.21.5': @@ -2509,10 +2154,10 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} - cpu: [s390x] + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + engines: {node: '>=18'} + cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.21.5': @@ -2521,10 +2166,10 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + engines: {node: '>=18'} + cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.21.5': @@ -2533,10 +2178,16 @@ packages: cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + engines: {node: '>=18'} cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + engines: {node: '>=18'} + cpu: [arm64] os: [netbsd] '@esbuild/netbsd-x64@0.21.5': @@ -2545,10 +2196,16 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + engines: {node: '>=18'} cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + engines: {node: '>=18'} + cpu: [arm64] os: [openbsd] '@esbuild/openbsd-x64@0.21.5': @@ -2557,11 +2214,17 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + engines: {node: '>=18'} cpu: [x64] - os: [sunos] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} @@ -2569,11 +2232,11 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} @@ -2581,10 +2244,10 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + engines: {node: '>=18'} + cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.21.5': @@ -2593,10 +2256,10 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + engines: {node: '>=18'} + cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.21.5': @@ -2605,6 +2268,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2615,14 +2284,38 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@eslint/config-array@0.19.2': + resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.12.0': + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@3.3.0': + resolution: {integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@8.57.1': resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/js@9.21.0': + resolution: {integrity: sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.7': + resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@esm2cjs/execa@6.1.1-cjs.1': resolution: {integrity: sha512-FHxfnmuDIjY1VS/BLzDkL8EkbcFvi8s6x1nYQ1Nyu0An0n88EJcGhDBcRWLFwt3C3nT7xwI+MwHRH1TZcAFW2w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2655,6 +2348,26 @@ packages: resolution: {integrity: sha512-o41riCGPiOEStayoikBCAqwa6igbv9L9rP+k5UCfQ24EJD/wGrdDs/KTNwkHG5JzDK3T60D5dMkWkLKEPy8gjA==} engines: {node: '>=12'} + '@foliojs-fork/fontkit@1.9.2': + resolution: {integrity: sha512-IfB5EiIb+GZk+77TRB86AHroVaqfq8JRFlUbz0WEwsInyCG0epX2tCPOy+UfaWPju30DeVoUAXfzWXmhn753KA==} + + '@foliojs-fork/linebreak@1.1.2': + resolution: {integrity: sha512-ZPohpxxbuKNE0l/5iBJnOAfUaMACwvUIKCvqtWGKIMv1lPYoNjYXRfhi9FeeV9McBkBLxsMFWTVVhHJA8cyzvg==} + + '@foliojs-fork/pdfkit@0.15.3': + resolution: {integrity: sha512-Obc0Wmy3bm7BINFVvPhcl2rnSSK61DQrlHU8aXnAqDk9LCjWdUOPwhgD8Ywz5VtuFjRxmVOM/kQ/XLIBjDvltw==} + + '@foliojs-fork/restructure@2.0.2': + resolution: {integrity: sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + '@humanwhocodes/config-array@0.13.0': resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} @@ -2668,6 +2381,119 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.2': + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} + engines: {node: '>=18.18'} + + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -2680,22 +2506,10 @@ packages: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} - '@jest/console@25.5.0': - resolution: {integrity: sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==} - engines: {node: '>= 8.3'} - '@jest/console@28.1.3': resolution: {integrity: sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/console@29.7.0': - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/core@25.5.4': - resolution: {integrity: sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==} - engines: {node: '>= 8.3'} - '@jest/core@28.1.3': resolution: {integrity: sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -2705,71 +2519,26 @@ packages: node-notifier: optional: true - '@jest/core@29.5.0': - resolution: {integrity: sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - '@jest/environment@25.5.0': - resolution: {integrity: sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==} - engines: {node: '>= 8.3'} - '@jest/environment@28.1.3': resolution: {integrity: sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/environment@29.7.0': - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jest/expect-utils@28.1.3': resolution: {integrity: sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/expect-utils@29.7.0': - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jest/expect@28.1.3': resolution: {integrity: sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/expect@29.7.0': - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/fake-timers@25.5.0': - resolution: {integrity: sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==} - engines: {node: '>= 8.3'} - '@jest/fake-timers@28.1.3': resolution: {integrity: sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/fake-timers@29.7.0': - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/globals@25.5.2': - resolution: {integrity: sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==} - engines: {node: '>= 8.3'} - '@jest/globals@28.1.3': resolution: {integrity: sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/globals@29.7.0': - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/reporters@25.5.1': - resolution: {integrity: sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==} - engines: {node: '>= 8.3'} - '@jest/reporters@28.1.3': resolution: {integrity: sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -2779,87 +2548,30 @@ packages: node-notifier: optional: true - '@jest/reporters@29.5.0': - resolution: {integrity: sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - '@jest/schemas@28.1.3': resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/source-map@25.5.0': - resolution: {integrity: sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==} - engines: {node: '>= 8.3'} - '@jest/source-map@28.1.2': resolution: {integrity: sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/source-map@29.6.3': - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-result@25.5.0': - resolution: {integrity: sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==} - engines: {node: '>= 8.3'} - '@jest/test-result@28.1.3': resolution: {integrity: sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/test-result@29.7.0': - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-sequencer@25.5.4': - resolution: {integrity: sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==} - engines: {node: '>= 8.3'} - '@jest/test-sequencer@28.1.3': resolution: {integrity: sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/test-sequencer@29.7.0': - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/transform@25.5.1': - resolution: {integrity: sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==} - engines: {node: '>= 8.3'} - '@jest/transform@28.1.3': resolution: {integrity: sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/transform@29.5.0': - resolution: {integrity: sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/transform@29.7.0': - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/types@25.5.0': - resolution: {integrity: sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==} - engines: {node: '>= 8.3'} - '@jest/types@28.1.3': resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jest/types@29.6.3': - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -2881,23 +2593,72 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@jsep-plugin/assignment@1.3.0': - resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==} - engines: {node: '>= 10.16.0'} - peerDependencies: - jsep: ^0.4.0||^1.0.0 + '@microsoft/api-extractor-model@7.30.4': + resolution: {integrity: sha512-RobC0gyVYsd2Fao9MTKOfTdBm41P/bCMUmzS5mQ7/MoAKEqy0FOBph3JOYdq4X4BsEnMEiSHc+0NUNmdzxCpjA==} - '@jsep-plugin/regex@1.0.4': - resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==} - engines: {node: '>= 10.16.0'} - peerDependencies: - jsep: ^0.4.0||^1.0.0 + '@microsoft/api-extractor@7.52.1': + resolution: {integrity: sha512-m3I5uAwE05orsu3D1AGyisX5KxsgVXB+U4bWOOaX/Z7Ftp/2Cy41qsNhO6LPvSxHBaapyser5dVorF1t5M6tig==} + hasBin: true + + '@microsoft/tsdoc-config@0.17.1': + resolution: {integrity: sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==} + + '@microsoft/tsdoc@0.15.1': + resolution: {integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==} + + '@next/env@15.2.3': + resolution: {integrity: sha512-a26KnbW9DFEUsSxAxKBORR/uD9THoYoKbkpFywMN/AFvboTt94b8+g/07T8J6ACsdLag8/PDU60ov4rPxRAixw==} + + '@next/eslint-plugin-next@15.2.1': + resolution: {integrity: sha512-6ppeToFd02z38SllzWxayLxjjNfzvc7Wm07gQOKSLjyASvKcXjNStZrLXMHuaWkhjqxe+cnhb2uzfWXm1VEj/Q==} + + '@next/swc-darwin-arm64@15.2.3': + resolution: {integrity: sha512-uaBhA8aLbXLqwjnsHSkxs353WrRgQgiFjduDpc7YXEU0B54IKx3vU+cxQlYwPCyC8uYEEX7THhtQQsfHnvv8dw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.2.3': + resolution: {integrity: sha512-pVwKvJ4Zk7h+4hwhqOUuMx7Ib02u3gDX3HXPKIShBi9JlYllI0nU6TWLbPT94dt7FSi6mSBhfc2JrHViwqbOdw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.2.3': + resolution: {integrity: sha512-50ibWdn2RuFFkOEUmo9NCcQbbV9ViQOrUfG48zHBCONciHjaUKtHcYFiCwBVuzD08fzvzkWuuZkd4AqbvKO7UQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.2.3': + resolution: {integrity: sha512-2gAPA7P652D3HzR4cLyAuVYwYqjG0mt/3pHSWTCyKZq/N/dJcUAEoNQMyUmwTZWCJRKofB+JPuDVP2aD8w2J6Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.2.3': + resolution: {integrity: sha512-ODSKvrdMgAJOVU4qElflYy1KSZRM3M45JVbeZu42TINCMG3anp7YCBn80RkISV6bhzKwcUqLBAmOiWkaGtBA9w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.2.3': + resolution: {integrity: sha512-ZR9kLwCWrlYxwEoytqPi1jhPd1TlsSJWAc+H/CJHmHkf2nD92MQpSRIURR1iNgA/kuFSdxB8xIPt4p/T78kwsg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] - '@microsoft/tsdoc-config@0.17.0': - resolution: {integrity: sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==} + '@next/swc-win32-arm64-msvc@15.2.3': + resolution: {integrity: sha512-+G2FrDcfm2YDbhDiObDU/qPriWeiz/9cRR0yMWJeTLGGX6/x8oryO3tt7HhodA1vZ8r2ddJPCjtLcpaVl7TE2Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] - '@microsoft/tsdoc@0.15.0': - resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==} + '@next/swc-win32-x64-msvc@15.2.3': + resolution: {integrity: sha512-gHYS9tc+G2W0ZC8rBL+H6RdtXIyk40uLiaos0yj5US85FNhbFEndMA2nW3z47nzOWiSvXTZ5kBClc3rD0zJg0w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -2911,6 +2672,10 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -2918,183 +2683,166 @@ packages: '@polka/url@1.0.0-next.28': resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} - '@rollup/plugin-babel@5.3.1': - resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} - engines: {node: '>= 10.0.0'} + '@rollup/plugin-terser@0.4.4': + resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} + engines: {node: '>=14.0.0'} peerDependencies: - '@babel/core': ^7.0.0 - '@types/babel__core': ^7.1.9 - rollup: ^1.20.0||^2.0.0 + rollup: ^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: - '@types/babel__core': + rollup: optional: true - '@rollup/plugin-commonjs@11.1.0': - resolution: {integrity: sha512-Ycr12N3ZPN96Fw2STurD21jMqzKwL9QuFhms3SD7KKRK7oaXUsBU9Zt0jL/rOPHiPYisI21/rXGO3jr9BnLHUA==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - - '@rollup/plugin-json@4.1.0': - resolution: {integrity: sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==} - peerDependencies: - rollup: ^1.20.0 || ^2.0.0 - - '@rollup/plugin-node-resolve@9.0.0': - resolution: {integrity: sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg==} - engines: {node: '>= 10.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - - '@rollup/plugin-replace@2.4.2': - resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} + '@rollup/plugin-url@8.0.2': + resolution: {integrity: sha512-5yW2LP5NBEgkvIRSSEdJkmxe5cUNZKG3eenKtfJvSkxVm/xTTu7w+ayBtNwhozl1ZnTUCU0xFaRQR+cBl2H7TQ==} + engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0 || ^2.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true - '@rollup/pluginutils@3.1.0': - resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} - engines: {node: '>= 8.0.0'} + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true - '@rollup/rollup-android-arm-eabi@4.24.0': - resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.24.0': - resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.24.0': - resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.24.0': - resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.24.0': - resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.24.0': - resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.24.0': - resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.24.0': - resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': - resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.24.0': - resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.24.0': - resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.24.0': - resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.24.0': - resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.24.0': - resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.24.0': - resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.24.0': - resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} cpu: [x64] os: [win32] '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@rushstack/eslint-config@4.0.2': - resolution: {integrity: sha512-RFLynEk5hiGjgzFKephENrBWZZfoQe+3e76Q78KXjeGsndbaZXDHy0OxLfZethlEutDQEDiE3vpkbJ1mfcMeGg==} - peerDependencies: - eslint: ^8.57.0 - typescript: '>=4.7.0' - '@rushstack/eslint-patch@1.10.4': resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==} - '@rushstack/eslint-plugin-packlets@0.9.2': - resolution: {integrity: sha512-rZofSLJpwyP7Xo6e4eKYkI7N4JM5PycvPuoX5IEK08PgxPDm/k5pdltH9DkIKnmWvLrxIMU+85VrB5xnjbK0RQ==} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - - '@rushstack/eslint-plugin-security@0.8.3': - resolution: {integrity: sha512-2l6bSIyTgaejiRPiFCsons/HA8sS7bKhmL/RHdAZo54jm/W/Xqb4zaFn4+OuMCNLASQhqXMc8FeYPF0V7t1Aow==} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - - '@rushstack/eslint-plugin@0.16.1': - resolution: {integrity: sha512-e+VVtwBvuGqvVCcXUDTireQFfaIncmlD6rOBils0BeGkrLbP1r330/AFcRoYQEZUZpdhVxFtJrIq48HIlWBFzA==} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - - '@rushstack/heft-config-file@0.15.8': - resolution: {integrity: sha512-qIhNBEwAZ+Ceh/axEbW4UoUP5F/hzzmjkYFZZuKQd91LWcWKKVriiy0izcx5uYMIJEtm5F0JhS/OUykO0xEpLg==} - engines: {node: '>=10.13.0'} - - '@rushstack/heft-jest-plugin@0.12.18': - resolution: {integrity: sha512-aHtHIdQiW7uxihUvc2SicfCfKEGGkxm9+qjMvktCn3m/f0GBP7aAGByuJR1+aJM4oO9HnUeRpI4hqD0QXBcVyg==} - peerDependencies: - '@rushstack/heft': ^0.68.6 - jest-environment-jsdom: ^29.5.0 - jest-environment-node: ^29.5.0 - peerDependenciesMeta: - jest-environment-jsdom: - optional: true - jest-environment-node: - optional: true - - '@rushstack/heft@0.68.6': - resolution: {integrity: sha512-effhdx7MzVQqVms1Fwh7Ey9qsBJ2y47+PTv3qM2fh+M/mprKDL6iex6Mnb6KwkN3C8f744dTXHxNKdF3+6fOnQ==} - engines: {node: '>=10.13.0'} - hasBin: true - - '@rushstack/node-core-library@5.9.0': - resolution: {integrity: sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==} - peerDependencies: - '@types/node': '*' - peerDependenciesMeta: - '@types/node': - optional: true - - '@rushstack/operation-graph@0.2.33': - resolution: {integrity: sha512-bokTOAt8jNAMiMZuMs83GXK4GkfAVbj3mx7g0hYuyqTVw7M/EgJO7eL2S/WjqyLxljwHL3cesXSY+csvhbbggA==} + '@rushstack/node-core-library@5.12.0': + resolution: {integrity: sha512-QSwwzgzWoil1SCQse+yCHwlhRxNv2dX9siPnAb9zR/UmMhac4mjMrlMZpk64BlCeOFi1kJKgXRkihSwRMbboAQ==} peerDependencies: '@types/node': '*' peerDependenciesMeta: @@ -3104,55 +2852,26 @@ packages: '@rushstack/rig-package@0.5.3': resolution: {integrity: sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==} - '@rushstack/terminal@0.14.2': - resolution: {integrity: sha512-2fC1wqu1VCExKC0/L+0noVcFQEXEnoBOtCIex1TOjBzEDWcw8KzJjjj7aTP6mLxepG0XIyn9OufeFb6SFsa+sg==} + '@rushstack/terminal@0.15.1': + resolution: {integrity: sha512-3vgJYwumcjoDOXU3IxZfd616lqOdmr8Ezj4OWgJZfhmiBK4Nh7eWcv8sU8N/HdzXcuHDXCRGn/6O2Q75QvaZMA==} peerDependencies: '@types/node': '*' peerDependenciesMeta: '@types/node': optional: true - '@rushstack/tree-pattern@0.3.4': - resolution: {integrity: sha512-9uROnkiHWsQqxW6HirXABfTRlgzhYp6tevbYIGkwKQ09VaayUBkvFvt/urDKMwlo+tGU0iQQLuVige6c48wTgw==} - - '@rushstack/ts-command-line@4.23.0': - resolution: {integrity: sha512-jYREBtsxduPV6ptNq8jOKp9+yx0ld1Tb/Tkdnlj8gTjazl1sF3DwX2VbluyYrNd0meWIL0bNeer7WDf5tKFjaQ==} + '@rushstack/ts-command-line@4.23.6': + resolution: {integrity: sha512-7WepygaF3YPEoToh4MAL/mmHkiIImQq3/uAkQX46kVoKTNOOlCtFGyNnze6OYuWw2o9rxsyrHVfIBKxq/am2RA==} '@sinclair/typebox@0.24.51': resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@sinonjs/commons@1.8.6': resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==} - '@sinonjs/commons@3.0.1': - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} - - '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - '@sinonjs/fake-timers@9.1.2': resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==} - '@size-limit/esbuild@7.0.8': - resolution: {integrity: sha512-AzCrxJJThDvHrBNoolebYVgXu46c6HuS3fOxoXr3V0YWNM0qz81z5F3j7RruzboZnls8ZgME4WrH6GM5rB9gtA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - peerDependencies: - size-limit: 7.0.8 - - '@size-limit/file@7.0.8': - resolution: {integrity: sha512-1KeFQuMXIXAH/iELqIX7x+YNYDFvzIvmxcp9PrdwEoSNL0dXdaDIo9WE/yz8xvOmUcKaLfqbWkL75DM0k91WHQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - peerDependencies: - size-limit: 7.0.8 - - '@size-limit/preset-small-lib@7.0.8': - resolution: {integrity: sha512-CT8nIYA/c2CSD+X4rAUgwqYccQMahJ6rBnaZxvi3YKFdkXIbuGNXHNjHsYaFksgwG9P4UjG/unyO5L73f3zQBw==} - peerDependencies: - size-limit: 7.0.8 - '@stylelint/postcss-css-in-js@0.37.3': resolution: {integrity: sha512-scLk3cSH1H9KggSniseb2KNAU5D9FWc3H7BxCSAIdtU9OWIyw0zkEZ9qEKHryRM+SExYXRKNb7tOOVNAsQ3iwg==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. @@ -3167,16 +2886,87 @@ packages: postcss: '>=7.0.0' postcss-syntax: '>=0.36.2' - '@swc/helpers@0.3.17': - resolution: {integrity: sha512-tb7Iu+oZ+zWJZ3HJqwx8oNwSDIU440hmVMDPhpACWQWnrZHK99Bxs70gT1L2dnr5Hg50ZRWEFkQCAnOVVV0z1Q==} + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@testing-library/dom@8.20.1': - resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==} - engines: {node: '>=12'} + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tailwindcss/node@4.0.9': + resolution: {integrity: sha512-tOJvdI7XfJbARYhxX+0RArAhmuDcczTC46DGCEziqxzzbIaPnfYaIyRT31n4u8lROrsO7Q6u/K9bmQHL2uL1bQ==} + + '@tailwindcss/oxide-android-arm64@4.0.9': + resolution: {integrity: sha512-YBgy6+2flE/8dbtrdotVInhMVIxnHJPbAwa7U1gX4l2ThUIaPUp18LjB9wEH8wAGMBZUb//SzLtdXXNBHPUl6Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.0.9': + resolution: {integrity: sha512-pWdl4J2dIHXALgy2jVkwKBmtEb73kqIfMpYmcgESr7oPQ+lbcQ4+tlPeVXaSAmang+vglAfFpXQCOvs/aGSqlw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.0.9': + resolution: {integrity: sha512-4Dq3lKp0/C7vrRSkNPtBGVebEyWt9QPPlQctxJ0H3MDyiQYvzVYf8jKow7h5QkWNe8hbatEqljMj/Y0M+ERYJg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.0.9': + resolution: {integrity: sha512-k7U1RwRODta8x0uealtVt3RoWAWqA+D5FAOsvVGpYoI6ObgmnzqWW6pnVwz70tL8UZ/QXjeMyiICXyjzB6OGtQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.9': + resolution: {integrity: sha512-NDDjVweHz2zo4j+oS8y3KwKL5wGCZoXGA9ruJM982uVJLdsF8/1AeKvUwKRlMBpxHt1EdWJSAh8a0Mfhl28GlQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.0.9': + resolution: {integrity: sha512-jk90UZ0jzJl3Dy1BhuFfRZ2KP9wVKMXPjmCtY4U6fF2LvrjP5gWFJj5VHzfzHonJexjrGe1lMzgtjriuZkxagg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.0.9': + resolution: {integrity: sha512-3eMjyTC6HBxh9nRgOHzrc96PYh1/jWOwHZ3Kk0JN0Kl25BJ80Lj9HEvvwVDNTgPg154LdICwuFLuhfgH9DULmg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.0.9': + resolution: {integrity: sha512-v0D8WqI/c3WpWH1kq/HP0J899ATLdGZmENa2/emmNjubT0sWtEke9W9+wXeEoACuGAhF9i3PO5MeyditpDCiWQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.0.9': + resolution: {integrity: sha512-Kvp0TCkfeXyeehqLJr7otsc4hd/BUPfcIGrQiwsTVCfaMfjQZCG7DjI+9/QqPZha8YapLA9UoIcUILRYO7NE1Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-win32-arm64-msvc@4.0.9': + resolution: {integrity: sha512-m3+60T/7YvWekajNq/eexjhV8z10rswcz4BC9bioJ7YaN+7K8W2AmLmG0B79H14m6UHE571qB0XsPus4n0QVgQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.0.9': + resolution: {integrity: sha512-dpc05mSlqkwVNOUjGu/ZXd5U1XNch1kHFJ4/cHkZFvaW1RzbHmRt24gvM8/HC6IirMxNarzVw4IXVtvrOoZtxA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.0.9': + resolution: {integrity: sha512-eLizHmXFqHswJONwfqi/WZjtmWZpIalpvMlNhTM99/bkHtUs6IqgI1XQ0/W5eO2HiRQcIlXUogI2ycvKhVLNcA==} + engines: {node: '>= 10'} - '@testing-library/jest-dom@5.17.0': - resolution: {integrity: sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==} - engines: {node: '>=8', npm: '>=6', yarn: '>=1'} + '@tailwindcss/postcss@4.0.9': + resolution: {integrity: sha512-BT/E+pdMqulavEAVM5NCpxmGEwHiLDPpkmg/c/X25ZBW+izTe+aZ+v1gf/HXTrihRoCxrUp5U4YyHsBTzspQKQ==} '@tootallnate/once@2.0.0': resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} @@ -3185,9 +2975,6 @@ packages: '@types/argparse@1.0.38': resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} - '@types/aria-query@5.0.4': - resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -3200,18 +2987,12 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} - '@types/deep-freeze@0.1.5': - resolution: {integrity: sha512-KZtR+jtmgkCpgE0f+We/QEI2Fi0towBV/tTkvHVhMzx+qhUVGXMx7pWvAtDp6vEWIjdKLTKpqbI/sORRCo8TKg==} - - '@types/eslint-visitor-keys@1.0.0': - resolution: {integrity: sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==} - - '@types/estree@0.0.39': - resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} - '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -3221,15 +3002,9 @@ packages: '@types/istanbul-lib-report@3.0.3': resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - '@types/istanbul-reports@1.1.2': - resolution: {integrity: sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==} - '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - '@types/jest@25.2.3': - resolution: {integrity: sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==} - '@types/jest@27.5.2': resolution: {integrity: sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==} @@ -3254,6 +3029,9 @@ packages: '@types/node@18.19.57': resolution: {integrity: sha512-I2ioBd/IPrYDMv9UNR5NlPElOZ68QB7yY5V2EsLtSrTO0LM0PnCEFF9biLWHf5k+sIy4ohueCV9t4gk1AEdlVA==} + '@types/node@22.19.15': + resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} + '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -3269,30 +3047,23 @@ packages: '@types/pdfkit@0.13.5': resolution: {integrity: sha512-cR4gZA3xiMVDUf/O/ijVr6aIguvN72ZmCDLcWwM0ycqn5P8XDSjMX9PixzWEoDnlINoofxo2LCdV4KvdD9Waqg==} - '@types/pdfmake@0.1.21': - resolution: {integrity: sha512-rDmJr/jzUZSg/AzWYAMVBS4z4weZKTOtrD6Jlt+hzZu87bkIe7WVA02+m+uGGopyTUazFoWYT6HXxwT68Nqfeg==} - - '@types/prettier@1.19.1': - resolution: {integrity: sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==} + '@types/pdfmake@0.2.11': + resolution: {integrity: sha512-gglgMQhnG6C2kco13DJlvokqTxL+XKxHwCejElH8fSCNF9ZCkRK6Mzo011jQ0zuug+YlIgn6BpcpZrARyWdW3Q==} '@types/prettier@2.7.3': resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} - '@types/resolve@1.17.1': - resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} - - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + '@types/react-dom@19.0.4': + resolution: {integrity: sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==} + peerDependencies: + '@types/react': ^19.0.0 - '@types/stack-utils@1.0.1': - resolution: {integrity: sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==} + '@types/react@19.0.10': + resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==} '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - '@types/tapable@1.0.6': - resolution: {integrity: sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==} - '@types/testing-library__jest-dom@5.14.9': resolution: {integrity: sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==} @@ -3305,34 +3076,9 @@ packages: '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@types/yargs@15.0.19': - resolution: {integrity: sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==} - '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@typescript-eslint/eslint-plugin@2.34.0': - resolution: {integrity: sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - '@typescript-eslint/parser': ^2.0.0 - eslint: ^5.0.0 || ^6.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/eslint-plugin@8.1.0': - resolution: {integrity: sha512-LlNBaHFCEBPHyD4pZXb35mzjGkuGKXU5eeCA1SxvHfiRES0E82dOounfVpL4DCqYvJEKab0bZIA0gCRpdLKkCw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/eslint-plugin@8.13.0': resolution: {integrity: sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3344,32 +3090,6 @@ packages: typescript: optional: true - '@typescript-eslint/experimental-utils@2.34.0': - resolution: {integrity: sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - eslint: '*' - - '@typescript-eslint/parser@2.34.0': - resolution: {integrity: sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - eslint: ^5.0.0 || ^6.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/parser@8.1.0': - resolution: {integrity: sha512-U7iTAtGgJk6DPX9wIWPPOlt1gO57097G06gIcl0N0EEnNw8RGD62c+2/DiP/zL7KrkqnnqF7gtFGR7YgzPllTA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/parser@8.13.0': resolution: {integrity: sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3380,27 +3100,10 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@6.19.1': - resolution: {integrity: sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@typescript-eslint/scope-manager@8.1.0': - resolution: {integrity: sha512-DsuOZQji687sQUjm4N6c9xABJa7fjvfIdjqpSIIVOgaENf2jFXiM9hIBZOL3hb6DHK9Nvd2d7zZnoMLf9e0OtQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.13.0': resolution: {integrity: sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.1.0': - resolution: {integrity: sha512-oLYvTxljVvsMnldfl6jIKxTaU7ok7km0KDrwOt1RHYu6nxlhN3TIx8k5Q52L6wR33nOwDgM7VwW1fT1qMNfFIA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/type-utils@8.13.0': resolution: {integrity: sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3410,45 +3113,10 @@ packages: typescript: optional: true - '@typescript-eslint/types@6.19.1': - resolution: {integrity: sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@typescript-eslint/types@8.1.0': - resolution: {integrity: sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.13.0': resolution: {integrity: sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@2.34.0': - resolution: {integrity: sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/typescript-estree@6.19.1': - resolution: {integrity: sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/typescript-estree@8.1.0': - resolution: {integrity: sha512-NTHhmufocEkMiAord/g++gWKb0Fr34e9AExBRdqgWdVBaKoei2dIyYKD9Q0jBnvfbEA5zaf8plUFMUH6kQ0vGg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/typescript-estree@8.13.0': resolution: {integrity: sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3458,32 +3126,12 @@ packages: typescript: optional: true - '@typescript-eslint/utils@6.19.1': - resolution: {integrity: sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - - '@typescript-eslint/utils@8.1.0': - resolution: {integrity: sha512-ypRueFNKTIFwqPeJBfeIpxZ895PQhNyH4YID6js0UoBImWYoSjBsahUn9KMiJXh94uOjVBgHD9AmkyPsPnFwJA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/utils@8.13.0': resolution: {integrity: sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/visitor-keys@6.19.1': - resolution: {integrity: sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==} - engines: {node: ^16.0.0 || >=18.0.0} - - '@typescript-eslint/visitor-keys@8.1.0': - resolution: {integrity: sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.13.0': resolution: {integrity: sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3534,6 +3182,35 @@ packages: '@vitest/utils@2.1.3': resolution: {integrity: sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==} + '@volar/language-core@2.4.12': + resolution: {integrity: sha512-RLrFdXEaQBWfSnYGVxvR2WrO6Bub0unkdHYIdC31HzIEqATIuuhRRzYu76iGPZ6OtA4Au1SnW0ZwIqPP217YhA==} + + '@volar/source-map@2.4.12': + resolution: {integrity: sha512-bUFIKvn2U0AWojOaqf63ER0N/iHIBYZPpNGogfLPQ68F5Eet6FnLlyho7BS0y2HJ1jFhSif7AcuTx1TqsCzRzw==} + + '@volar/typescript@2.4.12': + resolution: {integrity: sha512-HJB73OTJDgPc80K30wxi3if4fSsZZAOScbj2fcicMuOPoOkcf9NNAINb33o+DzhBdF9xTKC1gnPmIRDous5S0g==} + + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + + '@vue/language-core@2.2.0': + resolution: {integrity: sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + '@webassemblyjs/ast@1.12.1': resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} @@ -3589,9 +3266,6 @@ packages: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} deprecated: Use your platform's native atob() and btoa() methods instead - acorn-globals@4.3.4: - resolution: {integrity: sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==} - acorn-globals@6.0.0: resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} @@ -3605,19 +3279,10 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@6.2.0: - resolution: {integrity: sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==} - engines: {node: '>=0.4.0'} - acorn-walk@7.2.0: resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} engines: {node: '>=0.4.0'} - acorn@6.4.2: - resolution: {integrity: sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==} - engines: {node: '>=0.4.0'} - hasBin: true - acorn@7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} @@ -3665,26 +3330,13 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - - ansi-escapes@3.2.0: - resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} - engines: {node: '>=4'} + alien-signals@0.4.14: + resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==} ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} - ansi-regex@3.0.1: - resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} - engines: {node: '>=4'} - - ansi-regex@4.1.1: - resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} - engines: {node: '>=6'} - ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -3709,45 +3361,23 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - anymatch@2.0.0: - resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} - anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - aria-query@5.1.3: - resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} - - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} - - arr-diff@4.0.0: - resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} - engines: {node: '>=0.10.0'} + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - arr-flatten@1.1.0: - resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} - engines: {node: '>=0.10.0'} + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - arr-union@3.1.0: - resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} - engines: {node: '>=0.10.0'} + aria-query@5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} - array-equal@1.0.2: - resolution: {integrity: sha512-gUHx76KtnhEgB3HOuFYiCm3FIdEs6ocM2asHvNTkfu/Y09qQVrrVVaOKENmS2KkSaGoxgXNqC+ZVtR/n0MOkSA==} - array-includes@3.1.8: resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} engines: {node: '>= 0.4'} @@ -3756,10 +3386,6 @@ packages: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - array-unique@0.3.2: - resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} - engines: {node: '>=0.10.0'} - array.prototype.findlast@1.2.5: resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} engines: {node: '>= 0.4'} @@ -3788,28 +3414,13 @@ packages: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - - assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - assign-symbols@1.0.0: - resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} - engines: {node: '>=0.10.0'} - ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - astral-regex@1.0.0: - resolution: {integrity: sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==} - engines: {node: '>=4'} - astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -3817,21 +3428,6 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - asyncro@3.0.0: - resolution: {integrity: sha512-nEnWYfrBmA3taTiuiOoZYmgJ/CNrSoQLeLs29SeLcPu60yaw/mHDBHV0iOZ051fTvsTHxpCY+gXibqT9wbQYfg==} - - at-least-node@1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} - - atob-lite@2.0.0: - resolution: {integrity: sha512-LEeSAWeh2Gfa2FtlQE1shxQ8zi5F9GHarrGKz08TMdODD5T4eH6BMsvtnhbWZ+XQn+Gb6om/917ucvRu7l7ukw==} - - atob@2.1.2: - resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} - engines: {node: '>= 4.5.0'} - hasBin: true - autoprefixer@9.8.8: resolution: {integrity: sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==} hasBin: true @@ -3840,12 +3436,6 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - aws-sign2@0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - - aws4@1.13.2: - resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} - axe-core@4.10.1: resolution: {integrity: sha512-qPC9o+kD8Tir0lzNGLeghbOrWMr3ZJpaRlCIb6Uobt/7N4FiEDvqUMnxzCHRHmg8vOg14kr5gVNyScRmbMaJ9g==} engines: {node: '>=4'} @@ -3857,60 +3447,20 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - babel-eslint@10.1.0: - resolution: {integrity: sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==} - engines: {node: '>=6'} - deprecated: babel-eslint is now @babel/eslint-parser. This package will no longer receive updates. - peerDependencies: - eslint: '>= 4.12.1' - - babel-jest@25.5.1: - resolution: {integrity: sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==} - engines: {node: '>= 8.3'} - peerDependencies: - '@babel/core': ^7.0.0 - babel-jest@28.1.3: resolution: {integrity: sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} peerDependencies: '@babel/core': ^7.8.0 - babel-jest@29.7.0: - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - - babel-plugin-annotate-pure-calls@0.4.0: - resolution: {integrity: sha512-oi4M/PWUJOU9ZyRGoPTfPMqdyMp06jbJAomd3RcyYuzUtBOddv98BqLm96Lucpi2QFoQHkdGQt0ACvw7VzVEQA==} - peerDependencies: - '@babel/core': ^6.0.0-0 || 7.x - - babel-plugin-dev-expression@0.2.3: - resolution: {integrity: sha512-rP5LK9QQTzCW61nVVzw88En1oK8t8gTsIeC6E61oelxNsU842yMjF0G1MxhvUpCkxCEIj7sE8/e5ieTheT//uw==} - peerDependencies: - '@babel/core': ^7.0.0 - babel-plugin-istanbul@6.1.1: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} - babel-plugin-jest-hoist@25.5.0: - resolution: {integrity: sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==} - engines: {node: '>= 8.3'} - babel-plugin-jest-hoist@28.1.3: resolution: {integrity: sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - babel-plugin-macros@2.8.0: - resolution: {integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==} - babel-plugin-polyfill-corejs2@0.4.11: resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} peerDependencies: @@ -3921,11 +3471,6 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.0.4: - resolution: {integrity: sha512-+/uCzO9JTYVZVGCpZpVAQkgPGt2zkR0VYiZvJ4aVoCe4ccgpKvNQqcjzAgQzSsjK64Jhc5hvrCR3l0087BevkA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - babel-plugin-polyfill-regenerator@0.6.2: resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} peerDependencies: @@ -3936,37 +3481,17 @@ packages: peerDependencies: '@babel/core': ^7.10.0 - babel-plugin-transform-rename-import@2.3.0: - resolution: {integrity: sha512-dPgJoT57XC0PqSnLgl2FwNvxFrWlspatX2dkk7yjKQj5HHGw071vAcOf+hqW8ClqcBDMvEbm6mevn5yHAD8mlQ==} - - babel-preset-current-node-syntax@0.1.4: - resolution: {integrity: sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==} - peerDependencies: - '@babel/core': ^7.0.0 - babel-preset-current-node-syntax@1.1.0: resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} peerDependencies: '@babel/core': ^7.0.0 - babel-preset-jest@25.5.0: - resolution: {integrity: sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==} - engines: {node: '>= 8.3'} - peerDependencies: - '@babel/core': ^7.0.0 - babel-preset-jest@28.1.3: resolution: {integrity: sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} peerDependencies: '@babel/core': ^7.0.0 - babel-preset-jest@29.6.3: - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - bail@1.0.5: resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} @@ -3976,34 +3501,18 @@ packages: balanced-match@2.0.0: resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} - base64-js@0.0.8: - resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} - engines: {node: '>= 0.4'} + base64-js@1.3.1: + resolution: {integrity: sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - base@0.11.2: - resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} - engines: {node: '>=0.10.0'} - - bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@2.3.2: - resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} - engines: {node: '>=0.10.0'} - braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -4014,9 +3523,6 @@ packages: browser-process-hrtime@1.0.0: resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} - browser-resolve@1.11.3: - resolution: {integrity: sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==} - browserslist@4.24.0: resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -4032,22 +3538,14 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - - bytes-iec@3.1.1: - resolution: {integrity: sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==} - engines: {node: '>= 0.8'} + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - cache-base@1.0.1: - resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} - engines: {node: '>=0.10.0'} - call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -4071,13 +3569,6 @@ packages: caniuse-lite@1.0.30001669: resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} - capture-exit@2.0.0: - resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==} - engines: {node: 6.* || 8.* || >= 10.*} - - caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - chai@5.1.1: resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} engines: {node: '>=12'} @@ -4086,10 +3577,6 @@ packages: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} - chalk@3.0.0: - resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} - engines: {node: '>=8'} - chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -4111,60 +3598,23 @@ packages: character-reference-invalid@1.1.4: resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} - chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - chrome-trace-event@1.0.4: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} - ci-info@2.0.0: - resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} - ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - ci-job-number@1.2.2: - resolution: {integrity: sha512-CLOGsVDrVamzv8sXJGaILUVI6dsuAkouJP/n6t+OxLPeeA4DDby7zn9SB6EUpa1H7oIKoE+rMmkW80zYsFfUjA==} - cjs-module-lexer@1.4.1: resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==} - class-utils@0.3.6: - resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} - engines: {node: '>=0.10.0'} - - cli-cursor@2.1.0: - resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} - engines: {node: '>=4'} - - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@1.3.1: - resolution: {integrity: sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==} - engines: {node: '>=4'} - - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - - cli-width@3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} - - cliui@6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} @@ -4189,10 +3639,6 @@ packages: collect-v8-coverage@1.0.2: resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} - collection-visit@1.0.0: - resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} - engines: {node: '>=0.10.0'} - color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -4206,6 +3652,13 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -4217,17 +3670,17 @@ packages: resolution: {integrity: sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==} engines: {node: '>= 12.0.0'} - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - - component-emitter@1.3.1: - resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - confusing-browser-globals@1.0.11: - resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.1: + resolution: {integrity: sha512-hkT3yDPFbs95mNCy1+7qNKC6Pro+/ibzYxtM2iqEigpf0sVw+bg4Zh9/snjsBcf990vfIsg5+1U7VyiyBb3etg==} convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} @@ -4235,44 +3688,30 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - copy-descriptor@0.1.1: - resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} - engines: {node: '>=0.10.0'} - core-js-compat@3.38.1: resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} core-js@3.38.1: resolution: {integrity: sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==} - core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cosmiconfig@6.0.0: - resolution: {integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==} - engines: {node: '>=8'} - cosmiconfig@7.1.0: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} - cross-spawn@6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} - engines: {node: '>=4.8'} - cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} - css.escape@1.5.1: - resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} - cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -4281,9 +3720,6 @@ packages: cssom@0.3.8: resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} - cssom@0.4.4: - resolution: {integrity: sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==} - cssom@0.5.0: resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} @@ -4291,23 +3727,15 @@ packages: resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} engines: {node: '>=8'} - curp@1.2.3: - resolution: {integrity: sha512-o/NZE+1A1y77orlN8kBRa4+yG4m1owVI9V2KzEpHDV1z2k90rPCHuECYmXLyW4bcYOHdTf36EJuz6KWLn/hyKg==} - engines: {npm: '>= 8.0.0'} + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - dashdash@1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} - data-uri-to-buffer@1.2.0: resolution: {integrity: sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==} - data-urls@1.1.0: - resolution: {integrity: sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==} - data-urls@3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} engines: {node: '>=12'} @@ -4324,6 +3752,9 @@ packages: resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} engines: {node: '>= 0.4'} + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} @@ -4339,6 +3770,15 @@ packages: supports-color: optional: true + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} engines: {node: '>=0.10.0'} @@ -4350,21 +3790,9 @@ packages: decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - decode-uri-component@0.2.2: - resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} - engines: {node: '>=0.10'} - dedent@0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} - dedent@1.5.3: - resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - deep-eql@4.1.4: resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} engines: {node: '>=6'} @@ -4373,6 +3801,10 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} + deep-equal@1.1.2: + resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} + engines: {node: '>= 0.4'} + deep-equal@2.2.3: resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} engines: {node: '>= 0.4'} @@ -4384,9 +3816,6 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -4395,22 +3824,19 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - define-property@0.2.5: - resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} - engines: {node: '>=0.10.0'} - - define-property@1.0.0: - resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} - engines: {node: '>=0.10.0'} - - define-property@2.0.2: - resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} - engines: {node: '>=0.10.0'} - delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -4418,10 +3844,6 @@ packages: dfa@1.2.0: resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==} - diff-sequences@25.2.6: - resolution: {integrity: sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==} - engines: {node: '>= 8.3'} - diff-sequences@27.5.1: resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -4430,13 +3852,6 @@ packages: resolution: {integrity: sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - dijkstrajs@1.0.3: - resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} - dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -4449,9 +3864,6 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} - dom-accessibility-api@0.5.16: - resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} - dom-serializer@0.2.2: resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} @@ -4461,10 +3873,6 @@ packages: domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - domexception@1.0.1: - resolution: {integrity: sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==} - deprecated: Use your platform's native DOMException instead - domexception@4.0.0: resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} engines: {node: '>=12'} @@ -4476,16 +3884,9 @@ packages: domutils@1.7.0: resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} - dtype@2.0.0: - resolution: {integrity: sha512-s2YVcLKdFGS0hpFqJaTwscsyt0E8nNFdmo73Ocd81xNPj4URI4rj6D60A+vFMIw7BXWlb4yRkEwfBqcZzPGiZg==} - engines: {node: '>= 0.8.0'} - eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - ecc-jsbn@0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - electron-to-chromium@1.5.41: resolution: {integrity: sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==} @@ -4493,29 +3894,19 @@ packages: resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} engines: {node: '>=12'} - emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - - emoji-regex@7.0.3: - resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} - emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - enhanced-resolve@5.17.1: resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} engines: {node: '>=10.13.0'} - enquirer@2.4.1: - resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} - engines: {node: '>=8.6'} + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} entities@1.1.2: resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==} @@ -4523,6 +3914,10 @@ packages: entities@2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -4563,141 +3958,16 @@ packages: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} - esbuild-android-64@0.14.54: - resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - esbuild-android-arm64@0.14.54: - resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - esbuild-darwin-64@0.14.54: - resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - esbuild-darwin-arm64@0.14.54: - resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - esbuild-freebsd-64@0.14.54: - resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - esbuild-freebsd-arm64@0.14.54: - resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - esbuild-linux-32@0.14.54: - resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - esbuild-linux-64@0.14.54: - resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - esbuild-linux-arm64@0.14.54: - resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - esbuild-linux-arm@0.14.54: - resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - esbuild-linux-mips64le@0.14.54: - resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - esbuild-linux-ppc64le@0.14.54: - resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - esbuild-linux-riscv64@0.14.54: - resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - esbuild-linux-s390x@0.14.54: - resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - esbuild-netbsd-64@0.14.54: - resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - esbuild-openbsd-64@0.14.54: - resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - esbuild-sunos-64@0.14.54: - resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - esbuild-windows-32@0.14.54: - resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - esbuild-windows-64@0.14.54: - resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - esbuild-windows-arm64@0.14.54: - resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - esbuild@0.14.54: - resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} - hasBin: true - esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} hasBin: true + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -4714,21 +3984,19 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - escodegen@1.14.3: - resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} - engines: {node: '>=4.0'} - hasBin: true - escodegen@2.1.0: resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} engines: {node: '>=6.0'} hasBin: true - eslint-config-prettier@6.15.0: - resolution: {integrity: sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==} - hasBin: true + eslint-config-next@15.2.1: + resolution: {integrity: sha512-mhsprz7l0no8X+PdDnVHF4dZKu9YBJp2Rf6ztWbXBLJ4h6gxmW//owbbGJMBVUU+PibGJDAqZhW4pt8SC8HSow==} peerDependencies: - eslint: '>=3.14.1' + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true eslint-config-prettier@8.10.0: resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} @@ -4736,19 +4004,6 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-config-react-app@5.2.1: - resolution: {integrity: sha512-pGIZ8t0mFLcV+6ZirRgYK6RVqUIKRIi9MmgzUEmrIknsn3AdO0I32asO86dJgloHq+9ZPl8UIg8mYrvgP5u2wQ==} - peerDependencies: - '@typescript-eslint/eslint-plugin': 2.x - '@typescript-eslint/parser': 2.x - babel-eslint: 10.x - eslint: 6.x - eslint-plugin-flowtype: 3.x || 4.x - eslint-plugin-import: 2.x - eslint-plugin-jsx-a11y: 6.x - eslint-plugin-react: 7.x - eslint-plugin-react-hooks: 1.x || 2.x - eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} @@ -4759,6 +4014,19 @@ packages: eslint: '*' eslint-plugin-import: '*' + eslint-import-resolver-typescript@3.8.3: + resolution: {integrity: sha512-A0bu4Ks2QqDWNpeEgTQMPTngaMhuDu4yv6xpftBMAf+1ziXnpx+eSR1WRfoPTe2BAiAjHFZ7kSNx1fvr5g5pmQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + eslint-module-utils@2.12.0: resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} engines: {node: '>=4'} @@ -4768,12 +4036,6 @@ packages: eslint: optional: true - eslint-plugin-flowtype@3.13.0: - resolution: {integrity: sha512-bhewp36P+t7cEV0b6OdmoRWJCBYRiHFlqPZAG1oS3SF+Y0LQkeDvFSM4oxoxvczD1OdONCXMlJfQFiWLcV9urw==} - engines: {node: '>=4'} - peerDependencies: - eslint: '>=5.0.0' - eslint-plugin-import@2.31.0: resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} engines: {node: '>=4'} @@ -4805,17 +4067,6 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-prettier@3.4.1: - resolution: {integrity: sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==} - engines: {node: '>=6.0.0'} - peerDependencies: - eslint: '>=5.0.0' - eslint-config-prettier: '*' - prettier: '>=1.13.0' - peerDependenciesMeta: - eslint-config-prettier: - optional: true - eslint-plugin-prettier@4.2.1: resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} @@ -4827,23 +4078,11 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-promise@6.1.1: - resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - - eslint-plugin-react-hooks@2.5.1: - resolution: {integrity: sha512-Y2c4b55R+6ZzwtTppKwSmK/Kar8AdLiC2f9NADCuxbcTgPPg41Gyqa6b9GppgXSvCtkRw43ZE86CT5sejKC6/g==} - engines: {node: '>=7'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - - eslint-plugin-react@7.33.2: - resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} - engines: {node: '>=4'} + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 eslint-plugin-react@7.37.1: resolution: {integrity: sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg==} @@ -4857,9 +4096,6 @@ packages: peerDependencies: eslint: 3 - 9 - eslint-plugin-tsdoc@0.3.0: - resolution: {integrity: sha512-0MuFdBrrJVBjT/gyhkP2BqpD0np1NxNLfQ38xXDlSs/KVVpKI2A6vN7jx2Rve/CyUsvOsMGwp9KKrinv7q9g3A==} - eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -4868,27 +4104,17 @@ packages: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-utils@1.4.3: - resolution: {integrity: sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==} - engines: {node: '>=6'} - - eslint-utils@2.1.0: - resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} - engines: {node: '>=6'} - - eslint-visitor-keys@1.3.0: - resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} - engines: {node: '>=4'} + eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint@6.8.0: - resolution: {integrity: sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. - hasBin: true + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint@8.57.1: resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} @@ -4896,9 +4122,19 @@ packages: deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true - espree@6.2.1: - resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==} - engines: {node: '>=6.0.0'} + eslint@9.21.0: + resolution: {integrity: sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} @@ -4925,11 +4161,8 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} - estree-walker@0.6.1: - resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} - - estree-walker@1.0.1: - resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -4945,21 +4178,6 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - exec-sh@0.3.6: - resolution: {integrity: sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==} - - execa@1.0.0: - resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} - engines: {node: '>=6'} - - execa@3.4.0: - resolution: {integrity: sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==} - engines: {node: ^8.12.0 || >=9.7.0} - - execa@4.1.0: - resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} - engines: {node: '>=10'} - execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -4972,51 +4190,26 @@ packages: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} - expand-brackets@2.1.4: - resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} - engines: {node: '>=0.10.0'} - - expect@25.5.0: - resolution: {integrity: sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==} - engines: {node: '>= 8.3'} - expect@28.1.3: resolution: {integrity: sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - extend-shallow@2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - - extend-shallow@3.0.2: - resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} - engines: {node: '>=0.10.0'} + exsolve@1.0.4: + resolution: {integrity: sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==} extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - - extglob@2.0.4: - resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} - engines: {node: '>=0.10.0'} - - extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} fast-diff@1.3.0: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -5040,8 +4233,17 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - fdir@6.4.2: - resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -5069,36 +4271,21 @@ packages: fflate@0.8.2: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - - file-entry-cache@5.0.1: - resolution: {integrity: sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==} - engines: {node: '>=4'} - file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} - file-saver@2.0.5: - resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - fill-range@4.0.0: - resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} - engines: {node: '>=0.10.0'} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - find-cache-dir@3.3.2: - resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} - engines: {node: '>=8'} - find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -5107,23 +4294,17 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - flat-cache@2.0.1: - resolution: {integrity: sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==} - engines: {node: '>=4'} - flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} - flatted@2.0.2: - resolution: {integrity: sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - flatten-vertex-data@1.0.2: - resolution: {integrity: sha512-BvCBFK2NZqerFTdMDgqfHBwxYWnxeCkwONsw6PvBMcUXqo8U/KDWwmXhqx1x2kLIg7DqIsJfOaJFOmlua3Lxuw==} - follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} @@ -5133,50 +4314,24 @@ packages: debug: optional: true - fontkit@1.9.0: - resolution: {integrity: sha512-HkW/8Lrk8jl18kzQHvAw9aTHe1cqsyx5sDnxncx652+CIfhawokEPkeM3BoIC+z/Xv7a0yMr0f3pRRwhGH455g==} - for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - for-in@1.0.2: - resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} - engines: {node: '>=0.10.0'} - foreground-child@3.3.0: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} - forever-agent@0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - - form-data@2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - form-data@4.0.1: resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} - fragment-cache@0.2.1: - resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} - engines: {node: '>=0.10.0'} + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} + engines: {node: '>=14.14'} fs-extra@3.0.1: resolution: {integrity: sha512-V3Z3WZWVUYd8hoCL5xfXJCaHWYzmtwW5XWYSlLgERi8PWd8bx1kUHUk8L1BT57e49oKnDDD180mjfrHc1yA9rg==} - fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} - - fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} - - fs-extra@9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -5196,9 +4351,6 @@ packages: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} - functional-red-black-tree@1.0.1: - resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} - functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} @@ -5218,22 +4370,10 @@ packages: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} - get-stdin@6.0.0: - resolution: {integrity: sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==} - engines: {node: '>=4'} - get-stdin@8.0.0: resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} engines: {node: '>=10'} - get-stream@4.1.0: - resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} - engines: {node: '>=6'} - - get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -5242,20 +4382,12 @@ packages: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} + get-tsconfig@4.10.0: + resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + get-uri@2.0.4: resolution: {integrity: sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q==} - get-value@2.0.6: - resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} - engines: {node: '>=0.10.0'} - - getpass@0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - - git-repo-info@2.1.1: - resolution: {integrity: sha512-8aCohiDo4jwjOwma4FmYFd3i97urZulL8XL24nIPxuE+GZnfsAyy/g2Shqx6OjUiFKUXZM+Yy+KHnOmmA3FVcg==} - engines: {node: '>= 4.0'} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -5269,11 +4401,7 @@ packages: glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - glob@11.0.0: - resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} - engines: {node: 20 || >=22} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.2.3: @@ -5292,21 +4420,18 @@ packages: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - globals@12.4.0: - resolution: {integrity: sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==} - engines: {node: '>=8'} - globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} - globalyzer@0.1.0: - resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} - globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -5331,18 +4456,6 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - growly@1.3.0: - resolution: {integrity: sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==} - - har-schema@2.0.0: - resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} - engines: {node: '>=4'} - - har-validator@5.1.5: - resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} - engines: {node: '>=6'} - deprecated: this library is no longer supported - hard-rejection@2.1.0: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} engines: {node: '>=6'} @@ -5376,22 +4489,6 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - has-value@0.3.1: - resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} - engines: {node: '>=0.10.0'} - - has-value@1.0.0: - resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} - engines: {node: '>=0.10.0'} - - has-values@0.1.4: - resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} - engines: {node: '>=0.10.0'} - - has-values@1.0.0: - resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} - engines: {node: '>=0.10.0'} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -5413,9 +4510,6 @@ packages: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} engines: {node: '>=10'} - html-encoding-sniffer@1.0.2: - resolution: {integrity: sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==} - html-encoding-sniffer@3.0.0: resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} engines: {node: '>=12'} @@ -5434,57 +4528,30 @@ packages: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} engines: {node: '>= 6'} - http-signature@1.2.0: - resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} - engines: {node: '>=0.8', npm: '>=1.3.7'} - https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} - human-signals@1.1.1: - resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} - engines: {node: '>=8.12.0'} - human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - humanize-duration@3.32.1: - resolution: {integrity: sha512-inh5wue5XdfObhu/IGEMiA1nUXigSGcaKNemcbLRKa7jXYGDZXr3LoT9pTIzq2hPEbld7w/qv9h+ikWGz8fL1g==} - - husky@8.0.3: - resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} - engines: {node: '>=14'} - hasBin: true - - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + identity-obj-proxy@3.0.0: resolution: {integrity: sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==} engines: {node: '>=4'} - ignore@4.0.6: - resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} - engines: {node: '>= 4'} - - ignore@5.1.9: - resolution: {integrity: sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==} - engines: {node: '>= 4'} - ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - immutable@4.3.7: - resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} - import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -5516,26 +4583,10 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - inquirer@7.3.3: - resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} - engines: {node: '>=8.0.0'} - internal-slot@1.0.7: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} - interpret@1.4.0: - resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} - engines: {node: '>= 0.10'} - - ip-regex@2.1.0: - resolution: {integrity: sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==} - engines: {node: '>=4'} - - is-accessor-descriptor@1.0.1: - resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} - engines: {node: '>= 0.10'} - is-alphabetical@1.0.4: resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} @@ -5553,55 +4604,35 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-async-function@2.0.0: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} - is-base64@0.1.0: - resolution: {integrity: sha512-WRRyllsGXJM7ZN7gPTCCQ/6wNPTRDwiWdPK66l5sJzcU/oOzcIcRRf0Rux8bkpox/1yjt0F6VJRsQOIG2qz5sg==} - is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-blob@1.0.0: - resolution: {integrity: sha512-QIZDHQZpRfMEZwSTD7egdNZS7H/awVW9FZ3yJv+gg1z8d8GPXEs76QWL67fZs2BoBqp2dGtamTJpEYFJHmD73g==} - engines: {node: '>=0.10.0'} - - is-blob@2.1.0: - resolution: {integrity: sha512-SZ/fTft5eUhQM6oF/ZaASFDEdbFVe89Imltn9uZr03wdKMcWNVYSMjQPFtg05QuNkt5l5c135ElvXEQG0rk4tw==} - engines: {node: '>=6'} - is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} - is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - is-buffer@2.0.5: resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} engines: {node: '>=4'} + is-bun-module@1.3.0: + resolution: {integrity: sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==} + is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-ci@2.0.0: - resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} - hasBin: true - is-core-module@2.15.1: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} - is-data-descriptor@1.0.1: - resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==} - engines: {node: '>= 0.4'} - is-data-view@1.0.1: resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} engines: {node: '>= 0.4'} @@ -5613,27 +4644,6 @@ packages: is-decimal@1.0.4: resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} - is-descriptor@0.1.7: - resolution: {integrity: sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==} - engines: {node: '>= 0.4'} - - is-descriptor@1.0.3: - resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==} - engines: {node: '>= 0.4'} - - is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - - is-extendable@0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - - is-extendable@1.0.1: - resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} - engines: {node: '>=0.10.0'} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -5641,10 +4651,6 @@ packages: is-finalizationregistry@1.0.2: resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} - is-fullwidth-code-point@2.0.0: - resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} - engines: {node: '>=4'} - is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -5664,17 +4670,10 @@ packages: is-hexadecimal@1.0.4: resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} - is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} @@ -5683,10 +4682,6 @@ packages: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} - is-number@3.0.0: - resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} - engines: {node: '>=0.10.0'} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -5703,16 +4698,9 @@ packages: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} - is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -5729,10 +4717,6 @@ packages: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} engines: {node: '>= 0.4'} - is-stream@1.1.0: - resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} - engines: {node: '>=0.10.0'} - is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -5770,14 +4754,6 @@ packages: resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} engines: {node: '>= 0.4'} - is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - - is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - isarray@0.0.1: resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} @@ -5790,25 +4766,10 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - isobject@2.1.0: - resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} - engines: {node: '>=0.10.0'} - - isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - - isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} - istanbul-lib-instrument@4.0.3: - resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==} - engines: {node: '>=8'} - istanbul-lib-instrument@5.2.1: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} @@ -5836,35 +4797,14 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jackspeak@4.0.2: - resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==} - engines: {node: 20 || >=22} - - jest-changed-files@25.5.0: - resolution: {integrity: sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw==} - engines: {node: '>= 8.3'} - jest-changed-files@28.1.3: resolution: {integrity: sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-circus@28.1.3: resolution: {integrity: sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-cli@25.5.4: - resolution: {integrity: sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw==} - engines: {node: '>= 8.3'} - hasBin: true - jest-cli@28.1.3: resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -5875,10 +4815,6 @@ packages: node-notifier: optional: true - jest-config@25.5.4: - resolution: {integrity: sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==} - engines: {node: '>= 8.3'} - jest-config@28.1.3: resolution: {integrity: sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -5891,22 +4827,6 @@ packages: ts-node: optional: true - jest-config@29.5.0: - resolution: {integrity: sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - - jest-diff@25.5.0: - resolution: {integrity: sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==} - engines: {node: '>= 8.3'} - jest-diff@27.5.1: resolution: {integrity: sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -5915,58 +4835,22 @@ packages: resolution: {integrity: sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-docblock@25.3.0: - resolution: {integrity: sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==} - engines: {node: '>= 8.3'} - jest-docblock@28.1.1: resolution: {integrity: sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-each@25.5.0: - resolution: {integrity: sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==} - engines: {node: '>= 8.3'} - jest-each@28.1.3: resolution: {integrity: sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-environment-jsdom@25.5.0: - resolution: {integrity: sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==} - engines: {node: '>= 8.3'} - jest-environment-jsdom@28.1.3: resolution: {integrity: sha512-HnlGUmZRdxfCByd3GM2F100DgQOajUBzEitjGqIREcb45kGjZvRrKUdlaF6escXBdcXNl0OBh+1ZrfeZT3GnAg==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-environment-node@25.5.0: - resolution: {integrity: sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==} - engines: {node: '>= 8.3'} - jest-environment-node@28.1.3: resolution: {integrity: sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-get-type@25.2.6: - resolution: {integrity: sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==} - engines: {node: '>= 8.3'} - jest-get-type@27.5.1: resolution: {integrity: sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -5975,48 +4859,20 @@ packages: resolution: {integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-haste-map@25.5.1: - resolution: {integrity: sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==} - engines: {node: '>= 8.3'} - jest-haste-map@28.1.3: resolution: {integrity: sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-jasmine2@25.5.4: - resolution: {integrity: sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==} - engines: {node: '>= 8.3'} - - jest-leak-detector@25.5.0: - resolution: {integrity: sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==} - engines: {node: '>= 8.3'} - jest-leak-detector@28.1.3: resolution: {integrity: sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-light-runner@0.2.2: resolution: {integrity: sha512-1SuBAnfrhmMIUKbGltvbIsCW9bIrCMeyd3EHaXTVI4dkmA6790tvV0j4UudYZsnpvS8h8X9Bl5iRCrRV8nR1/A==} engines: {node: '>=12.20.0'} peerDependencies: jest: ^27.0.0 || ^28.0.0 - jest-matcher-utils@25.5.0: - resolution: {integrity: sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==} - engines: {node: '>= 8.3'} - jest-matcher-utils@27.5.1: resolution: {integrity: sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -6025,34 +4881,14 @@ packages: resolution: {integrity: sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-message-util@25.5.0: - resolution: {integrity: sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==} - engines: {node: '>= 8.3'} - jest-message-util@28.1.3: resolution: {integrity: sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-mock@25.5.0: - resolution: {integrity: sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==} - engines: {node: '>= 8.3'} - jest-mock@28.1.3: resolution: {integrity: sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-pnp-resolver@1.2.3: resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} engines: {node: '>=6'} @@ -6062,117 +4898,37 @@ packages: jest-resolve: optional: true - jest-regex-util@25.2.6: - resolution: {integrity: sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==} - engines: {node: '>= 8.3'} - jest-regex-util@28.0.2: resolution: {integrity: sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-resolve-dependencies@25.5.4: - resolution: {integrity: sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw==} - engines: {node: '>= 8.3'} - jest-resolve-dependencies@28.1.3: resolution: {integrity: sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-resolve@25.5.1: - resolution: {integrity: sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==} - engines: {node: '>= 8.3'} - jest-resolve@28.1.3: resolution: {integrity: sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-resolve@29.5.0: - resolution: {integrity: sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-runner@25.5.4: - resolution: {integrity: sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==} - engines: {node: '>= 8.3'} - jest-runner@28.1.3: resolution: {integrity: sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-runtime@25.5.4: - resolution: {integrity: sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==} - engines: {node: '>= 8.3'} - hasBin: true - jest-runtime@28.1.3: resolution: {integrity: sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-serializer@25.5.0: - resolution: {integrity: sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==} - engines: {node: '>= 8.3'} - - jest-snapshot@25.5.1: - resolution: {integrity: sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==} - engines: {node: '>= 8.3'} - jest-snapshot@28.1.3: resolution: {integrity: sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-snapshot@29.5.0: - resolution: {integrity: sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-util@25.5.0: - resolution: {integrity: sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==} - engines: {node: '>= 8.3'} - jest-util@28.1.3: resolution: {integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-validate@25.5.0: - resolution: {integrity: sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==} - engines: {node: '>= 8.3'} - jest-validate@28.1.3: resolution: {integrity: sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - - jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-watch-typeahead@0.5.0: - resolution: {integrity: sha512-4r36w9vU8+rdg48hj0Z7TvcSqVP6Ao8dk04grlHQNgduyCB0SqrI0xWIl85ZhXrzYvxQ0N5H+rRLAejkQzEHeQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} jest-watch-typeahead@1.1.0: resolution: {integrity: sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==} @@ -6180,26 +4936,10 @@ packages: peerDependencies: jest: ^27.0.0 || ^28.0.0 - jest-watcher@25.5.0: - resolution: {integrity: sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q==} - engines: {node: '>= 8.3'} - jest-watcher@28.1.3: resolution: {integrity: sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-worker@24.9.0: - resolution: {integrity: sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==} - engines: {node: '>= 6'} - - jest-worker@25.5.0: - resolution: {integrity: sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==} - engines: {node: '>= 8.3'} - jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} @@ -6208,15 +4948,6 @@ packages: resolution: {integrity: sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest@25.5.4: - resolution: {integrity: sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ==} - engines: {node: '>= 8.3'} - hasBin: true - jest@28.1.3: resolution: {integrity: sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -6227,11 +4958,16 @@ packages: node-notifier: optional: true + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} - jpjs@1.2.1: - resolution: {integrity: sha512-GxJWybWU4NV0RNKi6EIqk6IRPOTqd/h+U7sbtyuD7yUISUzV78LdHnq2xkevJsTlz/EImux4sWj+wfMiwKLkiw==} + jpeg-exif@1.1.4: + resolution: {integrity: sha512-a+bKEcCjtuW5WTdgeXFzswSrdqi0jk4XlEtZlx5A94wCoBpFjfFTbo/Tra5SpNCl/YFZPvcV1dJc+TAYeg6ROQ==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -6244,22 +4980,10 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsbn@0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - jsdoc-type-pratt-parser@3.1.0: resolution: {integrity: sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==} engines: {node: '>=12.0.0'} - jsdom@15.2.1: - resolution: {integrity: sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==} - engines: {node: '>=8'} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - jsdom@19.0.0: resolution: {integrity: sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==} engines: {node: '>=12'} @@ -6269,10 +4993,6 @@ packages: canvas: optional: true - jsep@1.4.0: - resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} - engines: {node: '>= 10.16.0'} - jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} @@ -6290,15 +5010,9 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true @@ -6311,21 +5025,9 @@ packages: jsonfile@3.0.1: resolution: {integrity: sha512-oBko6ZHlubVB5mRFkur5vgYR1UyqX+S6Y/oCfLhqNdcc2fYFlDpIoNc7AfKS1KOGcnNAkvsr0grLck9ANM815w==} - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - jsonpath-plus@10.1.0: - resolution: {integrity: sha512-gHfV1IYqH8uJHYVTs8BJX1XKy2/rR93+f8QQi0xhx95aCiXn1ettYAd5T+7FU6wfqyDoX/wy0pm/fL3jOKJ9Lg==} - engines: {node: '>=18.0.0'} - hasBin: true - - jsprim@1.4.2: - resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} - engines: {node: '>=0.6.0'} - jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -6333,14 +5035,6 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - kind-of@3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - - kind-of@4.0.0: - resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} - engines: {node: '>=0.10.0'} - kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -6352,6 +5046,9 @@ packages: known-css-properties@0.21.0: resolution: {integrity: sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==} + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -6363,20 +5060,73 @@ packages: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} - levn@0.3.0: - resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} - engines: {node: '>= 0.8.0'} - levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lilconfig@2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} + lightningcss-darwin-arm64@1.29.1: + resolution: {integrity: sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.29.1: + resolution: {integrity: sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.29.1: + resolution: {integrity: sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.29.1: + resolution: {integrity: sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.29.1: + resolution: {integrity: sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.29.1: + resolution: {integrity: sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.29.1: + resolution: {integrity: sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] - linebreak@1.1.0: - resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} + lightningcss-linux-x64-musl@1.29.1: + resolution: {integrity: sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.29.1: + resolution: {integrity: sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.29.1: + resolution: {integrity: sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.29.1: + resolution: {integrity: sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==} + engines: {node: '>= 12.0.0'} lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -6385,6 +5135,10 @@ packages: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} + local-pkg@1.1.1: + resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} + engines: {node: '>=14'} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -6414,21 +5168,10 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - log-symbols@3.0.0: - resolution: {integrity: sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==} - engines: {node: '>=8'} - log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} - log-update@2.3.0: - resolution: {integrity: sha512-vlP11XfFGyeNQlmEn9tJ66rEW1coA/79m5z6BCkudjbAGE83uhAcGYrBFwfs3AdLiLzGRusRPAbSPK9xZteCmg==} - engines: {node: '>=4'} - - lolex@5.1.2: - resolution: {integrity: sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==} - longest-streak@2.0.4: resolution: {integrity: sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==} @@ -6439,16 +5182,9 @@ packages: loupe@3.1.2: resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} - lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.0.2: - resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} - engines: {node: 20 || >=22} - lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -6456,15 +5192,8 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} - lz-string@1.5.0: - resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} - hasBin: true - - magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - - magic-string@0.30.12: - resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} @@ -6483,10 +5212,6 @@ packages: makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - map-cache@0.2.2: - resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} - engines: {node: '>=0.10.0'} - map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -6495,10 +5220,6 @@ packages: resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} engines: {node: '>=8'} - map-visit@1.0.0: - resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} - engines: {node: '>=0.10.0'} - mathml-tag-names@2.1.3: resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} @@ -6525,10 +5246,6 @@ packages: micromark@2.11.4: resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} - micromatch@3.1.10: - resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} - engines: {node: '>=0.10.0'} - micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -6541,9 +5258,10 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mimic-fn@1.2.0: - resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} - engines: {node: '>=4'} + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} @@ -6553,17 +5271,12 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} - engines: {node: 20 || >=22} + minimatch@3.0.8: + resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==} minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -6579,29 +5292,12 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - mixin-deep@1.3.2: - resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} - engines: {node: '>=0.10.0'} - - mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - - moment-timezone@0.5.46: - resolution: {integrity: sha512-ZXm9b36esbe7OmdABqIWJuBBiLLwAjrN7CE+7sYdCCx82Nabt1wHDj8TVseS59QIlfFPbOoiBPm6ca9BioG4hw==} + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - mrmime@2.0.0: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} @@ -6612,20 +5308,18 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanomatch@1.2.13: - resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} - engines: {node: '>=0.10.0'} - - nanospinner@1.1.0: - resolution: {integrity: sha512-yFvNYMig4AthKYfHFl1sLj7B2nkHL4lzdig4osvl9/LdGbXwrdFRoqBS98gsEsOakr0yH+r5NZ/1Y9gdVB8trA==} + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} @@ -6636,16 +5330,31 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + next@15.2.3: + resolution: {integrity: sha512-x6eDkZxk2rPpu46E1ZVUWIBhYCLszmUY6fvHBFcbzJ9dD+qRX6vcHusaqqDlnY+VngKzKbAiG2iRCkPbmi8f7w==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + nice-napi@1.0.2: resolution: {integrity: sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==} os: ['!win32'] - nice-try@1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - - no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - node-addon-api@3.2.1: resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} @@ -6672,9 +5381,6 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-notifier@6.0.0: - resolution: {integrity: sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==} - node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} @@ -6685,10 +5391,6 @@ packages: resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} engines: {node: '>=10'} - normalize-path@2.1.1: - resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} - engines: {node: '>=0.10.0'} - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -6700,10 +5402,6 @@ packages: normalize-selector@0.2.0: resolution: {integrity: sha512-dxvWdI8gw6eAvk9BlPffgEoGfM7AdijoCwOEJge3e3ulT2XLgmU7KvvxprOaCu05Q1uGRHmOhHe1r6emZoKyFw==} - npm-run-path@2.0.2: - resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} - engines: {node: '>=4'} - npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -6714,17 +5412,10 @@ packages: nwsapi@2.2.13: resolution: {integrity: sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==} - oauth-sign@0.9.0: - resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - object-copy@0.1.0: - resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} - engines: {node: '>=0.10.0'} - object-inspect@1.13.2: resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} engines: {node: '>= 0.4'} @@ -6737,10 +5428,6 @@ packages: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} - object-visit@1.0.1: - resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} - engines: {node: '>=0.10.0'} - object.assign@4.1.5: resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} @@ -6757,14 +5444,6 @@ packages: resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} engines: {node: '>= 0.4'} - object.hasown@1.1.4: - resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} - engines: {node: '>= 0.4'} - - object.pick@1.3.0: - resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} - engines: {node: '>=0.10.0'} - object.values@1.2.0: resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} engines: {node: '>= 0.4'} @@ -6772,42 +5451,14 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@2.0.1: - resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==} - engines: {node: '>=4'} - onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - optionator@0.8.3: - resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} - engines: {node: '>= 0.8.0'} - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} - ora@4.1.1: - resolution: {integrity: sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==} - engines: {node: '>=8'} - - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - - p-each-series@2.2.0: - resolution: {integrity: sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==} - engines: {node: '>=8'} - - p-finally@1.0.0: - resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} - engines: {node: '>=4'} - - p-finally@2.0.1: - resolution: {integrity: sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==} - engines: {node: '>=8'} - p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -6848,18 +5499,11 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - parse5@5.1.0: - resolution: {integrity: sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==} - parse5@6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - pascal-case@3.1.2: - resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} - - pascalcase@0.1.1: - resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} - engines: {node: '>=0.10.0'} + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} @@ -6869,10 +5513,6 @@ packages: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} - path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -6884,10 +5524,6 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-scurry@2.0.0: - resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} - engines: {node: 20 || >=22} - path-to-regexp@2.4.0: resolution: {integrity: sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==} @@ -6898,6 +5534,9 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pathval@2.0.0: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} @@ -6906,15 +5545,9 @@ packages: resolution: {integrity: sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A==} engines: {node: '>=6.8.1'} - pdfkit@0.12.3: - resolution: {integrity: sha512-+qDLgm2yq6WOKcxTb43lDeo3EtMIDQs0CK1RNqhHC9iT6u0KOmgwAClkYh9xFw2ATbmUZzt4f7KMwDCOfPDluA==} - - pdfmake@0.1.72: - resolution: {integrity: sha512-xZrPS+Safjf1I8ZYtMoXX83E6C6Pd1zFwa168yNTeeJWHclqf1z9DoYajjlY2uviN7gGyxwVZeou39uSk1oh1g==} - engines: {node: '>=8'} - - performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + pdfmake@0.2.23: + resolution: {integrity: sha512-A/IksoKb/ikOZH1edSDJ/2zBbqJKDghD4+fXn3rT7quvCJDlsZMs3NmIB3eajLMMFU9Bd3bZPVvlUMXhvFI+bQ==} + engines: {node: '>=18'} picocolors@0.2.1: resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==} @@ -6930,6 +5563,10 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -6941,20 +5578,15 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} - pn@1.1.0: - resolution: {integrity: sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.1.0: + resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} png-js@1.0.0: resolution: {integrity: sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==} - pngjs@5.0.0: - resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} - engines: {node: '>=10.13.0'} - - posix-character-classes@0.1.1: - resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} - engines: {node: '>=0.10.0'} - possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -7006,13 +5638,17 @@ packages: resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} engines: {node: '>=6.0.0'} - postcss@8.4.47: - resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - prelude-ls@1.1.2: - resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} - engines: {node: '>= 0.8.0'} + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -7022,20 +5658,11 @@ packages: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} - prettier@1.19.1: - resolution: {integrity: sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==} - engines: {node: '>=4'} - hasBin: true - prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} hasBin: true - pretty-format@25.5.0: - resolution: {integrity: sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==} - engines: {node: '>= 8.3'} - pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -7044,20 +5671,9 @@ packages: resolution: {integrity: sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - progress-estimator@0.2.2: - resolution: {integrity: sha512-GF76Ac02MTJD6o2nMNtmtOFjwWCnHcvXyn5HOWPQnEMO8OTLw7LAvNmrwe8LmdsB+eZhwUu9fX/c9iQnBxWaFA==} - - progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -7068,24 +5684,12 @@ packages: psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - - qrcode@1.5.4: - resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} - engines: {node: '>=10.13.0'} - hasBin: true - - qs@6.5.3: - resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} - engines: {node: '>=0.6'} + quansync@0.2.10: + resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} querystring@0.2.1: resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==} @@ -7105,6 +5709,11 @@ packages: randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + react-dom@19.0.0: + resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} + peerDependencies: + react: ^19.0.0 + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -7114,6 +5723,10 @@ packages: react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react@19.0.0: + resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} + engines: {node: '>=0.10.0'} + read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -7132,18 +5745,6 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - realpath-native@2.0.0: - resolution: {integrity: sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==} - engines: {node: '>=8'} - - rechoir@0.6.2: - resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} - engines: {node: '>= 0.10'} - redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -7159,31 +5760,16 @@ packages: regenerate@1.4.2: resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - regenerator-runtime@0.13.11: - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - regex-not@1.0.2: - resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} - engines: {node: '>=0.10.0'} - regexp.prototype.flags@1.5.3: resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} - regexpp@2.0.1: - resolution: {integrity: sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==} - engines: {node: '>=6.5.0'} - - regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - regexpu-core@6.1.1: resolution: {integrity: sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==} engines: {node: '>=4'} @@ -7204,35 +5790,10 @@ packages: remark@13.0.0: resolution: {integrity: sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==} - remove-trailing-separator@1.1.0: - resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} - - repeat-element@1.1.4: - resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} - engines: {node: '>=0.10.0'} - repeat-string@1.6.1: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} - request-promise-core@1.1.4: - resolution: {integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==} - engines: {node: '>=0.10.0'} - peerDependencies: - request: ^2.34 - - request-promise-native@1.0.9: - resolution: {integrity: sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==} - engines: {node: '>=0.12.0'} - deprecated: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 - peerDependencies: - request: ^2.34 - - request@2.88.2: - resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} - engines: {node: '>= 6'} - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -7241,9 +5802,6 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -7259,24 +5817,13 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - resolve-url@0.2.1: - resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} - deprecated: https://github.com/lydell/resolve-url#deprecated + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} resolve.exports@1.1.1: resolution: {integrity: sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==} engines: {node: '>=10'} - resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - - resolve@1.1.7: - resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} - - resolve@1.17.0: - resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} - resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -7285,98 +5832,23 @@ packages: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true - restore-cursor@2.0.0: - resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} - engines: {node: '>=4'} - - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - - restructure@2.0.1: - resolution: {integrity: sha512-e0dOpjm5DseomnXx2M5lpdZ5zoHqF1+bqdMJUohoYVVQa7cBdnk7fdmeI6byNWP/kiME72EeTiSypTCVnpLiDg==} - - ret@0.1.15: - resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} - engines: {node: '>=0.12'} - reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rimraf@2.6.3: - resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rimraf@6.0.1: - resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} - engines: {node: 20 || >=22} - hasBin: true - - rollup-plugin-sourcemaps@0.6.3: - resolution: {integrity: sha512-paFu+nT1xvuO1tPFYXGe+XnQvg4Hjqv/eIhG8i5EspfYYPBKL57X7iVbfv55aNVASg3dzWvES9dmWsL2KhfByw==} - engines: {node: '>=10.0.0'} - peerDependencies: - '@types/node': '>=10.0.0' - rollup: '>=0.31.2' - peerDependenciesMeta: - '@types/node': - optional: true - - rollup-plugin-terser@5.3.1: - resolution: {integrity: sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w==} - deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser - peerDependencies: - rollup: '>=0.66.0 <3' - - rollup-plugin-typescript2@0.27.3: - resolution: {integrity: sha512-gmYPIFmALj9D3Ga1ZbTZAKTXq1JKlTQBtj299DXhqYz9cL3g/AQfUvbb2UhH+Nf++cCq941W2Mv7UcrcgLzJJg==} - peerDependencies: - rollup: '>=1.26.3' - typescript: '>=2.4.0' - - rollup-pluginutils@2.8.2: - resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - - rollup@1.32.1: - resolution: {integrity: sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==} - hasBin: true - - rollup@3.29.5: - resolution: {integrity: sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} - hasBin: true - - rollup@4.24.0: - resolution: {integrity: sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==} + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rsvp@4.8.5: - resolution: {integrity: sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==} - engines: {node: 6.* || >= 7.*} - - run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - rxjs@6.6.7: - resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} - engines: {npm: '>=2.0.0'} - - sade@1.8.1: - resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} - engines: {node: '>=6'} - safe-array-concat@1.1.2: resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} @@ -7391,32 +5863,23 @@ packages: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} - safe-regex@1.1.0: - resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} - safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sane@4.1.0: - resolution: {integrity: sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==} - engines: {node: 6.* || 8.* || >= 10.*} - deprecated: some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added - hasBin: true - - save-file@2.3.1: - resolution: {integrity: sha512-VOD2Ojb1/kuj0XbvSXzZ5xr4rRSZD8f+HzKWGztXNp93gBQDj3njFt9HMhmLtnwd7q0BjJkzLXqd8M2+PFS1qg==} - sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} - saxes@3.1.11: - resolution: {integrity: sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==} - engines: {node: '>=8'} + sax@1.5.0: + resolution: {integrity: sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==} + engines: {node: '>=11.0.0'} saxes@5.0.1: resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} engines: {node: '>=10'} + scheduler@0.25.0: + resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} + schema-utils@3.3.0: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} @@ -7429,11 +5892,6 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.3.5: - resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} - engines: {node: '>=10'} - hasBin: true - semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} engines: {node: '>=10'} @@ -7444,15 +5902,14 @@ packages: engines: {node: '>=10'} hasBin: true - serialize-javascript@4.0.0: - resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -7461,34 +5918,18 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} - set-value@2.0.1: - resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} - engines: {node: '>=0.10.0'} - - shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} - shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shelljs@0.8.5: - resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} - engines: {node: '>=4'} - hasBin: true - - shellwords@0.1.1: - resolution: {integrity: sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==} - side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} @@ -7503,9 +5944,8 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-mime@0.1.0: - resolution: {integrity: sha512-2EoTElzj77w0hV4lW6nWdA+MR+81hviMBhEc/ppUi0+Q311EFCvwKrGS7dcxqvGRKnUdbAyqPJtBQbRYgmtmvQ==} - engines: {'0': node >= 0.2.0} + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} sirv@2.0.4: resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} @@ -7514,11 +5954,6 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - size-limit@7.0.8: - resolution: {integrity: sha512-3h76c9E0e/nNhYLSR7IBI/bSoXICeo7EYkYjlyVqNIsu7KvN/PQmMbIXeyd2QKIF8iZKhaiZQoXLkGWbyPDtvQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - hasBin: true - slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -7527,64 +5962,27 @@ packages: resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} engines: {node: '>=12'} - slice-ansi@2.1.0: - resolution: {integrity: sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==} - engines: {node: '>=6'} - slice-ansi@4.0.0: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} - snapdragon-node@2.1.1: - resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} - engines: {node: '>=0.10.0'} - - snapdragon-util@3.0.1: - resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} - engines: {node: '>=0.10.0'} - - snapdragon@0.8.2: - resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} - engines: {node: '>=0.10.0'} + smob@1.5.0: + resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} - source-map-resolve@0.5.3: - resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} - deprecated: See https://github.com/lydell/source-map-resolve#deprecated - - source-map-resolve@0.6.0: - resolution: {integrity: sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==} - deprecated: See https://github.com/lydell/source-map-resolve#deprecated - source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - source-map-url@0.4.1: - resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} - deprecated: See https://github.com/lydell/source-map-url#deprecated - - source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} - - sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} @@ -7601,21 +5999,11 @@ packages: resolution: {integrity: sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==} hasBin: true - split-string@3.1.0: - resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} - engines: {node: '>=0.10.0'} - sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - sshpk@1.18.0: - resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} - engines: {node: '>=0.10.0'} - hasBin: true - - stack-utils@1.0.5: - resolution: {integrity: sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==} - engines: {node: '>=8'} + stable-hash@0.0.4: + resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} @@ -7624,29 +6012,21 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - static-extend@0.1.2: - resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} - engines: {node: '>=0.10.0'} - std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} - stealthy-require@1.1.1: - resolution: {integrity: sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==} - engines: {node: '>=0.10.0'} - stop-iteration-iterator@1.0.0: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} - string-length@3.1.0: - resolution: {integrity: sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==} - engines: {node: '>=8'} - string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -7655,17 +6035,6 @@ packages: resolution: {integrity: sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==} engines: {node: '>=12.20'} - string-to-arraybuffer@1.0.2: - resolution: {integrity: sha512-DaGZidzi93dwjQen5I2osxR9ERS/R7B1PFyufNMnzhj+fmlDQAc1DSDIJVJhgI8Oq221efIMbABUBdPHDRt43Q==} - - string-width@2.1.1: - resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} - engines: {node: '>=4'} - - string-width@3.1.0: - resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} - engines: {node: '>=6'} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -7705,14 +6074,6 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - strip-ansi@4.0.0: - resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} - engines: {node: '>=4'} - - strip-ansi@5.2.0: - resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} - engines: {node: '>=6'} - strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -7729,10 +6090,6 @@ packages: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} - strip-eof@1.0.0: - resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} - engines: {node: '>=0.10.0'} - strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -7748,6 +6105,19 @@ packages: style-search@0.1.0: resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + stylelint-config-recommended@5.0.0: resolution: {integrity: sha512-c8aubuARSu5A3vEHLBeOSJt1udOdS+1iue7BmJDTSXoCBmfEQmmWX+59vYIj3NQdJBY6a/QRv1ozVFpaB9jaqA==} peerDependencies: @@ -7770,10 +6140,6 @@ packages: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} - supports-color@6.1.0: - resolution: {integrity: sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==} - engines: {node: '>=6'} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -7797,23 +6163,15 @@ packages: svg-tags@1.0.0: resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} - svg-to-pdfkit@0.1.8: - resolution: {integrity: sha512-QItiGZBy5TstGy+q8mjQTMGRlDDOARXLxH+sgVm1n/LYeo0zFcQlcCh8m4zi8QxctrxB9Kue/lStc/RD5iLadQ==} - symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - table@5.4.6: - resolution: {integrity: sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==} - engines: {node: '>=6.0.0'} - table@6.8.2: resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==} engines: {node: '>=10.0.0'} - tapable@1.1.3: - resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==} - engines: {node: '>=6'} + tailwindcss@4.0.9: + resolution: {integrity: sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==} tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} @@ -7839,11 +6197,6 @@ packages: uglify-js: optional: true - terser@4.8.1: - resolution: {integrity: sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==} - engines: {node: '>=6.0.0'} - hasBin: true - terser@5.36.0: resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==} engines: {node: '>=10'} @@ -7860,15 +6213,6 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - throat@5.0.0: - resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} - - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - tiny-glob@0.2.9: - resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} - tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} @@ -7878,8 +6222,12 @@ packages: tinyexec@0.3.1: resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} - tinyglobby@0.2.9: - resolution: {integrity: sha512-8or1+BGEdk1Zkkw2ii16qSS7uVrQJPre5A9o/XkWPATkk23FZh/15BKFxPnlTy6vkljZxLqYCzzBMj30ZrSvjw==} + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} tinypool@1.0.1: @@ -7894,48 +6242,21 @@ packages: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - to-array-buffer@3.2.0: - resolution: {integrity: sha512-zN33mwi0gpL+7xW1ITLfJ48CEj6ZQW0ZAP0MU+2W3kEY0PAIncyuxmD4OqkUVhPAbTP7amq9j/iwvZKYS+lzSQ==} - to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} - to-object-path@0.3.0: - resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} - engines: {node: '>=0.10.0'} - - to-regex-range@2.1.1: - resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} - engines: {node: '>=0.10.0'} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - to-regex@3.0.2: - resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} - engines: {node: '>=0.10.0'} - totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - tough-cookie@2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} - - tough-cookie@3.0.1: - resolution: {integrity: sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==} - engines: {node: '>=6'} - tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -7963,14 +6284,6 @@ packages: peerDependencies: typescript: '>=4.2.0' - ts-jest@25.5.1: - resolution: {integrity: sha512-kHEUlZMK8fn8vkxDjwbHlxXRB9dHYpyzqKIGDNxbzs+Rz+ssNDSDNusEK8Fk/sDd4xE6iKoQLfFkFVaskmTJyw==} - engines: {node: '>= 8'} - hasBin: true - peerDependencies: - jest: '>=25 <26' - typescript: '>=3.4 <4.0' - ts-jest@28.0.8: resolution: {integrity: sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -8019,35 +6332,16 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} - tsdx@0.14.1: - resolution: {integrity: sha512-keHmFdCL2kx5nYFlBdbE3639HQ2v9iGedAFAajobrUTH2wfX0nLPdDhbHv+GHLQZqf0c5ur1XteE8ek/+Eyj5w==} - engines: {node: '>=10'} - hasBin: true - - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - - tslib@2.0.1: - resolution: {integrity: sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==} - tslib@2.8.0: resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} - tsutils@3.21.0: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - - tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - type-check@0.3.2: - resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} - engines: {node: '>= 0.8.0'} + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -8100,22 +6394,33 @@ packages: typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} - typescript@3.9.10: - resolution: {integrity: sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==} - engines: {node: '>=4.2.0'} - hasBin: true - typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.8.2: + resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + unicode-canonical-property-names-ecmascript@2.0.1: resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} engines: {node: '>=4'} @@ -8141,10 +6446,6 @@ packages: unified@9.2.2: resolution: {integrity: sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==} - union-value@1.0.1: - resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} - engines: {node: '>=0.10.0'} - unist-util-find-all-after@3.0.2: resolution: {integrity: sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==} @@ -8166,10 +6467,6 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - unset-value@1.0.0: - resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} - engines: {node: '>=0.10.0'} - update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -8182,32 +6479,15 @@ packages: urijs@1.19.11: resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} - urix@0.1.0: - resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} - deprecated: Please see https://github.com/lydell/urix#deprecated - url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - use@3.1.1: - resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} - engines: {node: '>=0.10.0'} - util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - uuid@3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - v8-compile-cache@2.4.0: resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} - v8-to-istanbul@4.1.4: - resolution: {integrity: sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==} - engines: {node: 8.x.x || >=10.10.0} - v8-to-istanbul@9.3.0: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} @@ -8215,17 +6495,10 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - validate-rfc@2.0.3: - resolution: {integrity: sha512-WS7CyAz/sfzx6DryOPZvprqz7uxHcQh1yhzDunNX1vidSmprfN7Og66VRpCyU21U82Vzkof5/bOIOKan3dEXLA==} - validator@9.4.1: resolution: {integrity: sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==} engines: {node: '>= 0.10'} - verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - vfile-message@2.0.4: resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} @@ -8237,6 +6510,15 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true + vite-plugin-dts@4.5.3: + resolution: {integrity: sha512-P64VnD00dR+e8S26ESoFELqc17+w7pKkwlBpgXteOljFyT0zDwD8hH4zXp49M/kciy//7ZbVXIwQCekBJjfWzA==} + peerDependencies: + typescript: '*' + vite: '*' + peerDependenciesMeta: + vite: + optional: true + vite-tsconfig-paths@4.2.3: resolution: {integrity: sha512-xVsA2xe6QSlzBujtWF8q2NYexh7PAUYfzJ4C8Axpe/7d2pcERYxuxGgph9F4f0iQO36g5tyGq6eBUYIssdUrVw==} peerDependencies: @@ -8245,15 +6527,16 @@ packages: vite: optional: true - vite@4.5.5: - resolution: {integrity: sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==} - engines: {node: ^14.18.0 || >=16.0.0} + vite@5.4.9: + resolution: {integrity: sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': '>= 14' + '@types/node': ^18.0.0 || >=20.0.0 less: '*' lightningcss: ^1.21.0 sass: '*' + sass-embedded: '*' stylus: '*' sugarss: '*' terser: ^5.4.0 @@ -8266,6 +6549,8 @@ packages: optional: true sass: optional: true + sass-embedded: + optional: true stylus: optional: true sugarss: @@ -8273,22 +6558,27 @@ packages: terser: optional: true - vite@5.4.9: - resolution: {integrity: sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==} - engines: {node: ^18.0.0 || >=20.0.0} + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: '@types/node': optional: true + jiti: + optional: true less: optional: true lightningcss: @@ -8303,6 +6593,10 @@ packages: optional: true terser: optional: true + tsx: + optional: true + yaml: + optional: true vitest@2.1.3: resolution: {integrity: sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA==} @@ -8329,13 +6623,13 @@ packages: jsdom: optional: true + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + w3c-hr-time@1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} deprecated: Use your platform's native performance.now() and performance.timeOrigin. - w3c-xmlserializer@1.1.2: - resolution: {integrity: sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==} - w3c-xmlserializer@3.0.0: resolution: {integrity: sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==} engines: {node: '>=12'} @@ -8343,17 +6637,10 @@ packages: walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - watchpack@2.4.0: - resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} - engines: {node: '>=10.13.0'} - watchpack@2.4.2: resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} engines: {node: '>=10.13.0'} - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -8378,16 +6665,10 @@ packages: webpack-cli: optional: true - whatwg-encoding@1.0.5: - resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} - whatwg-encoding@2.0.0: resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} engines: {node: '>=12'} - whatwg-mimetype@2.3.0: - resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==} - whatwg-mimetype@3.0.0: resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} engines: {node: '>=12'} @@ -8406,9 +6687,6 @@ packages: whatwg-url@6.5.0: resolution: {integrity: sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==} - whatwg-url@7.1.0: - resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} - which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -8420,9 +6698,6 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-module@2.0.1: - resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} - which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} @@ -8445,14 +6720,6 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - wrap-ansi@3.0.1: - resolution: {integrity: sha512-iXR3tDXpbnTpzjKSylUJRkLuOrEC7hwEB221cgn6wtF8wpmz28puFXAEfPT5zrjM3wahygB//VuWEr1vTkDcNQ==} - engines: {node: '>=4'} - - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -8471,22 +6738,6 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - write@1.0.3: - resolution: {integrity: sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==} - engines: {node: '>=4'} - - ws@7.5.10: - resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -8503,9 +6754,6 @@ packages: resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} hasBin: true - xml-name-validator@3.0.0: - resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==} - xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} @@ -8521,8 +6769,9 @@ packages: xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - xmldoc@1.3.0: - resolution: {integrity: sha512-y7IRWW6PvEnYQZNZFMRLNJw+p3pezM4nKYPfr15g4OOW9i8VpeydycFuipE2297OvZnh3jSb2pxOt9QpkZUVng==} + xmldoc@2.0.3: + resolution: {integrity: sha512-6gRk4NY/Jvg67xn7OzJuxLRsGgiXBaPUQplVJ/9l99uIugxh4FTOewYz5ic8WScj7Xx/2WvhENiQKwkK9RpE4w==} + engines: {node: '>=12.0.0'} xmldom@0.1.31: resolution: {integrity: sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==} @@ -8540,16 +6789,6 @@ packages: resolution: {integrity: sha512-pbozXtnzgTVU1XvRtel3Y0sRdAqRCsgsUoESJUIVd/PdeUzScMnPZyIq8QMFQoAi7pm0AWsEXVjdMnUEF/+CbQ==} engines: {node: '>=6.11.0'} - xslt-processor@0.11.7: - resolution: {integrity: sha512-66vcLzwSP4dAvzm4O+Lq20Su03ckrGaYn1kbdCNDp9HaaBZgHJJNZlrVSkvfEuKNvqd4wk9XGU5Rvi+eUJqf+w==} - - xslt@0.9.1: - resolution: {integrity: sha512-2eFkaiFRVkVzedBKYv3MUYmvvK9103NTNFGsyFhLim0Pad0q5yXp2j9tQM2lFW1gFr9fSXV70RRrdcRM7YdRcg==} - engines: {node: '>=0.10.33'} - - y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} - y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -8564,10 +6803,6 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} - yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} @@ -8576,10 +6811,6 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - yargs@15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} - yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -8599,7 +6830,7 @@ snapshots: transitivePeerDependencies: - encoding - '@adobe/css-tools@4.4.0': {} + '@alloc/quick-lru@5.2.0': {} '@ampproject/remapping@2.3.0': dependencies: @@ -8681,20 +6912,6 @@ snapshots: regexpu-core: 6.1.1 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.0.3(@babel/core@7.25.8)': - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@babel/helper-compilation-targets': 7.25.7 - '@babel/helper-module-imports': 7.25.7(supports-color@9.4.0) - '@babel/helper-plugin-utils': 7.25.7 - '@babel/traverse': 7.25.7(supports-color@9.4.0) - debug: 4.3.7(supports-color@9.4.0) - lodash.debounce: 4.0.8 - resolve: 1.22.8 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.8)': dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) @@ -8833,14 +7050,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.25.8)': - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) - '@babel/helper-plugin-utils': 7.25.7 - transitivePeerDependencies: - - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.8)': dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) @@ -8885,11 +7094,6 @@ snapshots: '@babel/core': 7.25.8(supports-color@9.4.0) '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-jsx@7.25.7(@babel/core@7.25.8)': - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.8)': dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) @@ -9369,10 +7573,10 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@cnakazawa/watch@1.0.4': + '@emnapi/runtime@1.3.1': dependencies: - exec-sh: 0.3.6 - minimist: 1.2.8 + tslib: 2.8.1 + optional: true '@es-joy/jsdoccomment@0.36.1': dependencies: @@ -9383,148 +7587,174 @@ snapshots: '@esbuild/aix-ppc64@0.21.5': optional: true - '@esbuild/android-arm64@0.18.20': + '@esbuild/aix-ppc64@0.27.4': optional: true '@esbuild/android-arm64@0.21.5': optional: true - '@esbuild/android-arm@0.18.20': + '@esbuild/android-arm64@0.27.4': optional: true '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-x64@0.18.20': + '@esbuild/android-arm@0.27.4': optional: true '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.18.20': + '@esbuild/android-x64@0.27.4': optional: true '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-x64@0.18.20': + '@esbuild/darwin-arm64@0.27.4': optional: true '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.18.20': + '@esbuild/darwin-x64@0.27.4': optional: true '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.18.20': + '@esbuild/freebsd-arm64@0.27.4': optional: true '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/linux-arm64@0.18.20': + '@esbuild/freebsd-x64@0.27.4': optional: true '@esbuild/linux-arm64@0.21.5': optional: true - '@esbuild/linux-arm@0.18.20': + '@esbuild/linux-arm64@0.27.4': optional: true '@esbuild/linux-arm@0.21.5': optional: true - '@esbuild/linux-ia32@0.18.20': + '@esbuild/linux-arm@0.27.4': optional: true '@esbuild/linux-ia32@0.21.5': optional: true - '@esbuild/linux-loong64@0.14.54': - optional: true - - '@esbuild/linux-loong64@0.18.20': + '@esbuild/linux-ia32@0.27.4': optional: true '@esbuild/linux-loong64@0.21.5': optional: true - '@esbuild/linux-mips64el@0.18.20': + '@esbuild/linux-loong64@0.27.4': optional: true '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/linux-ppc64@0.18.20': + '@esbuild/linux-mips64el@0.27.4': optional: true '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.18.20': + '@esbuild/linux-ppc64@0.27.4': optional: true '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/linux-s390x@0.18.20': + '@esbuild/linux-riscv64@0.27.4': optional: true '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/linux-x64@0.18.20': + '@esbuild/linux-s390x@0.27.4': optional: true '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/netbsd-x64@0.18.20': + '@esbuild/linux-x64@0.27.4': + optional: true + + '@esbuild/netbsd-arm64@0.27.4': optional: true '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.18.20': + '@esbuild/netbsd-x64@0.27.4': + optional: true + + '@esbuild/openbsd-arm64@0.27.4': optional: true '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/sunos-x64@0.18.20': + '@esbuild/openbsd-x64@0.27.4': + optional: true + + '@esbuild/openharmony-arm64@0.27.4': optional: true '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/win32-arm64@0.18.20': + '@esbuild/sunos-x64@0.27.4': optional: true '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/win32-ia32@0.18.20': + '@esbuild/win32-arm64@0.27.4': optional: true '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-x64@0.18.20': + '@esbuild/win32-ia32@0.27.4': optional: true '@esbuild/win32-x64@0.21.5': optional: true + '@esbuild/win32-x64@0.27.4': + optional: true + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': dependencies: eslint: 8.57.1 eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.4.0(eslint@9.21.0(jiti@2.4.2))': + dependencies: + eslint: 9.21.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.12.1': {} + '@eslint/config-array@0.19.2': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.3.7(supports-color@9.4.0) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.12.0': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 @@ -9539,7 +7769,30 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.57.1': {} + '@eslint/eslintrc@3.3.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.7(supports-color@9.4.0) + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@eslint/js@9.21.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.2.7': + dependencies: + '@eslint/core': 0.12.0 + levn: 0.4.1 '@esm2cjs/execa@6.1.1-cjs.1': dependencies: @@ -9571,6 +7824,39 @@ snapshots: '@esm2cjs/strip-final-newline@3.0.1-cjs.0': {} + '@foliojs-fork/fontkit@1.9.2': + dependencies: + '@foliojs-fork/restructure': 2.0.2 + brotli: 1.3.3 + clone: 1.0.4 + deep-equal: 1.1.2 + dfa: 1.2.0 + tiny-inflate: 1.0.3 + unicode-properties: 1.4.1 + unicode-trie: 2.0.0 + + '@foliojs-fork/linebreak@1.1.2': + dependencies: + base64-js: 1.3.1 + unicode-trie: 2.0.0 + + '@foliojs-fork/pdfkit@0.15.3': + dependencies: + '@foliojs-fork/fontkit': 1.9.2 + '@foliojs-fork/linebreak': 1.1.2 + crypto-js: 4.2.0 + jpeg-exif: 1.1.4 + png-js: 1.0.0 + + '@foliojs-fork/restructure@2.0.2': {} + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -9583,6 +7869,85 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.2': {} + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.3.1 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -9602,68 +7967,15 @@ snapshots: '@istanbuljs/schema@0.1.3': {} - '@jest/console@25.5.0': - dependencies: - '@jest/types': 25.5.0 - chalk: 3.0.0 - jest-message-util: 25.5.0 - jest-util: 25.5.0 - slash: 3.0.0 - '@jest/console@28.1.3': dependencies: '@jest/types': 28.1.3 - '@types/node': 18.19.57 + '@types/node': 22.19.15 chalk: 4.1.2 jest-message-util: 28.1.3 jest-util: 28.1.3 slash: 3.0.0 - '@jest/console@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@types/node': 18.19.57 - chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - - '@jest/core@25.5.4': - dependencies: - '@jest/console': 25.5.0 - '@jest/reporters': 25.5.1 - '@jest/test-result': 25.5.0 - '@jest/transform': 25.5.1 - '@jest/types': 25.5.0 - ansi-escapes: 4.3.2 - chalk: 3.0.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 25.5.0 - jest-config: 25.5.4 - jest-haste-map: 25.5.1 - jest-message-util: 25.5.0 - jest-regex-util: 25.2.6 - jest-resolve: 25.5.1 - jest-resolve-dependencies: 25.5.4 - jest-runner: 25.5.4 - jest-runtime: 25.5.4 - jest-snapshot: 25.5.1 - jest-util: 25.5.0 - jest-validate: 25.5.0 - jest-watcher: 25.5.0 - micromatch: 4.0.8 - p-each-series: 2.2.0 - realpath-native: 2.0.0 - rimraf: 3.0.2 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate - '@jest/core@28.1.3': dependencies: '@jest/console': 28.1.3 @@ -9671,14 +7983,14 @@ snapshots: '@jest/test-result': 28.1.3 '@jest/transform': 28.1.3(supports-color@9.4.0) '@jest/types': 28.1.3 - '@types/node': 18.19.57 + '@types/node': 22.19.15 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 28.1.3 - jest-config: 28.1.3(@types/node@18.19.57) + jest-config: 28.1.3(@types/node@22.19.15) jest-haste-map: 28.1.3 jest-message-util: 28.1.3 jest-regex-util: 28.0.2 @@ -9699,69 +8011,17 @@ snapshots: - supports-color - ts-node - '@jest/core@29.5.0': - dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.5.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.6.3 - '@types/node': 18.19.57 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.5.0(@types/node@18.19.57) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.5.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.5.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - - '@jest/environment@25.5.0': - dependencies: - '@jest/fake-timers': 25.5.0 - '@jest/types': 25.5.0 - jest-mock: 25.5.0 - '@jest/environment@28.1.3': dependencies: '@jest/fake-timers': 28.1.3 '@jest/types': 28.1.3 - '@types/node': 18.19.57 + '@types/node': 22.19.15 jest-mock: 28.1.3 - '@jest/environment@29.7.0': - dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 18.19.57 - jest-mock: 29.7.0 - '@jest/expect-utils@28.1.3': dependencies: jest-get-type: 28.0.2 - '@jest/expect-utils@29.7.0': - dependencies: - jest-get-type: 29.6.3 - '@jest/expect@28.1.3(supports-color@9.4.0)': dependencies: expect: 28.1.3 @@ -9769,45 +8029,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/expect@29.7.0': - dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - '@jest/fake-timers@25.5.0': - dependencies: - '@jest/types': 25.5.0 - jest-message-util: 25.5.0 - jest-mock: 25.5.0 - jest-util: 25.5.0 - lolex: 5.1.2 - '@jest/fake-timers@28.1.3': dependencies: '@jest/types': 28.1.3 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.19.57 + '@types/node': 22.19.15 jest-message-util: 28.1.3 jest-mock: 28.1.3 jest-util: 28.1.3 - '@jest/fake-timers@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 18.19.57 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - '@jest/globals@25.5.2': - dependencies: - '@jest/environment': 25.5.0 - '@jest/types': 25.5.0 - expect: 25.5.0 - '@jest/globals@28.1.3(supports-color@9.4.0)': dependencies: '@jest/environment': 28.1.3 @@ -9816,46 +8046,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/globals@29.7.0': - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 - transitivePeerDependencies: - - supports-color - - '@jest/reporters@25.5.1': - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 25.5.0 - '@jest/test-result': 25.5.0 - '@jest/transform': 25.5.1 - '@jest/types': 25.5.0 - chalk: 3.0.0 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 4.0.3 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.7 - jest-haste-map: 25.5.1 - jest-resolve: 25.5.1 - jest-util: 25.5.0 - jest-worker: 25.5.0 - slash: 3.0.0 - source-map: 0.6.1 - string-length: 3.1.0 - terminal-link: 2.1.1 - v8-to-istanbul: 4.1.4 - optionalDependencies: - node-notifier: 6.0.0 - transitivePeerDependencies: - - supports-color - '@jest/reporters@28.1.3': dependencies: '@bcoe/v8-coverage': 0.2.3 @@ -9864,7 +8054,7 @@ snapshots: '@jest/transform': 28.1.3(supports-color@9.4.0) '@jest/types': 28.1.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 18.19.57 + '@types/node': 22.19.15 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -9886,183 +8076,43 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/reporters@29.5.0': - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 18.19.57 - chalk: 4.1.2 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 5.2.1(supports-color@9.4.0) - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.7 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.3.0 - transitivePeerDependencies: - - supports-color - '@jest/schemas@28.1.3': dependencies: '@sinclair/typebox': 0.24.51 - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - - '@jest/source-map@25.5.0': - dependencies: - callsites: 3.1.0 - graceful-fs: 4.2.11 - source-map: 0.6.1 - '@jest/source-map@28.1.2': dependencies: '@jridgewell/trace-mapping': 0.3.25 callsites: 3.1.0 graceful-fs: 4.2.11 - '@jest/source-map@29.6.3': - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - callsites: 3.1.0 - graceful-fs: 4.2.11 - - '@jest/test-result@25.5.0': - dependencies: - '@jest/console': 25.5.0 - '@jest/types': 25.5.0 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 - '@jest/test-result@28.1.3': dependencies: '@jest/console': 28.1.3 '@jest/types': 28.1.3 '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 - - '@jest/test-result@29.7.0': - dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 - - '@jest/test-sequencer@25.5.4': - dependencies: - '@jest/test-result': 25.5.0 - graceful-fs: 4.2.11 - jest-haste-map: 25.5.1 - jest-runner: 25.5.4 - jest-runtime: 25.5.4 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate - - '@jest/test-sequencer@28.1.3': - dependencies: - '@jest/test-result': 28.1.3 - graceful-fs: 4.2.11 - jest-haste-map: 28.1.3 - slash: 3.0.0 - - '@jest/test-sequencer@29.7.0': - dependencies: - '@jest/test-result': 29.7.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - slash: 3.0.0 - - '@jest/transform@25.5.1': - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@jest/types': 25.5.0 - babel-plugin-istanbul: 6.1.1(supports-color@9.4.0) - chalk: 3.0.0 - convert-source-map: 1.9.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 25.5.1 - jest-regex-util: 25.2.6 - jest-util: 25.5.0 - micromatch: 4.0.8 - pirates: 4.0.6 - realpath-native: 2.0.0 - slash: 3.0.0 - source-map: 0.6.1 - write-file-atomic: 3.0.3 - transitivePeerDependencies: - - supports-color - - '@jest/transform@28.1.3(supports-color@9.4.0)': - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@jest/types': 28.1.3 - '@jridgewell/trace-mapping': 0.3.25 - babel-plugin-istanbul: 6.1.1(supports-color@9.4.0) - chalk: 4.1.2 - convert-source-map: 1.9.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 28.1.3 - jest-regex-util: 28.0.2 - jest-util: 28.1.3 - micromatch: 4.0.8 - pirates: 4.0.6 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - - '@jest/transform@29.5.0': - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - babel-plugin-istanbul: 6.1.1(supports-color@9.4.0) - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@28.1.3': + dependencies: + '@jest/test-result': 28.1.3 graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.8 - pirates: 4.0.6 + jest-haste-map: 28.1.3 slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - '@jest/transform@29.7.0': + '@jest/transform@28.1.3(supports-color@9.4.0)': dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) - '@jest/types': 29.6.3 + '@jest/types': 28.1.3 '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1(supports-color@9.4.0) chalk: 4.1.2 - convert-source-map: 2.0.0 + convert-source-map: 1.9.0 fast-json-stable-stringify: 2.1.0 graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 + jest-haste-map: 28.1.3 + jest-regex-util: 28.0.2 + jest-util: 28.1.3 micromatch: 4.0.8 pirates: 4.0.6 slash: 3.0.0 @@ -10070,28 +8120,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/types@25.5.0': - dependencies: - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 1.1.2 - '@types/yargs': 15.0.19 - chalk: 3.0.0 - '@jest/types@28.1.3': dependencies: '@jest/schemas': 28.1.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 18.19.57 - '@types/yargs': 17.0.33 - chalk: 4.1.2 - - '@jest/types@29.6.3': - dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 18.19.57 + '@types/node': 22.19.15 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -10117,22 +8151,70 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@jsep-plugin/assignment@1.3.0(jsep@1.4.0)': + '@microsoft/api-extractor-model@7.30.4(@types/node@22.19.15)': dependencies: - jsep: 1.4.0 + '@microsoft/tsdoc': 0.15.1 + '@microsoft/tsdoc-config': 0.17.1 + '@rushstack/node-core-library': 5.12.0(@types/node@22.19.15) + transitivePeerDependencies: + - '@types/node' - '@jsep-plugin/regex@1.0.4(jsep@1.4.0)': + '@microsoft/api-extractor@7.52.1(@types/node@22.19.15)': dependencies: - jsep: 1.4.0 + '@microsoft/api-extractor-model': 7.30.4(@types/node@22.19.15) + '@microsoft/tsdoc': 0.15.1 + '@microsoft/tsdoc-config': 0.17.1 + '@rushstack/node-core-library': 5.12.0(@types/node@22.19.15) + '@rushstack/rig-package': 0.5.3 + '@rushstack/terminal': 0.15.1(@types/node@22.19.15) + '@rushstack/ts-command-line': 4.23.6(@types/node@22.19.15) + lodash: 4.17.21 + minimatch: 3.0.8 + resolve: 1.22.8 + semver: 7.5.4 + source-map: 0.6.1 + typescript: 5.8.2 + transitivePeerDependencies: + - '@types/node' - '@microsoft/tsdoc-config@0.17.0': + '@microsoft/tsdoc-config@0.17.1': dependencies: - '@microsoft/tsdoc': 0.15.0 + '@microsoft/tsdoc': 0.15.1 ajv: 8.12.0 jju: 1.4.0 resolve: 1.22.8 - '@microsoft/tsdoc@0.15.0': {} + '@microsoft/tsdoc@0.15.1': {} + + '@next/env@15.2.3': {} + + '@next/eslint-plugin-next@15.2.1': + dependencies: + fast-glob: 3.3.1 + + '@next/swc-darwin-arm64@15.2.3': + optional: true + + '@next/swc-darwin-x64@15.2.3': + optional: true + + '@next/swc-linux-arm64-gnu@15.2.3': + optional: true + + '@next/swc-linux-arm64-musl@15.2.3': + optional: true + + '@next/swc-linux-x64-gnu@15.2.3': + optional: true + + '@next/swc-linux-x64-musl@15.2.3': + optional: true + + '@next/swc-win32-arm64-msvc@15.2.3': + optional: true + + '@next/swc-win32-x64-msvc@15.2.3': + optional: true '@nodelib/fs.scandir@2.1.5': dependencies: @@ -10146,243 +8228,144 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@nolyfill/is-core-module@1.0.39': {} + '@pkgjs/parseargs@0.11.0': optional: true '@polka/url@1.0.0-next.28': {} - '@rollup/plugin-babel@5.3.1(@babel/core@7.25.8)(@types/babel__core@7.20.5)(rollup@1.32.1)': + '@rollup/plugin-terser@0.4.4(rollup@4.59.0)': dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@babel/helper-module-imports': 7.25.7(supports-color@9.4.0) - '@rollup/pluginutils': 3.1.0(rollup@1.32.1) - rollup: 1.32.1 + serialize-javascript: 6.0.2 + smob: 1.5.0 + terser: 5.36.0 optionalDependencies: - '@types/babel__core': 7.20.5 - transitivePeerDependencies: - - supports-color - - '@rollup/plugin-commonjs@11.1.0(rollup@1.32.1)': - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@1.32.1) - commondir: 1.0.1 - estree-walker: 1.0.1 - glob: 7.2.3 - is-reference: 1.2.1 - magic-string: 0.25.9 - resolve: 1.22.8 - rollup: 1.32.1 + rollup: 4.59.0 - '@rollup/plugin-json@4.1.0(rollup@1.32.1)': + '@rollup/plugin-url@8.0.2(rollup@4.59.0)': dependencies: - '@rollup/pluginutils': 3.1.0(rollup@1.32.1) - rollup: 1.32.1 + '@rollup/pluginutils': 5.1.4(rollup@4.59.0) + make-dir: 3.1.0 + mime: 3.0.0 + optionalDependencies: + rollup: 4.59.0 - '@rollup/plugin-node-resolve@9.0.0(rollup@1.32.1)': + '@rollup/pluginutils@5.1.4(rollup@4.59.0)': dependencies: - '@rollup/pluginutils': 3.1.0(rollup@1.32.1) - '@types/resolve': 1.17.1 - builtin-modules: 3.3.0 - deepmerge: 4.3.1 - is-module: 1.0.0 - resolve: 1.22.8 - rollup: 1.32.1 + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.59.0 - '@rollup/plugin-replace@2.4.2(rollup@1.32.1)': - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@1.32.1) - magic-string: 0.25.9 - rollup: 1.32.1 + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true - '@rollup/pluginutils@3.1.0(rollup@1.32.1)': - dependencies: - '@types/estree': 0.0.39 - estree-walker: 1.0.1 - picomatch: 2.3.1 - rollup: 1.32.1 + '@rollup/rollup-android-arm64@4.59.0': + optional: true - '@rollup/rollup-android-arm-eabi@4.24.0': + '@rollup/rollup-darwin-arm64@4.59.0': optional: true - '@rollup/rollup-android-arm64@4.24.0': + '@rollup/rollup-darwin-x64@4.59.0': optional: true - '@rollup/rollup-darwin-arm64@4.24.0': + '@rollup/rollup-freebsd-arm64@4.59.0': optional: true - '@rollup/rollup-darwin-x64@4.24.0': + '@rollup/rollup-freebsd-x64@4.59.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.24.0': + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.24.0': + '@rollup/rollup-linux-arm-musleabihf@4.59.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.24.0': + '@rollup/rollup-linux-arm64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.24.0': + '@rollup/rollup-linux-arm64-musl@4.59.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': + '@rollup/rollup-linux-loong64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.24.0': + '@rollup/rollup-linux-loong64-musl@4.59.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.24.0': + '@rollup/rollup-linux-ppc64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.24.0': + '@rollup/rollup-linux-ppc64-musl@4.59.0': optional: true - '@rollup/rollup-linux-x64-musl@4.24.0': + '@rollup/rollup-linux-riscv64-gnu@4.59.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.24.0': + '@rollup/rollup-linux-riscv64-musl@4.59.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.24.0': + '@rollup/rollup-linux-s390x-gnu@4.59.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.24.0': + '@rollup/rollup-linux-x64-gnu@4.59.0': optional: true - '@rtsao/scc@1.1.0': {} + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true - '@rushstack/eslint-config@4.0.2(eslint@8.57.1)(typescript@5.6.3)': - dependencies: - '@rushstack/eslint-patch': 1.10.4 - '@rushstack/eslint-plugin': 0.16.1(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/eslint-plugin-packlets': 0.9.2(eslint@8.57.1)(typescript@5.6.3) - '@rushstack/eslint-plugin-security': 0.8.3(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/eslint-plugin': 8.1.0(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/parser': 8.1.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.1.0(eslint@8.57.1)(typescript@5.6.3) - eslint: 8.57.1 - eslint-plugin-promise: 6.1.1(eslint@8.57.1) - eslint-plugin-react: 7.33.2(eslint@8.57.1) - eslint-plugin-tsdoc: 0.3.0 - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true - '@rushstack/eslint-patch@1.10.4': {} + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true - '@rushstack/eslint-plugin-packlets@0.9.2(eslint@8.57.1)(typescript@5.6.3)': - dependencies: - '@rushstack/tree-pattern': 0.3.4 - '@typescript-eslint/utils': 6.19.1(eslint@8.57.1)(typescript@5.6.3) - eslint: 8.57.1 - transitivePeerDependencies: - - supports-color - - typescript + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true - '@rushstack/eslint-plugin-security@0.8.3(eslint@8.57.1)(typescript@5.6.3)': - dependencies: - '@rushstack/tree-pattern': 0.3.4 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.1)(typescript@5.6.3) - eslint: 8.57.1 - transitivePeerDependencies: - - supports-color - - typescript + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true - '@rushstack/eslint-plugin@0.16.1(eslint@8.57.1)(typescript@5.6.3)': - dependencies: - '@rushstack/tree-pattern': 0.3.4 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.1)(typescript@5.6.3) - eslint: 8.57.1 - transitivePeerDependencies: - - supports-color - - typescript + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true - '@rushstack/heft-config-file@0.15.8(@types/node@18.19.57)': - dependencies: - '@rushstack/node-core-library': 5.9.0(@types/node@18.19.57) - '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.14.2(@types/node@18.19.57) - jsonpath-plus: 10.1.0 - transitivePeerDependencies: - - '@types/node' + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true - '@rushstack/heft-jest-plugin@0.12.18(@rushstack/heft@0.68.6(@types/node@18.19.57))(@types/node@18.19.57)(jest-environment-node@29.7.0)': - dependencies: - '@jest/core': 29.5.0 - '@jest/reporters': 29.5.0 - '@jest/transform': 29.5.0 - '@rushstack/heft': 0.68.6(@types/node@18.19.57) - '@rushstack/heft-config-file': 0.15.8(@types/node@18.19.57) - '@rushstack/node-core-library': 5.9.0(@types/node@18.19.57) - '@rushstack/terminal': 0.14.2(@types/node@18.19.57) - jest-config: 29.5.0(@types/node@18.19.57) - jest-resolve: 29.5.0 - jest-snapshot: 29.5.0 - lodash: 4.17.21 - optionalDependencies: - jest-environment-node: 29.7.0 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - node-notifier - - supports-color - - ts-node + '@rtsao/scc@1.1.0': {} - '@rushstack/heft@0.68.6(@types/node@18.19.57)': - dependencies: - '@rushstack/heft-config-file': 0.15.8(@types/node@18.19.57) - '@rushstack/node-core-library': 5.9.0(@types/node@18.19.57) - '@rushstack/operation-graph': 0.2.33(@types/node@18.19.57) - '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.14.2(@types/node@18.19.57) - '@rushstack/ts-command-line': 4.23.0(@types/node@18.19.57) - '@types/tapable': 1.0.6 - fast-glob: 3.3.2 - git-repo-info: 2.1.1 - ignore: 5.1.9 - tapable: 1.1.3 - watchpack: 2.4.0 - transitivePeerDependencies: - - '@types/node' + '@rushstack/eslint-patch@1.10.4': {} - '@rushstack/node-core-library@5.9.0(@types/node@18.19.57)': + '@rushstack/node-core-library@5.12.0(@types/node@22.19.15)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) ajv-formats: 3.0.1 - fs-extra: 7.0.1 + fs-extra: 11.3.0 import-lazy: 4.0.0 jju: 1.4.0 resolve: 1.22.8 semver: 7.5.4 optionalDependencies: - '@types/node': 18.19.57 - - '@rushstack/operation-graph@0.2.33(@types/node@18.19.57)': - dependencies: - '@rushstack/node-core-library': 5.9.0(@types/node@18.19.57) - '@rushstack/terminal': 0.14.2(@types/node@18.19.57) - optionalDependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 '@rushstack/rig-package@0.5.3': dependencies: resolve: 1.22.8 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.14.2(@types/node@18.19.57)': + '@rushstack/terminal@0.15.1(@types/node@22.19.15)': dependencies: - '@rushstack/node-core-library': 5.9.0(@types/node@18.19.57) + '@rushstack/node-core-library': 5.12.0(@types/node@22.19.15) supports-color: 8.1.1 optionalDependencies: - '@types/node': 18.19.57 - - '@rushstack/tree-pattern@0.3.4': {} + '@types/node': 22.19.15 - '@rushstack/ts-command-line@4.23.0(@types/node@18.19.57)': + '@rushstack/ts-command-line@4.23.6(@types/node@22.19.15)': dependencies: - '@rushstack/terminal': 0.14.2(@types/node@18.19.57) + '@rushstack/terminal': 0.15.1(@types/node@22.19.15) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -10391,41 +8374,14 @@ snapshots: '@sinclair/typebox@0.24.51': {} - '@sinclair/typebox@0.27.8': {} - '@sinonjs/commons@1.8.6': dependencies: type-detect: 4.0.8 - '@sinonjs/commons@3.0.1': - dependencies: - type-detect: 4.0.8 - - '@sinonjs/fake-timers@10.3.0': - dependencies: - '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers@9.1.2': dependencies: '@sinonjs/commons': 1.8.6 - '@size-limit/esbuild@7.0.8(size-limit@7.0.8)': - dependencies: - esbuild: 0.14.54 - nanoid: 3.3.7 - size-limit: 7.0.8 - - '@size-limit/file@7.0.8(size-limit@7.0.8)': - dependencies: - semver: 7.3.5 - size-limit: 7.0.8 - - '@size-limit/preset-small-lib@7.0.8(size-limit@7.0.8)': - dependencies: - '@size-limit/esbuild': 7.0.8(size-limit@7.0.8) - '@size-limit/file': 7.0.8(size-limit@7.0.8) - size-limit: 7.0.8 - '@stylelint/postcss-css-in-js@0.37.3(postcss-syntax@0.36.2(postcss@7.0.39))(postcss@7.0.39)': dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) @@ -10443,39 +8399,78 @@ snapshots: transitivePeerDependencies: - supports-color - '@swc/helpers@0.3.17': - dependencies: - tslib: 2.8.0 + '@swc/counter@0.1.3': {} - '@testing-library/dom@8.20.1': + '@swc/helpers@0.5.15': dependencies: - '@babel/code-frame': 7.25.7 - '@babel/runtime': 7.25.7 - '@types/aria-query': 5.0.4 - aria-query: 5.1.3 - chalk: 4.1.2 - dom-accessibility-api: 0.5.16 - lz-string: 1.5.0 - pretty-format: 27.5.1 + tslib: 2.8.1 - '@testing-library/jest-dom@5.17.0': + '@tailwindcss/node@4.0.9': dependencies: - '@adobe/css-tools': 4.4.0 - '@babel/runtime': 7.25.7 - '@types/testing-library__jest-dom': 5.14.9 - aria-query: 5.3.2 - chalk: 3.0.0 - css.escape: 1.5.1 - dom-accessibility-api: 0.5.16 - lodash: 4.17.21 - redent: 3.0.0 + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + tailwindcss: 4.0.9 + + '@tailwindcss/oxide-android-arm64@4.0.9': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.0.9': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.0.9': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.0.9': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.9': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.0.9': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.0.9': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.0.9': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.0.9': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.0.9': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.0.9': + optional: true + + '@tailwindcss/oxide@4.0.9': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.0.9 + '@tailwindcss/oxide-darwin-arm64': 4.0.9 + '@tailwindcss/oxide-darwin-x64': 4.0.9 + '@tailwindcss/oxide-freebsd-x64': 4.0.9 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.9 + '@tailwindcss/oxide-linux-arm64-gnu': 4.0.9 + '@tailwindcss/oxide-linux-arm64-musl': 4.0.9 + '@tailwindcss/oxide-linux-x64-gnu': 4.0.9 + '@tailwindcss/oxide-linux-x64-musl': 4.0.9 + '@tailwindcss/oxide-win32-arm64-msvc': 4.0.9 + '@tailwindcss/oxide-win32-x64-msvc': 4.0.9 + + '@tailwindcss/postcss@4.0.9': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.0.9 + '@tailwindcss/oxide': 4.0.9 + lightningcss: 1.29.1 + postcss: 8.5.3 + tailwindcss: 4.0.9 '@tootallnate/once@2.0.0': {} '@types/argparse@1.0.38': {} - '@types/aria-query@5.0.4': {} - '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.25.8 @@ -10497,17 +8492,13 @@ snapshots: dependencies: '@babel/types': 7.25.8 - '@types/deep-freeze@0.1.5': {} - - '@types/eslint-visitor-keys@1.0.0': {} - - '@types/estree@0.0.39': {} - '@types/estree@1.0.6': {} + '@types/estree@1.0.8': {} + '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 '@types/istanbul-lib-coverage@2.0.6': {} @@ -10515,20 +8506,10 @@ snapshots: dependencies: '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports@1.1.2': - dependencies: - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-lib-report': 3.0.3 - '@types/istanbul-reports@3.0.4': dependencies: '@types/istanbul-lib-report': 3.0.3 - '@types/jest@25.2.3': - dependencies: - jest-diff: 25.5.0 - pretty-format: 25.5.0 - '@types/jest@27.5.2': dependencies: jest-matcher-utils: 27.5.1 @@ -10536,7 +8517,7 @@ snapshots: '@types/jsdom@16.2.15': dependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 '@types/parse5': 6.0.3 '@types/tough-cookie': 4.0.5 @@ -10552,12 +8533,16 @@ snapshots: '@types/node-forge@1.3.11': dependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 '@types/node@18.19.57': dependencies: undici-types: 5.26.5 + '@types/node@22.19.15': + dependencies: + undici-types: 6.21.0 + '@types/normalize-package-data@2.4.4': {} '@types/parse-json@4.0.2': {} @@ -10568,29 +8553,25 @@ snapshots: '@types/pdfkit@0.13.5': dependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 - '@types/pdfmake@0.1.21': + '@types/pdfmake@0.2.11': dependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 '@types/pdfkit': 0.13.5 - '@types/prettier@1.19.1': {} - '@types/prettier@2.7.3': {} - '@types/resolve@1.17.1': + '@types/react-dom@19.0.4(@types/react@19.0.10)': dependencies: - '@types/node': 18.19.57 + '@types/react': 19.0.10 - '@types/semver@7.5.8': {} - - '@types/stack-utils@1.0.1': {} + '@types/react@19.0.10': + dependencies: + csstype: 3.1.3 '@types/stack-utils@2.0.3': {} - '@types/tapable@1.0.6': {} - '@types/testing-library__jest-dom@5.14.9': dependencies: '@types/jest': 27.5.2 @@ -10601,45 +8582,10 @@ snapshots: '@types/yargs-parser@21.0.3': {} - '@types/yargs@15.0.19': - dependencies: - '@types/yargs-parser': 21.0.3 - '@types/yargs@17.0.33': dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@2.34.0(@typescript-eslint/parser@2.34.0(eslint@6.8.0)(typescript@3.9.10))(eslint@6.8.0)(typescript@3.9.10)': - dependencies: - '@typescript-eslint/experimental-utils': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - '@typescript-eslint/parser': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - eslint: 6.8.0 - functional-red-black-tree: 1.0.1 - regexpp: 3.2.0 - tsutils: 3.21.0(typescript@3.9.10) - optionalDependencies: - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/eslint-plugin@8.1.0(@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.1.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/type-utils': 8.1.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/utils': 8.1.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.1.0 - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare: 1.4.0 - ts-api-utils: 1.4.0(typescript@5.6.3) - optionalDependencies: - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/eslint-plugin@8.13.0(@typescript-eslint/parser@8.13.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -10658,39 +8604,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/experimental-utils@2.34.0(eslint@6.8.0)(typescript@3.9.10)': - dependencies: - '@types/json-schema': 7.0.15 - '@typescript-eslint/typescript-estree': 2.34.0(typescript@3.9.10) - eslint: 6.8.0 - eslint-scope: 5.1.1 - eslint-utils: 2.1.0 - transitivePeerDependencies: - - supports-color - - typescript - - '@typescript-eslint/parser@2.34.0(eslint@6.8.0)(typescript@3.9.10)': - dependencies: - '@types/eslint-visitor-keys': 1.0.0 - '@typescript-eslint/experimental-utils': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - '@typescript-eslint/typescript-estree': 2.34.0(typescript@3.9.10) - eslint: 6.8.0 - eslint-visitor-keys: 1.3.0 - optionalDependencies: - typescript: 3.9.10 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.1.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2))(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2)': dependencies: - '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.1.0 - debug: 4.3.7(supports-color@9.4.0) - eslint: 8.57.1 + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.13.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2) + '@typescript-eslint/scope-manager': 8.13.0 + '@typescript-eslint/type-utils': 8.13.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2) + '@typescript-eslint/utils': 8.13.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2) + '@typescript-eslint/visitor-keys': 8.13.0 + eslint: 9.21.0(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.4.0(typescript@5.7.2) optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.2 transitivePeerDependencies: - supports-color @@ -10707,33 +8635,24 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@6.19.1': - dependencies: - '@typescript-eslint/types': 6.19.1 - '@typescript-eslint/visitor-keys': 6.19.1 - - '@typescript-eslint/scope-manager@8.1.0': - dependencies: - '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/visitor-keys': 8.1.0 - - '@typescript-eslint/scope-manager@8.13.0': + '@typescript-eslint/parser@8.13.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2)': dependencies: + '@typescript-eslint/scope-manager': 8.13.0 '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.7.2) '@typescript-eslint/visitor-keys': 8.13.0 - - '@typescript-eslint/type-utils@8.1.0(eslint@8.57.1)(typescript@5.6.3)': - dependencies: - '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.1.0(eslint@8.57.1)(typescript@5.6.3) debug: 4.3.7(supports-color@9.4.0) - ts-api-utils: 1.4.0(typescript@5.6.3) + eslint: 9.21.0(jiti@2.4.2) optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.2 transitivePeerDependencies: - - eslint - supports-color + '@typescript-eslint/scope-manager@8.13.0': + dependencies: + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/visitor-keys': 8.13.0 + '@typescript-eslint/type-utils@8.13.0(eslint@8.57.1)(typescript@5.6.3)': dependencies: '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) @@ -10746,47 +8665,26 @@ snapshots: - eslint - supports-color - '@typescript-eslint/types@6.19.1': {} - - '@typescript-eslint/types@8.1.0': {} - - '@typescript-eslint/types@8.13.0': {} - - '@typescript-eslint/typescript-estree@2.34.0(typescript@3.9.10)': + '@typescript-eslint/type-utils@8.13.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2)': dependencies: + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.7.2) + '@typescript-eslint/utils': 8.13.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2) debug: 4.3.7(supports-color@9.4.0) - eslint-visitor-keys: 1.3.0 - glob: 7.2.3 - is-glob: 4.0.3 - lodash: 4.17.21 - semver: 7.6.3 - tsutils: 3.21.0(typescript@3.9.10) + ts-api-utils: 1.4.0(typescript@5.7.2) optionalDependencies: - typescript: 3.9.10 + typescript: 5.7.2 transitivePeerDependencies: + - eslint - supports-color - '@typescript-eslint/typescript-estree@6.19.1(typescript@5.6.3)': - dependencies: - '@typescript-eslint/types': 6.19.1 - '@typescript-eslint/visitor-keys': 6.19.1 - debug: 4.3.7(supports-color@9.4.0) - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.3 - semver: 7.6.3 - ts-api-utils: 1.4.0(typescript@5.6.3) - optionalDependencies: - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color + '@typescript-eslint/types@8.13.0': {} - '@typescript-eslint/typescript-estree@8.1.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@8.13.0(typescript@5.6.3)': dependencies: - '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/visitor-keys': 8.1.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/visitor-keys': 8.13.0 debug: 4.3.7(supports-color@9.4.0) - globby: 11.1.0 + fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 @@ -10796,7 +8694,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.13.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@8.13.0(typescript@5.7.2)': dependencies: '@typescript-eslint/types': 8.13.0 '@typescript-eslint/visitor-keys': 8.13.0 @@ -10805,58 +8703,34 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.4.0(typescript@5.6.3) + ts-api-utils: 1.4.0(typescript@5.7.2) optionalDependencies: - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@6.19.1(eslint@8.57.1)(typescript@5.6.3)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 6.19.1 - '@typescript-eslint/types': 6.19.1 - '@typescript-eslint/typescript-estree': 6.19.1(typescript@5.6.3) - eslint: 8.57.1 - semver: 7.6.3 + typescript: 5.7.2 transitivePeerDependencies: - supports-color - - typescript - '@typescript-eslint/utils@8.1.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/utils@8.13.0(eslint@8.57.1)(typescript@5.6.3)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.13.0 + '@typescript-eslint/types': 8.13.0 + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) eslint: 8.57.1 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.13.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/utils@8.13.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.21.0(jiti@2.4.2)) '@typescript-eslint/scope-manager': 8.13.0 '@typescript-eslint/types': 8.13.0 - '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) - eslint: 8.57.1 + '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.7.2) + eslint: 9.21.0(jiti@2.4.2) transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@6.19.1': - dependencies: - '@typescript-eslint/types': 6.19.1 - eslint-visitor-keys: 3.4.3 - - '@typescript-eslint/visitor-keys@8.1.0': - dependencies: - '@typescript-eslint/types': 8.1.0 - eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.13.0': dependencies: '@typescript-eslint/types': 8.13.0 @@ -10864,21 +8738,21 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitest/coverage-v8@2.1.3(vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0))': + '@vitest/coverage-v8@2.1.3(vitest@2.1.3)': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 - magic-string: 0.30.12 + magic-string: 0.30.17 magicast: 0.3.5 std-env: 3.7.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + vitest: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) transitivePeerDependencies: - supports-color @@ -10889,13 +8763,13 @@ snapshots: chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.3(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0))': + '@vitest/mocker@2.1.3(vite@5.4.9(@types/node@22.19.15)(lightningcss@1.29.1)(terser@5.36.0))': dependencies: '@vitest/spy': 2.1.3 estree-walker: 3.0.3 - magic-string: 0.30.12 + magic-string: 0.30.17 optionalDependencies: - vite: 5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0) + vite: 5.4.9(@types/node@22.19.15)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) '@vitest/pretty-format@2.1.3': dependencies: @@ -10909,7 +8783,7 @@ snapshots: '@vitest/snapshot@2.1.3': dependencies: '@vitest/pretty-format': 2.1.3 - magic-string: 0.30.12 + magic-string: 0.30.17 pathe: 1.1.2 '@vitest/spy@2.1.3': @@ -10923,9 +8797,9 @@ snapshots: flatted: 3.3.1 pathe: 1.1.2 sirv: 2.0.4 - tinyglobby: 0.2.9 + tinyglobby: 0.2.15 tinyrainbow: 1.2.0 - vitest: 2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0) + vitest: 2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) '@vitest/utils@2.1.3': dependencies: @@ -10933,6 +8807,64 @@ snapshots: loupe: 3.1.2 tinyrainbow: 1.2.0 + '@volar/language-core@2.4.12': + dependencies: + '@volar/source-map': 2.4.12 + + '@volar/source-map@2.4.12': {} + + '@volar/typescript@2.4.12': + dependencies: + '@volar/language-core': 2.4.12 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + + '@vue/compiler-core@3.5.13': + dependencies: + '@babel/parser': 7.25.8 + '@vue/shared': 3.5.13 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.13': + dependencies: + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/language-core@2.2.0(typescript@5.6.3)': + dependencies: + '@volar/language-core': 2.4.12 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.13 + alien-signals: 0.4.14 + minimatch: 9.0.5 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.6.3 + + '@vue/language-core@2.2.0(typescript@5.8.2)': + dependencies: + '@volar/language-core': 2.4.12 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.13 + alien-signals: 0.4.14 + minimatch: 9.0.5 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.8.2 + + '@vue/shared@3.5.13': {} + '@webassemblyjs/ast@1.12.1': dependencies: '@webassemblyjs/helper-numbers': 1.11.6 @@ -11015,11 +8947,6 @@ snapshots: abab@2.0.6: {} - acorn-globals@4.3.4: - dependencies: - acorn: 6.4.2 - acorn-walk: 6.2.0 - acorn-globals@6.0.0: dependencies: acorn: 7.4.1 @@ -11029,20 +8956,12 @@ snapshots: dependencies: acorn: 8.13.0 - acorn-jsx@5.3.2(acorn@7.4.1): - dependencies: - acorn: 7.4.1 - acorn-jsx@5.3.2(acorn@8.14.0): dependencies: acorn: 8.14.0 - acorn-walk@6.2.0: {} - acorn-walk@7.2.0: {} - acorn@6.4.2: {} - acorn@7.4.1: {} acorn@8.13.0: {} @@ -11051,7 +8970,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.7(supports-color@9.4.0) + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -11095,18 +9014,12 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - ansi-colors@4.1.3: {} - - ansi-escapes@3.2.0: {} + alien-signals@0.4.14: {} ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 - ansi-regex@3.0.1: {} - - ansi-regex@4.1.1: {} - ansi-regex@5.0.1: {} ansi-regex@6.1.0: {} @@ -11123,11 +9036,6 @@ snapshots: ansi-styles@6.2.1: {} - anymatch@2.0.0: - dependencies: - micromatch: 3.1.10 - normalize-path: 2.1.1 - anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -11143,21 +9051,11 @@ snapshots: dependencies: deep-equal: 2.2.3 - aria-query@5.3.2: {} - - arr-diff@4.0.0: {} - - arr-flatten@1.1.0: {} - - arr-union@3.1.0: {} - array-buffer-byte-length@1.0.1: dependencies: call-bind: 1.0.7 is-array-buffer: 3.0.4 - array-equal@1.0.2: {} - array-includes@3.1.8: dependencies: call-bind: 1.0.7 @@ -11169,8 +9067,6 @@ snapshots: array-union@2.1.0: {} - array-unique@0.3.2: {} - array.prototype.findlast@1.2.5: dependencies: call-bind: 1.0.7 @@ -11224,32 +9120,14 @@ snapshots: arrify@1.0.1: {} - asn1@0.2.6: - dependencies: - safer-buffer: 2.1.2 - - assert-plus@1.0.0: {} - assertion-error@2.0.1: {} - assign-symbols@1.0.0: {} - ast-types-flow@0.0.8: {} - astral-regex@1.0.0: {} - astral-regex@2.0.0: {} asynckit@0.4.0: {} - asyncro@3.0.0: {} - - at-least-node@1.0.0: {} - - atob-lite@2.0.0: {} - - atob@2.1.2: {} - autoprefixer@9.8.8: dependencies: browserslist: 4.24.0 @@ -11264,10 +9142,6 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - aws-sign2@0.7.0: {} - - aws4@1.13.2: {} - axe-core@4.10.1: {} axios@0.27.2: @@ -11279,32 +9153,6 @@ snapshots: axobject-query@4.1.0: {} - babel-eslint@10.1.0(eslint@6.8.0): - dependencies: - '@babel/code-frame': 7.25.7 - '@babel/parser': 7.25.8 - '@babel/traverse': 7.25.7(supports-color@9.4.0) - '@babel/types': 7.25.8 - eslint: 6.8.0 - eslint-visitor-keys: 1.3.0 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color - - babel-jest@25.5.1(@babel/core@7.25.8): - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@jest/transform': 25.5.1 - '@jest/types': 25.5.0 - '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1(supports-color@9.4.0) - babel-preset-jest: 25.5.0(@babel/core@7.25.8) - chalk: 3.0.0 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - babel-jest@28.1.3(@babel/core@7.25.8): dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) @@ -11318,27 +9166,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-jest@29.7.0(@babel/core@7.25.8): - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1(supports-color@9.4.0) - babel-preset-jest: 29.6.3(@babel/core@7.25.8) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-annotate-pure-calls@0.4.0(@babel/core@7.25.8): - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - - babel-plugin-dev-expression@0.2.3(@babel/core@7.25.8): - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - babel-plugin-istanbul@6.1.1(supports-color@9.4.0): dependencies: '@babel/helper-plugin-utils': 7.25.7 @@ -11349,12 +9176,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-jest-hoist@25.5.0: - dependencies: - '@babel/template': 7.25.7 - '@babel/types': 7.25.8 - '@types/babel__traverse': 7.20.6 - babel-plugin-jest-hoist@28.1.3: dependencies: '@babel/template': 7.25.7 @@ -11362,19 +9183,6 @@ snapshots: '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.6 - babel-plugin-jest-hoist@29.6.3: - dependencies: - '@babel/template': 7.25.7 - '@babel/types': 7.25.8 - '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.6 - - babel-plugin-macros@2.8.0: - dependencies: - '@babel/runtime': 7.25.7 - cosmiconfig: 6.0.0 - resolve: 1.22.8 - babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.25.8): dependencies: '@babel/compat-data': 7.25.8 @@ -11392,13 +9200,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.0.4(@babel/core@7.25.8): - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@babel/helper-define-polyfill-provider': 0.0.3(@babel/core@7.25.8) - transitivePeerDependencies: - - supports-color - babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.25.8): dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) @@ -11412,23 +9213,6 @@ snapshots: '@babel/template': 7.25.7 tslib: 2.8.0 - babel-plugin-transform-rename-import@2.3.0: {} - - babel-preset-current-node-syntax@0.1.4(@babel/core@7.25.8): - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.8) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.8) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.8) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.8) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.8) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.8) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.8) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.8) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.8) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.8) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.8) - babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.8): dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) @@ -11448,50 +9232,22 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.8) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.8) - babel-preset-jest@25.5.0(@babel/core@7.25.8): - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - babel-plugin-jest-hoist: 25.5.0 - babel-preset-current-node-syntax: 0.1.4(@babel/core@7.25.8) - babel-preset-jest@28.1.3(@babel/core@7.25.8): dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) babel-plugin-jest-hoist: 28.1.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.8) - babel-preset-jest@29.6.3(@babel/core@7.25.8): - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.8) - bail@1.0.5: {} balanced-match@1.0.2: {} balanced-match@2.0.0: {} - base64-js@0.0.8: {} + base64-js@1.3.1: {} base64-js@1.5.1: {} - base@0.11.2: - dependencies: - cache-base: 1.0.1 - class-utils: 0.3.6 - component-emitter: 1.3.1 - define-property: 1.0.0 - isobject: 3.0.1 - mixin-deep: 1.3.2 - pascalcase: 0.1.1 - - bcrypt-pbkdf@1.0.2: - dependencies: - tweetnacl: 0.14.5 - - binary-extensions@2.3.0: {} - brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -11501,19 +9257,6 @@ snapshots: dependencies: balanced-match: 1.0.2 - braces@2.3.2: - dependencies: - arr-flatten: 1.1.0 - array-unique: 0.3.2 - extend-shallow: 2.0.1 - fill-range: 4.0.0 - isobject: 3.0.1 - repeat-element: 1.1.4 - snapdragon: 0.8.2 - snapdragon-node: 2.1.1 - split-string: 3.1.0 - to-regex: 3.0.2 - braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -11524,10 +9267,6 @@ snapshots: browser-process-hrtime@1.0.0: {} - browser-resolve@1.11.3: - dependencies: - resolve: 1.1.7 - browserslist@4.24.0: dependencies: caniuse-lite: 1.0.30001669 @@ -11545,24 +9284,12 @@ snapshots: buffer-from@1.1.2: {} - builtin-modules@3.3.0: {} - - bytes-iec@3.1.1: {} + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 cac@6.7.14: {} - cache-base@1.0.1: - dependencies: - collection-visit: 1.0.0 - component-emitter: 1.3.1 - get-value: 2.0.6 - has-value: 1.0.0 - isobject: 3.0.1 - set-value: 2.0.1 - to-object-path: 0.3.0 - union-value: 1.0.1 - unset-value: 1.0.0 - call-bind@1.0.7: dependencies: es-define-property: 1.0.0 @@ -11585,12 +9312,6 @@ snapshots: caniuse-lite@1.0.30001669: {} - capture-exit@2.0.0: - dependencies: - rsvp: 4.8.5 - - caseless@0.12.0: {} - chai@5.1.1: dependencies: assertion-error: 2.0.1 @@ -11605,11 +9326,6 @@ snapshots: escape-string-regexp: 1.0.5 supports-color: 5.5.0 - chalk@3.0.0: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -11625,58 +9341,15 @@ snapshots: character-reference-invalid@1.1.4: {} - chardet@0.7.0: {} - check-error@2.1.1: {} - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - chrome-trace-event@1.0.4: {} - ci-info@2.0.0: {} - ci-info@3.9.0: {} - ci-job-number@1.2.2: {} - cjs-module-lexer@1.4.1: {} - class-utils@0.3.6: - dependencies: - arr-union: 3.1.0 - define-property: 0.2.5 - isobject: 3.0.1 - static-extend: 0.1.2 - - cli-cursor@2.1.0: - dependencies: - restore-cursor: 2.0.0 - - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@1.3.1: {} - - cli-spinners@2.9.2: {} - - cli-width@3.0.0: {} - - cliui@6.0.0: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 + client-only@0.0.1: {} cliui@8.0.1: dependencies: @@ -11696,11 +9369,6 @@ snapshots: collect-v8-coverage@1.0.2: {} - collection-visit@1.0.0: - dependencies: - map-visit: 1.0.0 - object-visit: 1.0.1 - color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -11713,6 +9381,18 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + optional: true + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -11721,38 +9401,26 @@ snapshots: comment-parser@1.3.1: {} - commondir@1.0.1: {} - - component-emitter@1.3.1: {} + compare-versions@6.1.1: {} concat-map@0.0.1: {} - confusing-browser-globals@1.0.11: {} + confbox@0.1.8: {} + + confbox@0.2.1: {} convert-source-map@1.9.0: {} convert-source-map@2.0.0: {} - copy-descriptor@0.1.1: {} - core-js-compat@3.38.1: dependencies: browserslist: 4.24.0 core-js@3.38.1: {} - core-util-is@1.0.2: {} - - core-util-is@1.0.3: {} - - cosmiconfig@6.0.0: - dependencies: - '@types/parse-json': 4.0.2 - import-fresh: 3.3.0 - parse-json: 5.2.0 - path-type: 4.0.0 - yaml: 1.10.2 - + core-util-is@1.0.3: {} + cosmiconfig@7.1.0: dependencies: '@types/parse-json': 4.0.2 @@ -11761,15 +9429,13 @@ snapshots: path-type: 4.0.0 yaml: 1.10.2 - cross-spawn@6.0.5: + cross-spawn@7.0.3: dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.2 - shebang-command: 1.2.0 - which: 1.3.1 + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 - cross-spawn@7.0.3: + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 @@ -11777,36 +9443,22 @@ snapshots: crypto-js@4.2.0: {} - css.escape@1.5.1: {} - cssesc@3.0.0: {} cssom@0.3.8: {} - cssom@0.4.4: {} - cssom@0.5.0: {} cssstyle@2.3.0: dependencies: cssom: 0.3.8 - curp@1.2.3: {} + csstype@3.1.3: {} damerau-levenshtein@1.0.8: {} - dashdash@1.14.1: - dependencies: - assert-plus: 1.0.0 - data-uri-to-buffer@1.2.0: {} - data-urls@1.1.0: - dependencies: - abab: 2.0.6 - whatwg-mimetype: 2.3.0 - whatwg-url: 7.1.0 - data-urls@3.0.2: dependencies: abab: 2.0.6 @@ -11831,6 +9483,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.1 + de-indent@1.0.2: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -11845,6 +9499,10 @@ snapshots: optionalDependencies: supports-color: 9.4.0 + debug@4.4.0: + dependencies: + ms: 2.1.3 + decamelize-keys@1.1.1: dependencies: decamelize: 1.2.0 @@ -11854,18 +9512,23 @@ snapshots: decimal.js@10.4.3: {} - decode-uri-component@0.2.2: {} - dedent@0.7.0: {} - dedent@1.5.3: {} - deep-eql@4.1.4: dependencies: type-detect: 4.1.0 deep-eql@5.0.2: {} + deep-equal@1.1.2: + dependencies: + is-arguments: 1.1.1 + is-date-object: 1.0.5 + is-regex: 1.1.4 + object-is: 1.1.6 + object-keys: 1.1.1 + regexp.prototype.flags: 1.5.3 + deep-equal@2.2.3: dependencies: array-buffer-byte-length: 1.0.1 @@ -11891,10 +9554,6 @@ snapshots: deepmerge@4.3.1: {} - defaults@1.0.4: - dependencies: - clone: 1.0.4 - define-data-property@1.1.4: dependencies: es-define-property: 1.0.0 @@ -11907,35 +9566,21 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 - define-property@0.2.5: - dependencies: - is-descriptor: 0.1.7 - - define-property@1.0.0: - dependencies: - is-descriptor: 1.0.3 + delayed-stream@1.0.0: {} - define-property@2.0.2: - dependencies: - is-descriptor: 1.0.3 - isobject: 3.0.1 + detect-libc@1.0.3: {} - delayed-stream@1.0.0: {} + detect-libc@2.0.3: + optional: true detect-newline@3.1.0: {} dfa@1.2.0: {} - diff-sequences@25.2.6: {} - diff-sequences@27.5.1: {} diff-sequences@28.1.1: {} - diff-sequences@29.6.3: {} - - dijkstrajs@1.0.3: {} - dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -11948,8 +9593,6 @@ snapshots: dependencies: esutils: 2.0.3 - dom-accessibility-api@0.5.16: {} - dom-serializer@0.2.2: dependencies: domelementtype: 2.3.0 @@ -11959,10 +9602,6 @@ snapshots: domelementtype@2.3.0: {} - domexception@1.0.1: - dependencies: - webidl-conversions: 4.0.2 - domexception@4.0.0: dependencies: webidl-conversions: 7.0.0 @@ -11976,45 +9615,32 @@ snapshots: dom-serializer: 0.2.2 domelementtype: 1.3.1 - dtype@2.0.0: {} - eastasianwidth@0.2.0: {} - ecc-jsbn@0.1.2: - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - electron-to-chromium@1.5.41: {} emittery@0.10.2: {} - emittery@0.13.1: {} - - emoji-regex@7.0.3: {} - emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - enhanced-resolve@5.17.1: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 - enquirer@2.4.1: + enhanced-resolve@5.18.1: dependencies: - ansi-colors: 4.1.3 - strip-ansi: 6.0.1 + graceful-fs: 4.2.11 + tapable: 2.2.1 entities@1.1.2: {} entities@2.2.0: {} + entities@4.5.0: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -12125,115 +9751,6 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.0.4 - esbuild-android-64@0.14.54: - optional: true - - esbuild-android-arm64@0.14.54: - optional: true - - esbuild-darwin-64@0.14.54: - optional: true - - esbuild-darwin-arm64@0.14.54: - optional: true - - esbuild-freebsd-64@0.14.54: - optional: true - - esbuild-freebsd-arm64@0.14.54: - optional: true - - esbuild-linux-32@0.14.54: - optional: true - - esbuild-linux-64@0.14.54: - optional: true - - esbuild-linux-arm64@0.14.54: - optional: true - - esbuild-linux-arm@0.14.54: - optional: true - - esbuild-linux-mips64le@0.14.54: - optional: true - - esbuild-linux-ppc64le@0.14.54: - optional: true - - esbuild-linux-riscv64@0.14.54: - optional: true - - esbuild-linux-s390x@0.14.54: - optional: true - - esbuild-netbsd-64@0.14.54: - optional: true - - esbuild-openbsd-64@0.14.54: - optional: true - - esbuild-sunos-64@0.14.54: - optional: true - - esbuild-windows-32@0.14.54: - optional: true - - esbuild-windows-64@0.14.54: - optional: true - - esbuild-windows-arm64@0.14.54: - optional: true - - esbuild@0.14.54: - optionalDependencies: - '@esbuild/linux-loong64': 0.14.54 - esbuild-android-64: 0.14.54 - esbuild-android-arm64: 0.14.54 - esbuild-darwin-64: 0.14.54 - esbuild-darwin-arm64: 0.14.54 - esbuild-freebsd-64: 0.14.54 - esbuild-freebsd-arm64: 0.14.54 - esbuild-linux-32: 0.14.54 - esbuild-linux-64: 0.14.54 - esbuild-linux-arm: 0.14.54 - esbuild-linux-arm64: 0.14.54 - esbuild-linux-mips64le: 0.14.54 - esbuild-linux-ppc64le: 0.14.54 - esbuild-linux-riscv64: 0.14.54 - esbuild-linux-s390x: 0.14.54 - esbuild-netbsd-64: 0.14.54 - esbuild-openbsd-64: 0.14.54 - esbuild-sunos-64: 0.14.54 - esbuild-windows-32: 0.14.54 - esbuild-windows-64: 0.14.54 - esbuild-windows-arm64: 0.14.54 - - esbuild@0.18.20: - optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -12260,6 +9777,35 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 + esbuild@0.27.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 + escalade@3.2.0: {} escape-string-regexp@1.0.5: {} @@ -12268,15 +9814,6 @@ snapshots: escape-string-regexp@4.0.0: {} - escodegen@1.14.3: - dependencies: - esprima: 4.0.1 - estraverse: 4.3.0 - esutils: 2.0.3 - optionator: 0.8.3 - optionalDependencies: - source-map: 0.6.1 - escodegen@2.1.0: dependencies: esprima: 4.0.1 @@ -12285,28 +9822,29 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-prettier@6.15.0(eslint@6.8.0): + eslint-config-next@15.2.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2): dependencies: - eslint: 6.8.0 - get-stdin: 6.0.0 + '@next/eslint-plugin-next': 15.2.1 + '@rushstack/eslint-patch': 1.10.4 + '@typescript-eslint/eslint-plugin': 8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2))(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2) + '@typescript-eslint/parser': 8.13.0(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.2) + eslint: 9.21.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0(eslint@9.21.0(jiti@2.4.2)))(eslint@9.21.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(eslint@9.21.0(jiti@2.4.2)) + eslint-plugin-jsx-a11y: 6.10.0(eslint@9.21.0(jiti@2.4.2)) + eslint-plugin-react: 7.37.1(eslint@9.21.0(jiti@2.4.2)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.21.0(jiti@2.4.2)) + optionalDependencies: + typescript: 5.7.2 + transitivePeerDependencies: + - eslint-plugin-import-x + - supports-color eslint-config-prettier@8.10.0(eslint@8.57.1): dependencies: eslint: 8.57.1 - eslint-config-react-app@5.2.1(@typescript-eslint/eslint-plugin@2.34.0(@typescript-eslint/parser@2.34.0(eslint@6.8.0)(typescript@3.9.10))(eslint@6.8.0)(typescript@3.9.10))(@typescript-eslint/parser@2.34.0(eslint@6.8.0)(typescript@3.9.10))(babel-eslint@10.1.0(eslint@6.8.0))(eslint-plugin-flowtype@3.13.0(eslint@6.8.0))(eslint-plugin-import@2.31.0(eslint@6.8.0))(eslint-plugin-jsx-a11y@6.10.0(eslint@6.8.0))(eslint-plugin-react-hooks@2.5.1(eslint@6.8.0))(eslint-plugin-react@7.37.1(eslint@6.8.0))(eslint@6.8.0): - dependencies: - '@typescript-eslint/eslint-plugin': 2.34.0(@typescript-eslint/parser@2.34.0(eslint@6.8.0)(typescript@3.9.10))(eslint@6.8.0)(typescript@3.9.10) - '@typescript-eslint/parser': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - babel-eslint: 10.1.0(eslint@6.8.0) - confusing-browser-globals: 1.0.11 - eslint: 6.8.0 - eslint-plugin-flowtype: 3.13.0(eslint@6.8.0) - eslint-plugin-import: 2.31.0(eslint@6.8.0) - eslint-plugin-jsx-a11y: 6.10.0(eslint@6.8.0) - eslint-plugin-react: 7.37.1(eslint@6.8.0) - eslint-plugin-react-hooks: 2.5.1(eslint@6.8.0) - eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 @@ -12325,11 +9863,20 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(eslint@6.8.0): + eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0(eslint@9.21.0(jiti@2.4.2)))(eslint@9.21.0(jiti@2.4.2)): dependencies: - debug: 3.2.7 + '@nolyfill/is-core-module': 1.0.39 + debug: 4.3.7(supports-color@9.4.0) + enhanced-resolve: 5.17.1 + eslint: 9.21.0(jiti@2.4.2) + get-tsconfig: 4.10.0 + is-bun-module: 1.3.0 + stable-hash: 0.0.4 + tinyglobby: 0.2.12 optionalDependencies: - eslint: 6.8.0 + eslint-plugin-import: 2.31.0(eslint@9.21.0(jiti@2.4.2)) + transitivePeerDependencies: + - supports-color eslint-module-utils@2.12.0(eslint@8.57.1): dependencies: @@ -12337,12 +9884,13 @@ snapshots: optionalDependencies: eslint: 8.57.1 - eslint-plugin-flowtype@3.13.0(eslint@6.8.0): + eslint-module-utils@2.12.0(eslint@9.21.0(jiti@2.4.2)): dependencies: - eslint: 6.8.0 - lodash: 4.17.21 + debug: 3.2.7 + optionalDependencies: + eslint: 9.21.0(jiti@2.4.2) - eslint-plugin-import@2.31.0(eslint@6.8.0): + eslint-plugin-import@2.31.0(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -12351,9 +9899,9 @@ snapshots: array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 6.8.0 + eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(eslint@6.8.0) + eslint-module-utils: 2.12.0(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -12365,7 +9913,7 @@ snapshots: string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 - eslint-plugin-import@2.31.0(eslint@8.57.1): + eslint-plugin-import@2.31.0(eslint@9.21.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -12374,9 +9922,9 @@ snapshots: array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.57.1 + eslint: 9.21.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(eslint@8.57.1) + eslint-module-utils: 2.12.0(eslint@9.21.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -12412,7 +9960,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-jsx-a11y@6.10.0(eslint@6.8.0): + eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1): dependencies: aria-query: 5.1.3 array-includes: 3.1.8 @@ -12423,7 +9971,7 @@ snapshots: damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 es-iterator-helpers: 1.1.0 - eslint: 6.8.0 + eslint: 8.57.1 hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -12432,7 +9980,7 @@ snapshots: safe-regex-test: 1.0.3 string.prototype.includes: 2.0.1 - eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1): + eslint-plugin-jsx-a11y@6.10.0(eslint@9.21.0(jiti@2.4.2)): dependencies: aria-query: 5.1.3 array-includes: 3.1.8 @@ -12443,7 +9991,7 @@ snapshots: damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 es-iterator-helpers: 1.1.0 - eslint: 8.57.1 + eslint: 9.21.0(jiti@2.4.2) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -12452,14 +10000,6 @@ snapshots: safe-regex-test: 1.0.3 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@3.4.1(eslint-config-prettier@6.15.0(eslint@6.8.0))(eslint@6.8.0)(prettier@1.19.1): - dependencies: - eslint: 6.8.0 - prettier: 1.19.1 - prettier-linter-helpers: 1.0.0 - optionalDependencies: - eslint-config-prettier: 6.15.0(eslint@6.8.0) - eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8): dependencies: eslint: 8.57.1 @@ -12468,35 +10008,11 @@ snapshots: optionalDependencies: eslint-config-prettier: 8.10.0(eslint@8.57.1) - eslint-plugin-promise@6.1.1(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-plugin-react-hooks@2.5.1(eslint@6.8.0): + eslint-plugin-react-hooks@5.2.0(eslint@9.21.0(jiti@2.4.2)): dependencies: - eslint: 6.8.0 - - eslint-plugin-react@7.33.2(eslint@8.57.1): - dependencies: - array-includes: 3.1.8 - array.prototype.flatmap: 1.3.2 - array.prototype.tosorted: 1.1.4 - doctrine: 2.1.0 - es-iterator-helpers: 1.1.0 - eslint: 8.57.1 - estraverse: 5.3.0 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.8 - object.fromentries: 2.0.8 - object.hasown: 1.1.4 - object.values: 1.2.0 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 - string.prototype.matchall: 4.0.11 + eslint: 9.21.0(jiti@2.4.2) - eslint-plugin-react@7.37.1(eslint@6.8.0): + eslint-plugin-react@7.37.1(eslint@9.21.0(jiti@2.4.2)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -12504,7 +10020,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.1.0 - eslint: 6.8.0 + eslint: 9.21.0(jiti@2.4.2) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -12523,11 +10039,6 @@ snapshots: eslint: 8.57.1 natural-compare-lite: 1.4.0 - eslint-plugin-tsdoc@0.3.0: - dependencies: - '@microsoft/tsdoc': 0.15.0 - '@microsoft/tsdoc-config': 0.17.0 - eslint-scope@5.1.1: dependencies: esrecurse: 4.3.0 @@ -12538,59 +10049,14 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-utils@1.4.3: + eslint-scope@8.2.0: dependencies: - eslint-visitor-keys: 1.3.0 - - eslint-utils@2.1.0: - dependencies: - eslint-visitor-keys: 1.3.0 - - eslint-visitor-keys@1.3.0: {} + esrecurse: 4.3.0 + estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} - eslint@6.8.0: - dependencies: - '@babel/code-frame': 7.25.7 - ajv: 6.12.6 - chalk: 2.4.2 - cross-spawn: 6.0.5 - debug: 4.3.7(supports-color@9.4.0) - doctrine: 3.0.0 - eslint-scope: 5.1.1 - eslint-utils: 1.4.3 - eslint-visitor-keys: 1.3.0 - espree: 6.2.1 - esquery: 1.6.0 - esutils: 2.0.3 - file-entry-cache: 5.0.1 - functional-red-black-tree: 1.0.1 - glob-parent: 5.1.2 - globals: 12.4.0 - ignore: 4.0.6 - import-fresh: 3.3.0 - imurmurhash: 0.1.4 - inquirer: 7.3.3 - is-glob: 4.0.3 - js-yaml: 3.14.1 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.3.0 - lodash: 4.17.21 - minimatch: 3.1.2 - mkdirp: 0.5.6 - natural-compare: 1.4.0 - optionator: 0.8.3 - progress: 2.0.3 - regexpp: 2.0.1 - semver: 6.3.1 - strip-ansi: 5.2.0 - strip-json-comments: 3.1.1 - table: 5.4.6 - text-table: 0.2.0 - v8-compile-cache: 2.4.0 - transitivePeerDependencies: - - supports-color + eslint-visitor-keys@4.2.0: {} eslint@8.57.1: dependencies: @@ -12635,11 +10101,52 @@ snapshots: transitivePeerDependencies: - supports-color - espree@6.2.1: + eslint@9.21.0(jiti@2.4.2): dependencies: - acorn: 7.4.1 - acorn-jsx: 5.3.2(acorn@7.4.1) - eslint-visitor-keys: 1.3.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.21.0(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.2 + '@eslint/core': 0.12.0 + '@eslint/eslintrc': 3.3.0 + '@eslint/js': 9.21.0 + '@eslint/plugin-kit': 0.2.7 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.3.7(supports-color@9.4.0) + escape-string-regexp: 4.0.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 espree@9.6.1: dependencies: @@ -12661,13 +10168,11 @@ snapshots: estraverse@5.3.0: {} - estree-walker@0.6.1: {} - - estree-walker@1.0.1: {} + estree-walker@2.0.2: {} estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.8 esutils@2.0.3: {} @@ -12675,43 +10180,6 @@ snapshots: events@3.3.0: {} - exec-sh@0.3.6: {} - - execa@1.0.0: - dependencies: - cross-spawn: 6.0.5 - get-stream: 4.1.0 - is-stream: 1.1.0 - npm-run-path: 2.0.2 - p-finally: 1.0.0 - signal-exit: 3.0.7 - strip-eof: 1.0.0 - - execa@3.4.0: - dependencies: - cross-spawn: 7.0.3 - get-stream: 5.2.0 - human-signals: 1.1.1 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - p-finally: 2.0.1 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - execa@4.1.0: - dependencies: - cross-spawn: 7.0.3 - get-stream: 5.2.0 - human-signals: 1.1.1 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - execa@5.1.1: dependencies: cross-spawn: 7.0.3 @@ -12730,25 +10198,6 @@ snapshots: exit@0.1.2: {} - expand-brackets@2.1.4: - dependencies: - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - posix-character-classes: 0.1.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - - expect@25.5.0: - dependencies: - '@jest/types': 25.5.0 - ansi-styles: 4.3.0 - jest-get-type: 25.2.6 - jest-matcher-utils: 25.5.0 - jest-message-util: 25.5.0 - jest-regex-util: 25.2.6 - expect@28.1.3: dependencies: '@jest/expect-utils': 28.1.3 @@ -12757,48 +10206,22 @@ snapshots: jest-message-util: 28.1.3 jest-util: 28.1.3 - expect@29.7.0: - dependencies: - '@jest/expect-utils': 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - - extend-shallow@2.0.1: - dependencies: - is-extendable: 0.1.1 - - extend-shallow@3.0.2: - dependencies: - assign-symbols: 1.0.0 - is-extendable: 1.0.1 + exsolve@1.0.4: {} extend@3.0.2: {} - external-editor@3.1.0: - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - - extglob@2.0.4: - dependencies: - array-unique: 0.3.2 - define-property: 1.0.0 - expand-brackets: 2.1.4 - extend-shallow: 2.0.1 - fragment-cache: 0.2.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - - extsprintf@1.3.0: {} - fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -12823,10 +10246,14 @@ snapshots: dependencies: bser: 2.1.1 - fdir@6.4.2(picomatch@4.0.2): + fdir@6.4.3(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + fetch-mock-jest@1.5.1(node-fetch@2.7.0): dependencies: fetch-mock: 9.11.0(node-fetch@2.7.0) @@ -12854,39 +10281,20 @@ snapshots: fflate@0.8.2: {} - figures@3.2.0: - dependencies: - escape-string-regexp: 1.0.5 - - file-entry-cache@5.0.1: - dependencies: - flat-cache: 2.0.1 - file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 - file-saver@2.0.5: {} + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 file-uri-to-path@1.0.0: {} - fill-range@4.0.0: - dependencies: - extend-shallow: 2.0.1 - is-number: 3.0.0 - repeat-string: 1.6.1 - to-regex-range: 2.1.1 - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - find-cache-dir@3.3.2: - dependencies: - commondir: 1.0.1 - make-dir: 3.1.0 - pkg-dir: 4.2.0 - find-up@4.1.0: dependencies: locate-path: 5.0.0 @@ -12897,68 +10305,41 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - flat-cache@2.0.1: - dependencies: - flatted: 2.0.2 - rimraf: 2.6.3 - write: 1.0.3 - flat-cache@3.2.0: dependencies: flatted: 3.3.1 keyv: 4.5.4 rimraf: 3.0.2 - flatted@2.0.2: {} + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 flatted@3.3.1: {} - flatten-vertex-data@1.0.2: - dependencies: - dtype: 2.0.0 - follow-redirects@1.15.9: {} - fontkit@1.9.0: - dependencies: - '@swc/helpers': 0.3.17 - brotli: 1.3.3 - clone: 2.1.2 - deep-equal: 2.2.3 - dfa: 1.2.0 - restructure: 2.0.1 - tiny-inflate: 1.0.3 - unicode-properties: 1.4.1 - unicode-trie: 2.0.0 - for-each@0.3.3: dependencies: is-callable: 1.2.7 - for-in@1.0.2: {} - foreground-child@3.3.0: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 signal-exit: 4.1.0 - forever-agent@0.6.1: {} - - form-data@2.3.3: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - form-data@4.0.1: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - fragment-cache@0.2.1: + fs-extra@11.3.0: dependencies: - map-cache: 0.2.2 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 fs-extra@3.0.1: dependencies: @@ -12966,25 +10347,6 @@ snapshots: jsonfile: 3.0.1 universalify: 0.1.2 - fs-extra@7.0.1: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fs-extra@8.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fs-extra@9.1.0: - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -13004,8 +10366,6 @@ snapshots: es-abstract: 1.23.3 functions-have-names: 1.2.3 - functional-red-black-tree@1.0.1: {} - functions-have-names@1.2.3: {} gensync@1.0.0-beta.2: {} @@ -13022,18 +10382,8 @@ snapshots: get-package-type@0.1.0: {} - get-stdin@6.0.0: {} - get-stdin@8.0.0: {} - get-stream@4.1.0: - dependencies: - pump: 3.0.2 - - get-stream@5.2.0: - dependencies: - pump: 3.0.2 - get-stream@6.0.1: {} get-symbol-description@1.0.2: @@ -13042,6 +10392,10 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.2.4 + get-tsconfig@4.10.0: + dependencies: + resolve-pkg-maps: 1.0.0 + get-uri@2.0.4: dependencies: data-uri-to-buffer: 1.2.0 @@ -13051,14 +10405,6 @@ snapshots: ftp: 0.3.10 readable-stream: 2.3.8 - get-value@2.0.6: {} - - getpass@0.1.7: - dependencies: - assert-plus: 1.0.0 - - git-repo-info@2.1.1: {} - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -13078,15 +10424,6 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - glob@11.0.0: - dependencies: - foreground-child: 3.3.0 - jackspeak: 4.0.2 - minimatch: 10.0.1 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 2.0.0 - glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -13108,21 +10445,17 @@ snapshots: globals@11.12.0: {} - globals@12.4.0: - dependencies: - type-fest: 0.8.1 - globals@13.24.0: dependencies: type-fest: 0.20.2 + globals@14.0.0: {} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 gopd: 1.0.1 - globalyzer@0.1.0: {} - globby@11.1.0: dependencies: array-union: 2.1.0 @@ -13148,16 +10481,6 @@ snapshots: graphemer@1.4.0: {} - growly@1.3.0: - optional: true - - har-schema@2.0.0: {} - - har-validator@5.1.5: - dependencies: - ajv: 6.12.6 - har-schema: 2.0.0 - hard-rejection@2.1.0: {} harmony-reflect@1.6.2: {} @@ -13180,25 +10503,6 @@ snapshots: dependencies: has-symbols: 1.0.3 - has-value@0.3.1: - dependencies: - get-value: 2.0.6 - has-values: 0.1.4 - isobject: 2.1.0 - - has-value@1.0.0: - dependencies: - get-value: 2.0.6 - has-values: 1.0.0 - isobject: 3.0.1 - - has-values@0.1.4: {} - - has-values@1.0.0: - dependencies: - is-number: 3.0.0 - kind-of: 4.0.0 - hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -13219,10 +10523,6 @@ snapshots: dependencies: lru-cache: 6.0.0 - html-encoding-sniffer@1.0.2: - dependencies: - whatwg-encoding: 1.0.5 - html-encoding-sniffer@3.0.0: dependencies: whatwg-encoding: 2.0.0 @@ -13244,36 +10544,24 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.4.0 transitivePeerDependencies: - supports-color - http-signature@1.2.0: - dependencies: - assert-plus: 1.0.0 - jsprim: 1.4.2 - sshpk: 1.18.0 - https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.4.0 transitivePeerDependencies: - supports-color - human-signals@1.1.1: {} - human-signals@2.1.0: {} - humanize-duration@3.32.1: {} - - husky@8.0.3: {} - - iconv-lite@0.4.24: + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 - iconv-lite@0.6.3: + iconv-lite@0.7.2: dependencies: safer-buffer: 2.1.2 @@ -13281,14 +10569,8 @@ snapshots: dependencies: harmony-reflect: 1.6.2 - ignore@4.0.6: {} - - ignore@5.1.9: {} - ignore@5.3.2: {} - immutable@4.3.7: {} - import-fresh@3.3.0: dependencies: parent-module: 1.0.1 @@ -13314,36 +10596,12 @@ snapshots: ini@1.3.8: {} - inquirer@7.3.3: - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - run-async: 2.4.1 - rxjs: 6.6.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - internal-slot@1.0.7: dependencies: es-errors: 1.3.0 hasown: 2.0.2 side-channel: 1.0.6 - interpret@1.4.0: {} - - ip-regex@2.1.0: {} - - is-accessor-descriptor@1.0.1: - dependencies: - hasown: 2.0.2 - is-alphabetical@1.0.4: {} is-alphanumerical@1.0.4: @@ -13363,44 +10621,31 @@ snapshots: is-arrayish@0.2.1: {} + is-arrayish@0.3.2: + optional: true + is-async-function@2.0.0: dependencies: has-tostringtag: 1.0.2 - is-base64@0.1.0: {} - is-bigint@1.0.4: dependencies: has-bigints: 1.0.2 - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-blob@1.0.0: {} - - is-blob@2.1.0: {} - is-boolean-object@1.1.2: dependencies: call-bind: 1.0.7 has-tostringtag: 1.0.2 - is-buffer@1.1.6: {} - is-buffer@2.0.5: {} - is-callable@1.2.7: {} - - is-ci@2.0.0: + is-bun-module@1.3.0: dependencies: - ci-info: 2.0.0 + semver: 7.7.1 - is-core-module@2.15.1: - dependencies: - hasown: 2.0.2 + is-callable@1.2.7: {} - is-data-descriptor@1.0.1: + is-core-module@2.15.1: dependencies: hasown: 2.0.2 @@ -13414,33 +10659,12 @@ snapshots: is-decimal@1.0.4: {} - is-descriptor@0.1.7: - dependencies: - is-accessor-descriptor: 1.0.1 - is-data-descriptor: 1.0.1 - - is-descriptor@1.0.3: - dependencies: - is-accessor-descriptor: 1.0.1 - is-data-descriptor: 1.0.1 - - is-docker@2.2.1: - optional: true - - is-extendable@0.1.1: {} - - is-extendable@1.0.1: - dependencies: - is-plain-object: 2.0.4 - is-extglob@2.1.1: {} is-finalizationregistry@1.0.2: dependencies: call-bind: 1.0.7 - is-fullwidth-code-point@2.0.0: {} - is-fullwidth-code-point@3.0.0: {} is-generator-fn@2.1.0: {} @@ -13455,22 +10679,14 @@ snapshots: is-hexadecimal@1.0.4: {} - is-interactive@1.0.0: {} - is-map@2.0.3: {} - is-module@1.0.0: {} - is-negative-zero@2.0.3: {} is-number-object@1.0.7: dependencies: has-tostringtag: 1.0.2 - is-number@3.0.0: - dependencies: - kind-of: 3.2.2 - is-number@7.0.0: {} is-path-inside@3.0.3: {} @@ -13479,16 +10695,8 @@ snapshots: is-plain-obj@2.1.0: {} - is-plain-object@2.0.4: - dependencies: - isobject: 3.0.1 - is-potential-custom-element-name@1.0.1: {} - is-reference@1.2.1: - dependencies: - '@types/estree': 1.0.6 - is-regex@1.1.4: dependencies: call-bind: 1.0.7 @@ -13502,8 +10710,6 @@ snapshots: dependencies: call-bind: 1.0.7 - is-stream@1.1.0: {} - is-stream@2.0.1: {} is-string@1.0.7: @@ -13535,13 +10741,6 @@ snapshots: call-bind: 1.0.7 get-intrinsic: 1.2.4 - is-windows@1.0.2: {} - - is-wsl@2.2.0: - dependencies: - is-docker: 2.2.1 - optional: true - isarray@0.0.1: {} isarray@1.0.0: {} @@ -13550,25 +10749,8 @@ snapshots: isexe@2.0.0: {} - isobject@2.1.0: - dependencies: - isarray: 1.0.0 - - isobject@3.0.1: {} - - isstream@0.1.2: {} - istanbul-lib-coverage@3.2.2: {} - istanbul-lib-instrument@4.0.3: - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - istanbul-lib-instrument@5.2.1(supports-color@9.4.0): dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) @@ -13587,7 +10769,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.7(supports-color@9.4.0) + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -13596,7 +10778,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -13620,34 +10802,18 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jackspeak@4.0.2: - dependencies: - '@isaacs/cliui': 8.0.2 - - jest-changed-files@25.5.0: - dependencies: - '@jest/types': 25.5.0 - execa: 3.4.0 - throat: 5.0.0 - jest-changed-files@28.1.3: dependencies: execa: 5.1.1 p-limit: 3.1.0 - jest-changed-files@29.7.0: - dependencies: - execa: 5.1.1 - jest-util: 29.7.0 - p-limit: 3.1.0 - jest-circus@28.1.3(supports-color@9.4.0): dependencies: '@jest/environment': 28.1.3 '@jest/expect': 28.1.3(supports-color@9.4.0) '@jest/test-result': 28.1.3 '@jest/types': 28.1.3 - '@types/node': 18.19.57 + '@types/node': 22.19.15 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -13665,54 +10831,6 @@ snapshots: transitivePeerDependencies: - supports-color - jest-circus@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 18.19.57 - chalk: 4.1.2 - co: 4.6.0 - dedent: 1.5.3 - is-generator-fn: 2.1.0 - jest-each: 29.7.0 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - p-limit: 3.1.0 - pretty-format: 29.7.0 - pure-rand: 6.1.0 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-cli@25.5.4: - dependencies: - '@jest/core': 25.5.4 - '@jest/test-result': 25.5.0 - '@jest/types': 25.5.0 - chalk: 3.0.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - import-local: 3.2.0 - is-ci: 2.0.0 - jest-config: 25.5.4 - jest-util: 25.5.0 - jest-validate: 25.5.0 - prompts: 2.4.2 - realpath-native: 2.0.0 - yargs: 15.4.1 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate - jest-cli@28.1.3(@types/node@18.19.57): dependencies: '@jest/core': 28.1.3 @@ -13732,33 +10850,6 @@ snapshots: - supports-color - ts-node - jest-config@25.5.4: - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@jest/test-sequencer': 25.5.4 - '@jest/types': 25.5.0 - babel-jest: 25.5.1(@babel/core@7.25.8) - chalk: 3.0.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-environment-jsdom: 25.5.0 - jest-environment-node: 25.5.0 - jest-get-type: 25.2.6 - jest-jasmine2: 25.5.4 - jest-regex-util: 25.2.6 - jest-resolve: 25.5.1 - jest-util: 25.5.0 - jest-validate: 25.5.0 - micromatch: 4.0.8 - pretty-format: 25.5.0 - realpath-native: 2.0.0 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate - jest-config@28.1.3(@types/node@18.19.57): dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) @@ -13788,43 +10879,35 @@ snapshots: transitivePeerDependencies: - supports-color - jest-config@29.5.0(@types/node@18.19.57): + jest-config@28.1.3(@types/node@22.19.15): dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.25.8) + '@jest/test-sequencer': 28.1.3 + '@jest/types': 28.1.3 + babel-jest: 28.1.3(@babel/core@7.25.8) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 glob: 7.2.3 graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.5.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 + jest-circus: 28.1.3(supports-color@9.4.0) + jest-environment-node: 28.1.3 + jest-get-type: 28.0.2 + jest-regex-util: 28.0.2 + jest-resolve: 28.1.3 + jest-runner: 28.1.3 + jest-util: 28.1.3 + jest-validate: 28.1.3 micromatch: 4.0.8 parse-json: 5.2.0 - pretty-format: 29.7.0 + pretty-format: 28.1.3 slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 transitivePeerDependencies: - - babel-plugin-macros - supports-color - jest-diff@25.5.0: - dependencies: - chalk: 3.0.0 - diff-sequences: 25.2.6 - jest-get-type: 25.2.6 - pretty-format: 25.5.0 - jest-diff@27.5.1: dependencies: chalk: 4.1.2 @@ -13839,32 +10922,9 @@ snapshots: jest-get-type: 28.0.2 pretty-format: 28.1.3 - jest-diff@29.7.0: - dependencies: - chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-docblock@25.3.0: - dependencies: - detect-newline: 3.1.0 - jest-docblock@28.1.1: dependencies: - detect-newline: 3.1.0 - - jest-docblock@29.7.0: - dependencies: - detect-newline: 3.1.0 - - jest-each@25.5.0: - dependencies: - '@jest/types': 25.5.0 - chalk: 3.0.0 - jest-get-type: 25.2.6 - jest-util: 25.5.0 - pretty-format: 25.5.0 + detect-newline: 3.1.0 jest-each@28.1.3: dependencies: @@ -13874,34 +10934,13 @@ snapshots: jest-util: 28.1.3 pretty-format: 28.1.3 - jest-each@29.7.0: - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - jest-get-type: 29.6.3 - jest-util: 29.7.0 - pretty-format: 29.7.0 - - jest-environment-jsdom@25.5.0: - dependencies: - '@jest/environment': 25.5.0 - '@jest/fake-timers': 25.5.0 - '@jest/types': 25.5.0 - jest-mock: 25.5.0 - jest-util: 25.5.0 - jsdom: 15.2.1 - transitivePeerDependencies: - - bufferutil - - canvas - - utf-8-validate - jest-environment-jsdom@28.1.3: dependencies: '@jest/environment': 28.1.3 '@jest/fake-timers': 28.1.3 '@jest/types': 28.1.3 '@types/jsdom': 16.2.15 - '@types/node': 18.19.57 + '@types/node': 22.19.15 jest-mock: 28.1.3 jest-util: 28.1.3 jsdom: 19.0.0 @@ -13911,63 +10950,24 @@ snapshots: - supports-color - utf-8-validate - jest-environment-node@25.5.0: - dependencies: - '@jest/environment': 25.5.0 - '@jest/fake-timers': 25.5.0 - '@jest/types': 25.5.0 - jest-mock: 25.5.0 - jest-util: 25.5.0 - semver: 6.3.1 - jest-environment-node@28.1.3: dependencies: '@jest/environment': 28.1.3 '@jest/fake-timers': 28.1.3 '@jest/types': 28.1.3 - '@types/node': 18.19.57 + '@types/node': 22.19.15 jest-mock: 28.1.3 jest-util: 28.1.3 - jest-environment-node@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 18.19.57 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - jest-get-type@25.2.6: {} - jest-get-type@27.5.1: {} jest-get-type@28.0.2: {} - jest-get-type@29.6.3: {} - - jest-haste-map@25.5.1: - dependencies: - '@jest/types': 25.5.0 - '@types/graceful-fs': 4.1.9 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-serializer: 25.5.0 - jest-util: 25.5.0 - jest-worker: 25.5.0 - micromatch: 4.0.8 - sane: 4.1.0 - walker: 1.0.8 - which: 2.0.2 - optionalDependencies: - fsevents: 2.3.3 - jest-haste-map@28.1.3: dependencies: '@jest/types': 28.1.3 '@types/graceful-fs': 4.1.9 - '@types/node': 18.19.57 + '@types/node': 22.19.15 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -13979,62 +10979,11 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - jest-haste-map@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.9 - '@types/node': 18.19.57 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - jest-worker: 29.7.0 - micromatch: 4.0.8 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.3 - - jest-jasmine2@25.5.4: - dependencies: - '@babel/traverse': 7.25.7(supports-color@9.4.0) - '@jest/environment': 25.5.0 - '@jest/source-map': 25.5.0 - '@jest/test-result': 25.5.0 - '@jest/types': 25.5.0 - chalk: 3.0.0 - co: 4.6.0 - expect: 25.5.0 - is-generator-fn: 2.1.0 - jest-each: 25.5.0 - jest-matcher-utils: 25.5.0 - jest-message-util: 25.5.0 - jest-runtime: 25.5.4 - jest-snapshot: 25.5.1 - jest-util: 25.5.0 - pretty-format: 25.5.0 - throat: 5.0.0 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate - - jest-leak-detector@25.5.0: - dependencies: - jest-get-type: 25.2.6 - pretty-format: 25.5.0 - jest-leak-detector@28.1.3: dependencies: jest-get-type: 28.0.2 pretty-format: 28.1.3 - jest-leak-detector@29.7.0: - dependencies: - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - jest-light-runner@0.2.2(jest@28.1.3(@types/node@18.19.57)): dependencies: '@jest/expect': 28.1.3(supports-color@9.4.0) @@ -14046,13 +10995,6 @@ snapshots: piscina: 3.2.0 supports-color: 9.4.0 - jest-matcher-utils@25.5.0: - dependencies: - chalk: 3.0.0 - jest-diff: 25.5.0 - jest-get-type: 25.2.6 - pretty-format: 25.5.0 - jest-matcher-utils@27.5.1: dependencies: chalk: 4.1.2 @@ -14067,24 +11009,6 @@ snapshots: jest-get-type: 28.0.2 pretty-format: 28.1.3 - jest-matcher-utils@29.7.0: - dependencies: - chalk: 4.1.2 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-message-util@25.5.0: - dependencies: - '@babel/code-frame': 7.25.7 - '@jest/types': 25.5.0 - '@types/stack-utils': 1.0.1 - chalk: 3.0.0 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - slash: 3.0.0 - stack-utils: 1.0.5 - jest-message-util@28.1.3: dependencies: '@babel/code-frame': 7.25.7 @@ -14097,61 +11021,17 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 - jest-message-util@29.7.0: - dependencies: - '@babel/code-frame': 7.25.7 - '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - stack-utils: 2.0.6 - - jest-mock@25.5.0: - dependencies: - '@jest/types': 25.5.0 - jest-mock@28.1.3: dependencies: '@jest/types': 28.1.3 - '@types/node': 18.19.57 - - jest-mock@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/node': 18.19.57 - jest-util: 29.7.0 - - jest-pnp-resolver@1.2.3(jest-resolve@25.5.1): - optionalDependencies: - jest-resolve: 25.5.1 + '@types/node': 22.19.15 jest-pnp-resolver@1.2.3(jest-resolve@28.1.3): optionalDependencies: jest-resolve: 28.1.3 - jest-pnp-resolver@1.2.3(jest-resolve@29.5.0): - optionalDependencies: - jest-resolve: 29.5.0 - - jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): - optionalDependencies: - jest-resolve: 29.7.0 - - jest-regex-util@25.2.6: {} - jest-regex-util@28.0.2: {} - jest-regex-util@29.6.3: {} - - jest-resolve-dependencies@25.5.4: - dependencies: - '@jest/types': 25.5.0 - jest-regex-util: 25.2.6 - jest-snapshot: 25.5.1 - jest-resolve-dependencies@28.1.3: dependencies: jest-regex-util: 28.0.2 @@ -14159,25 +11039,6 @@ snapshots: transitivePeerDependencies: - supports-color - jest-resolve-dependencies@29.7.0: - dependencies: - jest-regex-util: 29.6.3 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - jest-resolve@25.5.1: - dependencies: - '@jest/types': 25.5.0 - browser-resolve: 1.11.3 - chalk: 3.0.0 - graceful-fs: 4.2.11 - jest-pnp-resolver: 1.2.3(jest-resolve@25.5.1) - read-pkg-up: 7.0.1 - realpath-native: 2.0.0 - resolve: 1.22.8 - slash: 3.0.0 - jest-resolve@28.1.3: dependencies: chalk: 4.1.2 @@ -14190,57 +11051,6 @@ snapshots: resolve.exports: 1.1.1 slash: 3.0.0 - jest-resolve@29.5.0: - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.5.0) - jest-util: 29.7.0 - jest-validate: 29.7.0 - resolve: 1.22.8 - resolve.exports: 2.0.2 - slash: 3.0.0 - - jest-resolve@29.7.0: - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) - jest-util: 29.7.0 - jest-validate: 29.7.0 - resolve: 1.22.8 - resolve.exports: 2.0.2 - slash: 3.0.0 - - jest-runner@25.5.4: - dependencies: - '@jest/console': 25.5.0 - '@jest/environment': 25.5.0 - '@jest/test-result': 25.5.0 - '@jest/types': 25.5.0 - chalk: 3.0.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 25.5.4 - jest-docblock: 25.3.0 - jest-haste-map: 25.5.1 - jest-jasmine2: 25.5.4 - jest-leak-detector: 25.5.0 - jest-message-util: 25.5.0 - jest-resolve: 25.5.1 - jest-runtime: 25.5.4 - jest-util: 25.5.0 - jest-worker: 25.5.0 - source-map-support: 0.5.21 - throat: 5.0.0 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate - jest-runner@28.1.3: dependencies: '@jest/console': 28.1.3 @@ -14248,7 +11058,7 @@ snapshots: '@jest/test-result': 28.1.3 '@jest/transform': 28.1.3(supports-color@9.4.0) '@jest/types': 28.1.3 - '@types/node': 18.19.57 + '@types/node': 22.19.15 chalk: 4.1.2 emittery: 0.10.2 graceful-fs: 4.2.11 @@ -14267,66 +11077,6 @@ snapshots: transitivePeerDependencies: - supports-color - jest-runner@29.7.0: - dependencies: - '@jest/console': 29.7.0 - '@jest/environment': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 18.19.57 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.11 - jest-docblock: 29.7.0 - jest-environment-node: 29.7.0 - jest-haste-map: 29.7.0 - jest-leak-detector: 29.7.0 - jest-message-util: 29.7.0 - jest-resolve: 29.7.0 - jest-runtime: 29.7.0 - jest-util: 29.7.0 - jest-watcher: 29.7.0 - jest-worker: 29.7.0 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - - jest-runtime@25.5.4: - dependencies: - '@jest/console': 25.5.0 - '@jest/environment': 25.5.0 - '@jest/globals': 25.5.2 - '@jest/source-map': 25.5.0 - '@jest/test-result': 25.5.0 - '@jest/transform': 25.5.1 - '@jest/types': 25.5.0 - '@types/yargs': 15.0.19 - chalk: 3.0.0 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-config: 25.5.4 - jest-haste-map: 25.5.1 - jest-message-util: 25.5.0 - jest-mock: 25.5.0 - jest-regex-util: 25.2.6 - jest-resolve: 25.5.1 - jest-snapshot: 25.5.1 - jest-util: 25.5.0 - jest-validate: 25.5.0 - realpath-native: 2.0.0 - slash: 3.0.0 - strip-bom: 4.0.0 - yargs: 15.4.1 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate - jest-runtime@28.1.3(supports-color@9.4.0): dependencies: '@jest/environment': 28.1.3 @@ -14354,55 +11104,6 @@ snapshots: transitivePeerDependencies: - supports-color - jest-runtime@29.7.0: - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.7.0 - '@jest/source-map': 29.6.3 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 18.19.57 - chalk: 4.1.2 - cjs-module-lexer: 1.4.1 - collect-v8-coverage: 1.0.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - - jest-serializer@25.5.0: - dependencies: - graceful-fs: 4.2.11 - - jest-snapshot@25.5.1: - dependencies: - '@babel/types': 7.25.8 - '@jest/types': 25.5.0 - '@types/prettier': 1.19.1 - chalk: 3.0.0 - expect: 25.5.0 - graceful-fs: 4.2.11 - jest-diff: 25.5.0 - jest-get-type: 25.2.6 - jest-matcher-utils: 25.5.0 - jest-message-util: 25.5.0 - jest-resolve: 25.5.1 - make-dir: 3.1.0 - natural-compare: 1.4.0 - pretty-format: 25.5.0 - semver: 6.3.1 - jest-snapshot@28.1.3(supports-color@9.4.0): dependencies: '@babel/core': 7.25.8(supports-color@9.4.0) @@ -14427,98 +11128,19 @@ snapshots: jest-util: 28.1.3 natural-compare: 1.4.0 pretty-format: 28.1.3 - semver: 7.6.3 - transitivePeerDependencies: - - supports-color - - jest-snapshot@29.5.0: - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@babel/generator': 7.25.7 - '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-syntax-typescript': 7.25.7(@babel/core@7.25.8) - '@babel/traverse': 7.25.7(supports-color@9.4.0) - '@babel/types': 7.25.8 - '@jest/expect-utils': 29.7.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.6.3 - '@types/babel__traverse': 7.20.6 - '@types/prettier': 2.7.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.8) - chalk: 4.1.2 - expect: 29.7.0 - graceful-fs: 4.2.11 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - natural-compare: 1.4.0 - pretty-format: 29.7.0 - semver: 7.6.3 - transitivePeerDependencies: - - supports-color - - jest-snapshot@29.7.0: - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@babel/generator': 7.25.7 - '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.8) - '@babel/plugin-syntax-typescript': 7.25.7(@babel/core@7.25.8) - '@babel/types': 7.25.8 - '@jest/expect-utils': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.8) - chalk: 4.1.2 - expect: 29.7.0 - graceful-fs: 4.2.11 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - natural-compare: 1.4.0 - pretty-format: 29.7.0 - semver: 7.6.3 + semver: 7.7.1 transitivePeerDependencies: - supports-color - jest-util@25.5.0: - dependencies: - '@jest/types': 25.5.0 - chalk: 3.0.0 - graceful-fs: 4.2.11 - is-ci: 2.0.0 - make-dir: 3.1.0 - jest-util@28.1.3: dependencies: '@jest/types': 28.1.3 - '@types/node': 18.19.57 - chalk: 4.1.2 - ci-info: 3.9.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 - - jest-util@29.7.0: - dependencies: - '@jest/types': 29.6.3 - '@types/node': 18.19.57 + '@types/node': 22.19.15 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 picomatch: 2.3.1 - jest-validate@25.5.0: - dependencies: - '@jest/types': 25.5.0 - camelcase: 5.3.1 - chalk: 3.0.0 - jest-get-type: 25.2.6 - leven: 3.1.0 - pretty-format: 25.5.0 - jest-validate@28.1.3: dependencies: '@jest/types': 28.1.3 @@ -14528,25 +11150,6 @@ snapshots: leven: 3.1.0 pretty-format: 28.1.3 - jest-validate@29.7.0: - dependencies: - '@jest/types': 29.6.3 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.6.3 - leven: 3.1.0 - pretty-format: 29.7.0 - - jest-watch-typeahead@0.5.0: - dependencies: - ansi-escapes: 4.3.2 - chalk: 3.0.0 - jest-regex-util: 25.2.6 - jest-watcher: 25.5.0 - slash: 3.0.0 - string-length: 3.1.0 - strip-ansi: 6.0.1 - jest-watch-typeahead@1.1.0(jest@28.1.3(@types/node@18.19.57)): dependencies: ansi-escapes: 4.3.2 @@ -14558,76 +11161,28 @@ snapshots: string-length: 5.0.1 strip-ansi: 7.1.0 - jest-watcher@25.5.0: - dependencies: - '@jest/test-result': 25.5.0 - '@jest/types': 25.5.0 - ansi-escapes: 4.3.2 - chalk: 3.0.0 - jest-util: 25.5.0 - string-length: 3.1.0 - jest-watcher@28.1.3: dependencies: '@jest/test-result': 28.1.3 '@jest/types': 28.1.3 - '@types/node': 18.19.57 + '@types/node': 22.19.15 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.10.2 jest-util: 28.1.3 string-length: 4.0.2 - jest-watcher@29.7.0: - dependencies: - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 18.19.57 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.7.0 - string-length: 4.0.2 - - jest-worker@24.9.0: - dependencies: - merge-stream: 2.0.0 - supports-color: 6.1.0 - - jest-worker@25.5.0: - dependencies: - merge-stream: 2.0.0 - supports-color: 7.2.0 - jest-worker@27.5.1: dependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@28.1.3: dependencies: - '@types/node': 18.19.57 - merge-stream: 2.0.0 - supports-color: 8.1.1 - - jest-worker@29.7.0: - dependencies: - '@types/node': 18.19.57 - jest-util: 29.7.0 + '@types/node': 22.19.15 merge-stream: 2.0.0 - supports-color: 8.1.1 - - jest@25.5.4: - dependencies: - '@jest/core': 25.5.4 - import-local: 3.2.0 - jest-cli: 25.5.4 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate + supports-color: 8.1.1 jest@28.1.3(@types/node@18.19.57): dependencies: @@ -14640,9 +11195,11 @@ snapshots: - supports-color - ts-node + jiti@2.4.2: {} + jju@1.4.0: {} - jpjs@1.2.1: {} + jpeg-exif@1.1.4: {} js-tokens@4.0.0: {} @@ -14655,46 +11212,12 @@ snapshots: dependencies: argparse: 2.0.1 - jsbn@0.1.1: {} - jsdoc-type-pratt-parser@3.1.0: {} - jsdom@15.2.1: - dependencies: - abab: 2.0.6 - acorn: 7.4.1 - acorn-globals: 4.3.4 - array-equal: 1.0.2 - cssom: 0.4.4 - cssstyle: 2.3.0 - data-urls: 1.1.0 - domexception: 1.0.1 - escodegen: 1.14.3 - html-encoding-sniffer: 1.0.2 - nwsapi: 2.2.13 - parse5: 5.1.0 - pn: 1.1.0 - request: 2.88.2 - request-promise-native: 1.0.9(request@2.88.2) - saxes: 3.1.11 - symbol-tree: 3.2.4 - tough-cookie: 3.0.1 - w3c-hr-time: 1.0.2 - w3c-xmlserializer: 1.1.2 - webidl-conversions: 4.0.2 - whatwg-encoding: 1.0.5 - whatwg-mimetype: 2.3.0 - whatwg-url: 7.1.0 - ws: 7.5.10 - xml-name-validator: 3.0.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - jsdom@19.0.0: dependencies: abab: 2.0.6 - acorn: 8.13.0 + acorn: 8.14.0 acorn-globals: 6.0.0 cssom: 0.5.0 cssstyle: 2.3.0 @@ -14725,8 +11248,6 @@ snapshots: - supports-color - utf-8-validate - jsep@1.4.0: {} - jsesc@3.0.2: {} json-buffer@3.0.1: {} @@ -14737,12 +11258,8 @@ snapshots: json-schema-traverse@1.0.0: {} - json-schema@0.4.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} - json-stringify-safe@5.0.1: {} - json5@1.0.2: dependencies: minimist: 1.2.8 @@ -14753,29 +11270,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - jsonfile@4.0.0: - optionalDependencies: - graceful-fs: 4.2.11 - jsonfile@6.1.0: dependencies: universalify: 2.0.1 optionalDependencies: graceful-fs: 4.2.11 - jsonpath-plus@10.1.0: - dependencies: - '@jsep-plugin/assignment': 1.3.0(jsep@1.4.0) - '@jsep-plugin/regex': 1.0.4(jsep@1.4.0) - jsep: 1.4.0 - - jsprim@1.4.2: - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -14787,20 +11287,14 @@ snapshots: dependencies: json-buffer: 3.0.1 - kind-of@3.2.2: - dependencies: - is-buffer: 1.1.6 - - kind-of@4.0.0: - dependencies: - is-buffer: 1.1.6 - kind-of@6.0.3: {} kleur@3.0.3: {} known-css-properties@0.21.0: {} + kolorist@1.8.0: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -14809,27 +11303,66 @@ snapshots: leven@3.1.0: {} - levn@0.3.0: - dependencies: - prelude-ls: 1.1.2 - type-check: 0.3.2 - levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - lilconfig@2.1.0: {} + lightningcss-darwin-arm64@1.29.1: + optional: true + + lightningcss-darwin-x64@1.29.1: + optional: true + + lightningcss-freebsd-x64@1.29.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.29.1: + optional: true + + lightningcss-linux-arm64-gnu@1.29.1: + optional: true + + lightningcss-linux-arm64-musl@1.29.1: + optional: true + + lightningcss-linux-x64-gnu@1.29.1: + optional: true + + lightningcss-linux-x64-musl@1.29.1: + optional: true + + lightningcss-win32-arm64-msvc@1.29.1: + optional: true + + lightningcss-win32-x64-msvc@1.29.1: + optional: true - linebreak@1.1.0: + lightningcss@1.29.1: dependencies: - base64-js: 0.0.8 - unicode-trie: 2.0.0 + detect-libc: 1.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.29.1 + lightningcss-darwin-x64: 1.29.1 + lightningcss-freebsd-x64: 1.29.1 + lightningcss-linux-arm-gnueabihf: 1.29.1 + lightningcss-linux-arm64-gnu: 1.29.1 + lightningcss-linux-arm64-musl: 1.29.1 + lightningcss-linux-x64-gnu: 1.29.1 + lightningcss-linux-x64-musl: 1.29.1 + lightningcss-win32-arm64-msvc: 1.29.1 + lightningcss-win32-x64-msvc: 1.29.1 lines-and-columns@1.2.4: {} loader-runner@4.3.0: {} + local-pkg@1.1.1: + dependencies: + mlly: 1.7.4 + pkg-types: 2.1.0 + quansync: 0.2.10 + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -14852,25 +11385,11 @@ snapshots: lodash@4.17.21: {} - log-symbols@3.0.0: - dependencies: - chalk: 2.4.2 - log-symbols@4.1.0: dependencies: chalk: 4.1.2 is-unicode-supported: 0.1.0 - log-update@2.3.0: - dependencies: - ansi-escapes: 3.2.0 - cli-cursor: 2.1.0 - wrap-ansi: 3.0.1 - - lolex@5.1.2: - dependencies: - '@sinonjs/commons': 1.8.6 - longest-streak@2.0.4: {} loose-envify@1.4.0: @@ -14879,14 +11398,8 @@ snapshots: loupe@3.1.2: {} - lower-case@2.0.2: - dependencies: - tslib: 2.8.0 - lru-cache@10.4.3: {} - lru-cache@11.0.2: {} - lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -14895,13 +11408,7 @@ snapshots: dependencies: yallist: 4.0.0 - lz-string@1.5.0: {} - - magic-string@0.25.9: - dependencies: - sourcemap-codec: 1.4.8 - - magic-string@0.30.12: + magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -14917,7 +11424,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.6.3 + semver: 7.7.1 make-error@1.3.6: {} @@ -14925,16 +11432,10 @@ snapshots: dependencies: tmpl: 1.0.5 - map-cache@0.2.2: {} - map-obj@1.0.1: {} map-obj@4.3.0: {} - map-visit@1.0.0: - dependencies: - object-visit: 1.0.1 - mathml-tag-names@2.1.3: {} mdast-util-from-markdown@0.8.5: @@ -14984,22 +11485,6 @@ snapshots: transitivePeerDependencies: - supports-color - micromatch@3.1.10: - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - braces: 2.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - extglob: 2.0.4 - fragment-cache: 0.2.1 - kind-of: 6.0.3 - nanomatch: 1.2.13 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -15011,24 +11496,20 @@ snapshots: dependencies: mime-db: 1.52.0 - mimic-fn@1.2.0: {} + mime@3.0.0: {} mimic-fn@2.1.0: {} min-indent@1.0.1: {} - minimatch@10.0.1: + minimatch@3.0.8: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 1.1.11 minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 - minimatch@9.0.3: - dependencies: - brace-expansion: 2.0.1 - minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 @@ -15043,52 +11524,26 @@ snapshots: minipass@7.1.2: {} - mixin-deep@1.3.2: - dependencies: - for-in: 1.0.2 - is-extendable: 1.0.1 - - mkdirp@0.5.6: - dependencies: - minimist: 1.2.8 - - mkdirp@1.0.4: {} - - moment-timezone@0.5.46: + mlly@1.7.4: dependencies: - moment: 2.30.1 + acorn: 8.14.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.5.4 moment@2.30.1: {} - mri@1.2.0: {} - mrmime@2.0.0: {} ms@2.0.0: {} ms@2.1.3: {} - mute-stream@0.0.8: {} + muggle-string@0.4.1: {} - nanoid@3.3.7: {} + nanoid@3.3.11: {} - nanomatch@1.2.13: - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - fragment-cache: 0.2.1 - is-windows: 1.0.2 - kind-of: 6.0.3 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - - nanospinner@1.1.0: - dependencies: - picocolors: 1.1.1 + nanoid@3.3.8: {} natural-compare-lite@1.4.0: {} @@ -15096,19 +11551,37 @@ snapshots: neo-async@2.6.2: {} + next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + '@next/env': 15.2.3 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001669 + postcss: 8.4.31 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + styled-jsx: 5.1.6(react@19.0.0) + optionalDependencies: + '@next/swc-darwin-arm64': 15.2.3 + '@next/swc-darwin-x64': 15.2.3 + '@next/swc-linux-arm64-gnu': 15.2.3 + '@next/swc-linux-arm64-musl': 15.2.3 + '@next/swc-linux-x64-gnu': 15.2.3 + '@next/swc-linux-x64-musl': 15.2.3 + '@next/swc-win32-arm64-msvc': 15.2.3 + '@next/swc-win32-x64-msvc': 15.2.3 + sharp: 0.33.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + nice-napi@1.0.2: dependencies: node-addon-api: 3.2.1 node-gyp-build: 4.8.2 optional: true - nice-try@1.0.5: {} - - no-case@3.0.4: - dependencies: - lower-case: 2.0.2 - tslib: 2.8.0 - node-addon-api@3.2.1: optional: true @@ -15125,15 +11598,6 @@ snapshots: node-int64@0.4.0: {} - node-notifier@6.0.0: - dependencies: - growly: 1.3.0 - is-wsl: 2.2.0 - semver: 6.3.1 - shellwords: 0.1.1 - which: 1.3.1 - optional: true - node-releases@2.0.18: {} normalize-package-data@2.5.0: @@ -15147,23 +11611,15 @@ snapshots: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.15.1 - semver: 7.6.3 + semver: 7.7.1 validate-npm-package-license: 3.0.4 - normalize-path@2.1.1: - dependencies: - remove-trailing-separator: 1.1.0 - normalize-path@3.0.0: {} normalize-range@0.1.2: {} normalize-selector@0.2.0: {} - npm-run-path@2.0.2: - dependencies: - path-key: 2.0.1 - npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -15172,16 +11628,8 @@ snapshots: nwsapi@2.2.13: {} - oauth-sign@0.9.0: {} - object-assign@4.1.1: {} - object-copy@0.1.0: - dependencies: - copy-descriptor: 0.1.1 - define-property: 0.2.5 - kind-of: 3.2.2 - object-inspect@1.13.2: {} object-is@1.1.6: @@ -15191,10 +11639,6 @@ snapshots: object-keys@1.1.1: {} - object-visit@1.0.1: - dependencies: - isobject: 3.0.1 - object.assign@4.1.5: dependencies: call-bind: 1.0.7 @@ -15221,16 +11665,6 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.23.3 - object.hasown@1.1.4: - dependencies: - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 - - object.pick@1.3.0: - dependencies: - isobject: 3.0.1 - object.values@1.2.0: dependencies: call-bind: 1.0.7 @@ -15241,23 +11675,10 @@ snapshots: dependencies: wrappy: 1.0.2 - onetime@2.0.1: - dependencies: - mimic-fn: 1.2.0 - onetime@5.1.2: dependencies: mimic-fn: 2.1.0 - optionator@0.8.3: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.3.0 - prelude-ls: 1.1.2 - type-check: 0.3.2 - word-wrap: 1.2.5 - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -15267,25 +11688,6 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 - ora@4.1.1: - dependencies: - chalk: 3.0.0 - cli-cursor: 3.1.0 - cli-spinners: 2.9.2 - is-interactive: 1.0.0 - log-symbols: 3.0.0 - mute-stream: 0.0.8 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - os-tmpdir@1.0.2: {} - - p-each-series@2.2.0: {} - - p-finally@1.0.0: {} - - p-finally@2.0.1: {} - p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -15330,23 +11732,14 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - parse5@5.1.0: {} - parse5@6.0.1: {} - pascal-case@3.1.2: - dependencies: - no-case: 3.0.4 - tslib: 2.8.0 - - pascalcase@0.1.1: {} + path-browserify@1.0.1: {} path-exists@4.0.0: {} path-is-absolute@1.0.1: {} - path-key@2.0.1: {} - path-key@3.1.1: {} path-parse@1.0.7: {} @@ -15356,17 +11749,14 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-scurry@2.0.0: - dependencies: - lru-cache: 11.0.2 - minipass: 7.1.2 - path-to-regexp@2.4.0: {} path-type@4.0.0: {} pathe@1.1.2: {} + pathe@2.0.3: {} + pathval@2.0.0: {} pdf-parse@1.1.1: @@ -15374,22 +11764,12 @@ snapshots: debug: 3.2.7 node-ensure: 0.0.0 - pdfkit@0.12.3: - dependencies: - crypto-js: 4.2.0 - fontkit: 1.9.0 - linebreak: 1.1.0 - png-js: 1.0.0 - - pdfmake@0.1.72: + pdfmake@0.2.23: dependencies: - iconv-lite: 0.6.3 - linebreak: 1.1.0 - pdfkit: 0.12.3 - svg-to-pdfkit: 0.1.8 - xmldoc: 1.3.0 - - performance-now@2.1.0: {} + '@foliojs-fork/linebreak': 1.1.2 + '@foliojs-fork/pdfkit': 0.15.3 + iconv-lite: 0.7.2 + xmldoc: 2.0.3 picocolors@0.2.1: {} @@ -15399,6 +11779,8 @@ snapshots: picomatch@4.0.2: {} + picomatch@4.0.3: {} + pirates@4.0.6: {} piscina@3.2.0: @@ -15413,13 +11795,19 @@ snapshots: dependencies: find-up: 4.1.0 - pn@1.1.0: {} - - png-js@1.0.0: {} + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.4 + pathe: 2.0.3 - pngjs@5.0.0: {} + pkg-types@2.1.0: + dependencies: + confbox: 0.2.1 + exsolve: 1.0.4 + pathe: 2.0.3 - posix-character-classes@0.1.1: {} + png-js@1.0.0: {} possible-typed-array-names@1.0.0: {} @@ -15471,13 +11859,23 @@ snapshots: picocolors: 0.2.1 source-map: 0.6.1 - postcss@8.4.47: + postcss@8.4.31: + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.3: dependencies: - nanoid: 3.3.7 + nanoid: 3.3.8 picocolors: 1.1.1 source-map-js: 1.2.1 - prelude-ls@1.1.2: {} + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 prelude-ls@1.2.1: {} @@ -15485,17 +11883,8 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier@1.19.1: {} - prettier@2.8.8: {} - pretty-format@25.5.0: - dependencies: - '@jest/types': 25.5.0 - ansi-regex: 5.0.1 - ansi-styles: 4.3.0 - react-is: 16.13.1 - pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 @@ -15509,23 +11898,8 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - process-nextick-args@2.0.1: {} - progress-estimator@0.2.2: - dependencies: - chalk: 2.4.2 - cli-spinners: 1.3.1 - humanize-duration: 3.32.1 - log-update: 2.3.0 - - progress@2.0.3: {} - prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -15539,22 +11913,9 @@ snapshots: psl@1.9.0: {} - pump@3.0.2: - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - punycode@2.3.1: {} - pure-rand@6.1.0: {} - - qrcode@1.5.4: - dependencies: - dijkstrajs: 1.0.3 - pngjs: 5.0.0 - yargs: 15.4.1 - - qs@6.5.3: {} + quansync@0.2.10: {} querystring@0.2.1: {} @@ -15568,12 +11929,19 @@ snapshots: dependencies: safe-buffer: 5.2.1 + react-dom@19.0.0(react@19.0.0): + dependencies: + react: 19.0.0 + scheduler: 0.25.0 + react-is@16.13.1: {} react-is@17.0.2: {} react-is@18.3.1: {} + react@19.0.0: {} + read-pkg-up@7.0.1: dependencies: find-up: 4.1.0 @@ -15610,16 +11978,6 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - realpath-native@2.0.0: {} - - rechoir@0.6.2: - dependencies: - resolve: 1.22.8 - redent@3.0.0: dependencies: indent-string: 4.0.0 @@ -15641,19 +11999,12 @@ snapshots: regenerate@1.4.2: {} - regenerator-runtime@0.13.11: {} - regenerator-runtime@0.14.1: {} regenerator-transform@0.15.2: dependencies: '@babel/runtime': 7.25.7 - regex-not@1.0.2: - dependencies: - extend-shallow: 3.0.2 - safe-regex: 1.1.0 - regexp.prototype.flags@1.5.3: dependencies: call-bind: 1.0.7 @@ -15661,10 +12012,6 @@ snapshots: es-errors: 1.3.0 set-function-name: 2.0.2 - regexpp@2.0.1: {} - - regexpp@3.2.0: {} - regexpu-core@6.1.1: dependencies: regenerate: 1.4.2 @@ -15698,53 +12045,12 @@ snapshots: transitivePeerDependencies: - supports-color - remove-trailing-separator@1.1.0: {} - - repeat-element@1.1.4: {} - repeat-string@1.6.1: {} - request-promise-core@1.1.4(request@2.88.2): - dependencies: - lodash: 4.17.21 - request: 2.88.2 - - request-promise-native@1.0.9(request@2.88.2): - dependencies: - request: 2.88.2 - request-promise-core: 1.1.4(request@2.88.2) - stealthy-require: 1.1.1 - tough-cookie: 2.5.0 - - request@2.88.2: - dependencies: - aws-sign2: 0.7.0 - aws4: 1.13.2 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - har-validator: 5.1.5 - http-signature: 1.2.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - oauth-sign: 0.9.0 - performance-now: 2.1.0 - qs: 6.5.3 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 3.4.0 - require-directory@2.1.1: {} require-from-string@2.0.2: {} - require-main-filename@2.0.0: {} - requires-port@1.0.0: {} resolve-cwd@3.0.0: @@ -15755,18 +12061,10 @@ snapshots: resolve-from@5.0.0: {} - resolve-url@0.2.1: {} + resolve-pkg-maps@1.0.0: {} resolve.exports@1.1.1: {} - resolve.exports@2.0.2: {} - - resolve@1.1.7: {} - - resolve@1.17.0: - dependencies: - path-parse: 1.0.7 - resolve@1.22.8: dependencies: is-core-module: 2.15.1 @@ -15779,114 +12077,47 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@2.0.0: - dependencies: - onetime: 2.0.1 - signal-exit: 3.0.7 - - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - - restructure@2.0.1: {} - - ret@0.1.15: {} - - reusify@1.0.4: {} - - rimraf@2.6.3: - dependencies: - glob: 7.2.3 - - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - - rimraf@6.0.1: - dependencies: - glob: 11.0.0 - package-json-from-dist: 1.0.1 - - rollup-plugin-sourcemaps@0.6.3(@types/node@18.19.57)(rollup@1.32.1): - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@1.32.1) - rollup: 1.32.1 - source-map-resolve: 0.6.0 - optionalDependencies: - '@types/node': 18.19.57 - - rollup-plugin-terser@5.3.1(rollup@1.32.1): - dependencies: - '@babel/code-frame': 7.25.7 - jest-worker: 24.9.0 - rollup: 1.32.1 - rollup-pluginutils: 2.8.2 - serialize-javascript: 4.0.0 - terser: 4.8.1 - - rollup-plugin-typescript2@0.27.3(rollup@1.32.1)(typescript@3.9.10): - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@1.32.1) - find-cache-dir: 3.3.2 - fs-extra: 8.1.0 - resolve: 1.17.0 - rollup: 1.32.1 - tslib: 2.0.1 - typescript: 3.9.10 - - rollup-pluginutils@2.8.2: - dependencies: - estree-walker: 0.6.1 + reusify@1.0.4: {} - rollup@1.32.1: + rimraf@3.0.2: dependencies: - '@types/estree': 1.0.6 - '@types/node': 18.19.57 - acorn: 7.4.1 - - rollup@3.29.5: - optionalDependencies: - fsevents: 2.3.3 + glob: 7.2.3 - rollup@4.24.0: + rollup@4.59.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.24.0 - '@rollup/rollup-android-arm64': 4.24.0 - '@rollup/rollup-darwin-arm64': 4.24.0 - '@rollup/rollup-darwin-x64': 4.24.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.24.0 - '@rollup/rollup-linux-arm-musleabihf': 4.24.0 - '@rollup/rollup-linux-arm64-gnu': 4.24.0 - '@rollup/rollup-linux-arm64-musl': 4.24.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.24.0 - '@rollup/rollup-linux-riscv64-gnu': 4.24.0 - '@rollup/rollup-linux-s390x-gnu': 4.24.0 - '@rollup/rollup-linux-x64-gnu': 4.24.0 - '@rollup/rollup-linux-x64-musl': 4.24.0 - '@rollup/rollup-win32-arm64-msvc': 4.24.0 - '@rollup/rollup-win32-ia32-msvc': 4.24.0 - '@rollup/rollup-win32-x64-msvc': 4.24.0 + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 - rsvp@4.8.5: {} - - run-async@2.4.1: {} - run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - rxjs@6.6.7: - dependencies: - tslib: 1.14.1 - - sade@1.8.1: - dependencies: - mri: 1.2.0 - safe-array-concat@1.1.2: dependencies: call-bind: 1.0.7 @@ -15904,43 +12135,18 @@ snapshots: es-errors: 1.3.0 is-regex: 1.1.4 - safe-regex@1.1.0: - dependencies: - ret: 0.1.15 - safer-buffer@2.1.2: {} - sane@4.1.0: - dependencies: - '@cnakazawa/watch': 1.0.4 - anymatch: 2.0.0 - capture-exit: 2.0.0 - exec-sh: 0.3.6 - execa: 1.0.0 - fb-watchman: 2.0.2 - micromatch: 3.1.10 - minimist: 1.2.8 - walker: 1.0.8 - - save-file@2.3.1: - dependencies: - file-saver: 2.0.5 - is-blob: 1.0.0 - is-buffer: 2.0.5 - simple-mime: 0.1.0 - to-array-buffer: 3.2.0 - write: 1.0.3 - sax@1.4.1: {} - saxes@3.1.11: - dependencies: - xmlchars: 2.2.0 + sax@1.5.0: {} saxes@5.0.1: dependencies: xmlchars: 2.2.0 + scheduler@0.25.0: {} + schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 @@ -15951,26 +12157,18 @@ snapshots: semver@6.3.1: {} - semver@7.3.5: - dependencies: - lru-cache: 6.0.0 - semver@7.5.4: dependencies: lru-cache: 6.0.0 semver@7.6.3: {} - serialize-javascript@4.0.0: - dependencies: - randombytes: 2.1.0 + semver@7.7.1: {} serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 - set-blocking@2.0.0: {} - set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -15987,34 +12185,39 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 - set-value@2.0.1: - dependencies: - extend-shallow: 2.0.1 - is-extendable: 0.1.1 - is-plain-object: 2.0.4 - split-string: 3.1.0 - - shebang-command@1.2.0: + sharp@0.33.5: dependencies: - shebang-regex: 1.0.0 + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.7.1 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + optional: true shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 - shebang-regex@1.0.0: {} - shebang-regex@3.0.0: {} - shelljs@0.8.5: - dependencies: - glob: 7.2.3 - interpret: 1.4.0 - rechoir: 0.6.2 - - shellwords@0.1.1: - optional: true - side-channel@1.0.6: dependencies: call-bind: 1.0.7 @@ -16028,7 +12231,10 @@ snapshots: signal-exit@4.1.0: {} - simple-mime@0.1.0: {} + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + optional: true sirv@2.0.4: dependencies: @@ -16038,69 +12244,20 @@ snapshots: sisteransi@1.0.5: {} - size-limit@7.0.8: - dependencies: - bytes-iec: 3.1.1 - chokidar: 3.6.0 - ci-job-number: 1.2.2 - globby: 11.1.0 - lilconfig: 2.1.0 - mkdirp: 1.0.4 - nanospinner: 1.1.0 - picocolors: 1.1.1 - slash@3.0.0: {} slash@4.0.0: {} - slice-ansi@2.1.0: - dependencies: - ansi-styles: 3.2.1 - astral-regex: 1.0.0 - is-fullwidth-code-point: 2.0.0 - slice-ansi@4.0.0: dependencies: ansi-styles: 4.3.0 astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 - snapdragon-node@2.1.1: - dependencies: - define-property: 1.0.0 - isobject: 3.0.1 - snapdragon-util: 3.0.1 - - snapdragon-util@3.0.1: - dependencies: - kind-of: 3.2.2 - - snapdragon@0.8.2: - dependencies: - base: 0.11.2 - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - map-cache: 0.2.2 - source-map: 0.5.7 - source-map-resolve: 0.5.3 - use: 3.1.1 + smob@1.5.0: {} source-map-js@1.2.1: {} - source-map-resolve@0.5.3: - dependencies: - atob: 2.1.2 - decode-uri-component: 0.2.2 - resolve-url: 0.2.1 - source-map-url: 0.4.1 - urix: 0.1.0 - - source-map-resolve@0.6.0: - dependencies: - atob: 2.1.2 - decode-uri-component: 0.2.2 - source-map-support@0.5.13: dependencies: buffer-from: 1.1.2 @@ -16111,16 +12268,8 @@ snapshots: buffer-from: 1.1.2 source-map: 0.6.1 - source-map-url@0.4.1: {} - - source-map@0.5.7: {} - source-map@0.6.1: {} - source-map@0.7.4: {} - - sourcemap-codec@1.4.8: {} - spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 @@ -16137,27 +12286,9 @@ snapshots: specificity@0.4.1: {} - split-string@3.1.0: - dependencies: - extend-shallow: 3.0.2 - sprintf-js@1.0.3: {} - sshpk@1.18.0: - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - - stack-utils@1.0.5: - dependencies: - escape-string-regexp: 2.0.0 + stable-hash@0.0.4: {} stack-utils@2.0.6: dependencies: @@ -16165,25 +12296,15 @@ snapshots: stackback@0.0.2: {} - static-extend@0.1.2: - dependencies: - define-property: 0.2.5 - object-copy: 0.1.0 - std-env@3.7.0: {} - stealthy-require@1.1.1: {} - stop-iteration-iterator@1.0.0: dependencies: internal-slot: 1.0.7 - string-argv@0.3.2: {} + streamsearch@1.1.0: {} - string-length@3.1.0: - dependencies: - astral-regex: 1.0.0 - strip-ansi: 5.2.0 + string-argv@0.3.2: {} string-length@4.0.2: dependencies: @@ -16195,22 +12316,6 @@ snapshots: char-regex: 2.0.1 strip-ansi: 7.1.0 - string-to-arraybuffer@1.0.2: - dependencies: - atob-lite: 2.0.0 - is-base64: 0.1.0 - - string-width@2.1.1: - dependencies: - is-fullwidth-code-point: 2.0.0 - strip-ansi: 4.0.0 - - string-width@3.1.0: - dependencies: - emoji-regex: 7.0.3 - is-fullwidth-code-point: 2.0.0 - strip-ansi: 5.2.0 - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -16278,14 +12383,6 @@ snapshots: dependencies: safe-buffer: 5.2.1 - strip-ansi@4.0.0: - dependencies: - ansi-regex: 3.0.1 - - strip-ansi@5.2.0: - dependencies: - ansi-regex: 4.1.1 - strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -16298,8 +12395,6 @@ snapshots: strip-bom@4.0.0: {} - strip-eof@1.0.0: {} - strip-final-newline@2.0.0: {} strip-indent@3.0.0: @@ -16310,6 +12405,11 @@ snapshots: style-search@0.1.0: {} + styled-jsx@5.1.6(react@19.0.0): + dependencies: + client-only: 0.0.1 + react: 19.0.0 + stylelint-config-recommended@5.0.0(stylelint@13.13.1): dependencies: stylelint: 13.13.1 @@ -16382,10 +12482,6 @@ snapshots: dependencies: has-flag: 3.0.0 - supports-color@6.1.0: - dependencies: - has-flag: 3.0.0 - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -16405,19 +12501,8 @@ snapshots: svg-tags@1.0.0: {} - svg-to-pdfkit@0.1.8: - dependencies: - pdfkit: 0.12.3 - symbol-tree@3.2.4: {} - table@5.4.6: - dependencies: - ajv: 6.12.6 - lodash: 4.17.21 - slice-ansi: 2.1.0 - string-width: 3.1.0 - table@6.8.2: dependencies: ajv: 8.17.1 @@ -16426,7 +12511,7 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tapable@1.1.3: {} + tailwindcss@4.0.9: {} tapable@2.2.1: {} @@ -16444,12 +12529,6 @@ snapshots: terser: 5.36.0 webpack: 5.95.0 - terser@4.8.1: - dependencies: - commander: 2.20.3 - source-map: 0.6.1 - source-map-support: 0.5.21 - terser@5.36.0: dependencies: '@jridgewell/source-map': 0.3.6 @@ -16471,79 +12550,38 @@ snapshots: text-table@0.2.0: {} - throat@5.0.0: {} - - through@2.3.8: {} - - tiny-glob@0.2.9: - dependencies: - globalyzer: 0.1.0 - globrex: 0.1.2 - tiny-inflate@1.0.3: {} tinybench@2.9.0: {} tinyexec@0.3.1: {} - tinyglobby@0.2.9: + tinyglobby@0.2.12: dependencies: - fdir: 6.4.2(picomatch@4.0.2) + fdir: 6.4.3(picomatch@4.0.2) picomatch: 4.0.2 + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + tinypool@1.0.1: {} tinyrainbow@1.2.0: {} tinyspy@3.0.2: {} - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 - tmpl@1.0.5: {} - to-array-buffer@3.2.0: - dependencies: - flatten-vertex-data: 1.0.2 - is-blob: 2.1.0 - string-to-arraybuffer: 1.0.2 - to-fast-properties@2.0.0: {} - to-object-path@0.3.0: - dependencies: - kind-of: 3.2.2 - - to-regex-range@2.1.1: - dependencies: - is-number: 3.0.0 - repeat-string: 1.6.1 - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - to-regex@3.0.2: - dependencies: - define-property: 2.0.2 - extend-shallow: 3.0.2 - regex-not: 1.0.2 - safe-regex: 1.1.0 - totalist@3.0.1: {} - tough-cookie@2.5.0: - dependencies: - psl: 1.9.0 - punycode: 2.3.1 - - tough-cookie@3.0.1: - dependencies: - ip-regex: 2.1.0 - psl: 1.9.0 - punycode: 2.3.1 - tough-cookie@4.1.4: dependencies: psl: 1.9.0 @@ -16569,20 +12607,9 @@ snapshots: dependencies: typescript: 5.6.3 - ts-jest@25.5.1(jest@25.5.4)(typescript@3.9.10): + ts-api-utils@1.4.0(typescript@5.7.2): dependencies: - bs-logger: 0.2.6 - buffer-from: 1.1.2 - fast-json-stable-stringify: 2.1.0 - jest: 25.5.4 - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - micromatch: 4.0.8 - mkdirp: 0.5.6 - semver: 6.3.1 - typescript: 3.9.10 - yargs-parser: 18.1.3 + typescript: 5.7.2 ts-jest@28.0.8(@babel/core@7.25.8)(@jest/types@28.1.3)(babel-jest@28.1.3(@babel/core@7.25.8))(jest@28.1.3(@types/node@18.19.57))(typescript@5.6.3): dependencies: @@ -16614,6 +12641,10 @@ snapshots: optionalDependencies: typescript: 5.6.3 + tsconfck@2.1.2(typescript@5.8.2): + optionalDependencies: + typescript: 5.8.2 + tsconfig-paths-webpack-plugin@3.5.2: dependencies: chalk: 4.1.2 @@ -16633,92 +12664,16 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tsdx@0.14.1(@types/babel__core@7.20.5)(@types/node@18.19.57): - dependencies: - '@babel/core': 7.25.8(supports-color@9.4.0) - '@babel/helper-module-imports': 7.25.7(supports-color@9.4.0) - '@babel/parser': 7.25.8 - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.25.8) - '@babel/preset-env': 7.25.8(@babel/core@7.25.8) - '@babel/traverse': 7.25.7(supports-color@9.4.0) - '@rollup/plugin-babel': 5.3.1(@babel/core@7.25.8)(@types/babel__core@7.20.5)(rollup@1.32.1) - '@rollup/plugin-commonjs': 11.1.0(rollup@1.32.1) - '@rollup/plugin-json': 4.1.0(rollup@1.32.1) - '@rollup/plugin-node-resolve': 9.0.0(rollup@1.32.1) - '@rollup/plugin-replace': 2.4.2(rollup@1.32.1) - '@types/jest': 25.2.3 - '@typescript-eslint/eslint-plugin': 2.34.0(@typescript-eslint/parser@2.34.0(eslint@6.8.0)(typescript@3.9.10))(eslint@6.8.0)(typescript@3.9.10) - '@typescript-eslint/parser': 2.34.0(eslint@6.8.0)(typescript@3.9.10) - ansi-escapes: 4.3.2 - asyncro: 3.0.0 - babel-eslint: 10.1.0(eslint@6.8.0) - babel-plugin-annotate-pure-calls: 0.4.0(@babel/core@7.25.8) - babel-plugin-dev-expression: 0.2.3(@babel/core@7.25.8) - babel-plugin-macros: 2.8.0 - babel-plugin-polyfill-regenerator: 0.0.4(@babel/core@7.25.8) - babel-plugin-transform-rename-import: 2.3.0 - camelcase: 6.3.0 - chalk: 4.1.2 - enquirer: 2.4.1 - eslint: 6.8.0 - eslint-config-prettier: 6.15.0(eslint@6.8.0) - eslint-config-react-app: 5.2.1(@typescript-eslint/eslint-plugin@2.34.0(@typescript-eslint/parser@2.34.0(eslint@6.8.0)(typescript@3.9.10))(eslint@6.8.0)(typescript@3.9.10))(@typescript-eslint/parser@2.34.0(eslint@6.8.0)(typescript@3.9.10))(babel-eslint@10.1.0(eslint@6.8.0))(eslint-plugin-flowtype@3.13.0(eslint@6.8.0))(eslint-plugin-import@2.31.0(eslint@6.8.0))(eslint-plugin-jsx-a11y@6.10.0(eslint@6.8.0))(eslint-plugin-react-hooks@2.5.1(eslint@6.8.0))(eslint-plugin-react@7.37.1(eslint@6.8.0))(eslint@6.8.0) - eslint-plugin-flowtype: 3.13.0(eslint@6.8.0) - eslint-plugin-import: 2.31.0(eslint@6.8.0) - eslint-plugin-jsx-a11y: 6.10.0(eslint@6.8.0) - eslint-plugin-prettier: 3.4.1(eslint-config-prettier@6.15.0(eslint@6.8.0))(eslint@6.8.0)(prettier@1.19.1) - eslint-plugin-react: 7.37.1(eslint@6.8.0) - eslint-plugin-react-hooks: 2.5.1(eslint@6.8.0) - execa: 4.1.0 - fs-extra: 9.1.0 - jest: 25.5.4 - jest-watch-typeahead: 0.5.0 - jpjs: 1.2.1 - lodash.merge: 4.6.2 - ora: 4.1.1 - pascal-case: 3.1.2 - prettier: 1.19.1 - progress-estimator: 0.2.2 - regenerator-runtime: 0.13.11 - rollup: 1.32.1 - rollup-plugin-sourcemaps: 0.6.3(@types/node@18.19.57)(rollup@1.32.1) - rollup-plugin-terser: 5.3.1(rollup@1.32.1) - rollup-plugin-typescript2: 0.27.3(rollup@1.32.1)(typescript@3.9.10) - sade: 1.8.1 - semver: 7.6.3 - shelljs: 0.8.5 - tiny-glob: 0.2.9 - ts-jest: 25.5.1(jest@25.5.4)(typescript@3.9.10) - tslib: 1.14.1 - typescript: 3.9.10 - transitivePeerDependencies: - - '@types/babel__core' - - '@types/node' - - bufferutil - - canvas - - supports-color - - utf-8-validate - - tslib@1.14.1: {} - - tslib@2.0.1: {} - tslib@2.8.0: {} - tsutils@3.21.0(typescript@3.9.10): - dependencies: - tslib: 1.14.1 - typescript: 3.9.10 - - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - - tweetnacl@0.14.5: {} + tslib@2.8.1: {} - type-check@0.3.2: + tsx@4.21.0: dependencies: - prelude-ls: 1.1.2 + esbuild: 0.27.4 + get-tsconfig: 4.10.0 + optionalDependencies: + fsevents: 2.3.3 type-check@0.4.0: dependencies: @@ -16774,10 +12729,14 @@ snapshots: dependencies: is-typedarray: 1.0.0 - typescript@3.9.10: {} - typescript@5.6.3: {} + typescript@5.7.2: {} + + typescript@5.8.2: {} + + ufo@1.5.4: {} + unbox-primitive@1.0.2: dependencies: call-bind: 1.0.7 @@ -16787,6 +12746,8 @@ snapshots: undici-types@5.26.5: {} + undici-types@6.21.0: {} + unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-match-property-ecmascript@2.0.0: @@ -16817,13 +12778,6 @@ snapshots: trough: 1.0.5 vfile: 4.2.1 - union-value@1.0.1: - dependencies: - arr-union: 3.1.0 - get-value: 2.0.6 - is-extendable: 0.1.1 - set-value: 2.0.1 - unist-util-find-all-after@3.0.2: dependencies: unist-util-is: 4.1.0 @@ -16840,11 +12794,6 @@ snapshots: universalify@2.0.1: {} - unset-value@1.0.0: - dependencies: - has-value: 0.3.1 - isobject: 3.0.1 - update-browserslist-db@1.1.1(browserslist@4.24.0): dependencies: browserslist: 4.24.0 @@ -16857,27 +12806,15 @@ snapshots: urijs@1.19.11: {} - urix@0.1.0: {} - url-parse@1.5.10: dependencies: querystringify: 2.2.0 requires-port: 1.0.0 - use@3.1.1: {} - util-deprecate@1.0.2: {} - uuid@3.4.0: {} - v8-compile-cache@2.4.0: {} - v8-to-istanbul@4.1.4: - dependencies: - '@types/istanbul-lib-coverage': 2.0.6 - convert-source-map: 1.9.0 - source-map: 0.7.4 - v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.25 @@ -16889,16 +12826,8 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - validate-rfc@2.0.3: {} - validator@9.4.1: {} - verror@1.10.0: - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - vfile-message@2.0.4: dependencies: '@types/unist': 2.0.11 @@ -16911,12 +12840,12 @@ snapshots: unist-util-stringify-position: 2.0.3 vfile-message: 2.0.4 - vite-node@2.1.3(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0): + vite-node@2.1.3(@types/node@22.19.15)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0): dependencies: cac: 6.7.14 - debug: 4.3.7(supports-color@9.4.0) + debug: 4.4.0 pathe: 1.1.2 - vite: 5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0) + vite: 5.4.9(@types/node@22.19.15)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) transitivePeerDependencies: - '@types/node' - less @@ -16928,73 +12857,118 @@ snapshots: - supports-color - terser - vite-tsconfig-paths@4.2.3(typescript@5.6.3)(vite@4.5.5(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)): + vite-plugin-dts@4.5.3(@types/node@22.19.15)(rollup@4.59.0)(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)): + dependencies: + '@microsoft/api-extractor': 7.52.1(@types/node@22.19.15) + '@rollup/pluginutils': 5.1.4(rollup@4.59.0) + '@volar/typescript': 2.4.12 + '@vue/language-core': 2.2.0(typescript@5.6.3) + compare-versions: 6.1.1 + debug: 4.4.0 + kolorist: 1.8.0 + local-pkg: 1.1.1 + magic-string: 0.30.17 + typescript: 5.6.3 + optionalDependencies: + vite: 7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0) + transitivePeerDependencies: + - '@types/node' + - rollup + - supports-color + + vite-plugin-dts@4.5.3(@types/node@22.19.15)(rollup@4.59.0)(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)): + dependencies: + '@microsoft/api-extractor': 7.52.1(@types/node@22.19.15) + '@rollup/pluginutils': 5.1.4(rollup@4.59.0) + '@volar/typescript': 2.4.12 + '@vue/language-core': 2.2.0(typescript@5.8.2) + compare-versions: 6.1.1 + debug: 4.4.0 + kolorist: 1.8.0 + local-pkg: 1.1.1 + magic-string: 0.30.17 + typescript: 5.8.2 + optionalDependencies: + vite: 7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0) + transitivePeerDependencies: + - '@types/node' + - rollup + - supports-color + + vite-tsconfig-paths@4.2.3(typescript@5.6.3)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.36.0)(tsx@4.21.0)): dependencies: debug: 4.3.7(supports-color@9.4.0) globrex: 0.1.2 tsconfck: 2.1.2(typescript@5.6.3) optionalDependencies: - vite: 4.5.5(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0) + vite: 7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0) transitivePeerDependencies: - supports-color - typescript - vite-tsconfig-paths@4.2.3(typescript@5.6.3)(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)): + vite-tsconfig-paths@4.2.3(typescript@5.8.2)(vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0)): dependencies: debug: 4.3.7(supports-color@9.4.0) globrex: 0.1.2 - tsconfck: 2.1.2(typescript@5.6.3) + tsconfck: 2.1.2(typescript@5.8.2) optionalDependencies: - vite: 5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0) + vite: 7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0) transitivePeerDependencies: - supports-color - typescript - vite@4.5.5(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0): + vite@5.4.9(@types/node@22.19.15)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0): dependencies: - esbuild: 0.18.20 - postcss: 8.4.47 - rollup: 3.29.5 + esbuild: 0.21.5 + postcss: 8.5.8 + rollup: 4.59.0 optionalDependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 fsevents: 2.3.3 + lightningcss: 1.29.1 sugarss: 2.0.0 terser: 5.36.0 - vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0): + vite@7.3.1(@types/node@22.19.15)(jiti@2.4.2)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0)(tsx@4.21.0): dependencies: - esbuild: 0.21.5 - postcss: 8.4.47 - rollup: 4.24.0 + esbuild: 0.27.4 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.8 + rollup: 4.59.0 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.29.1 sugarss: 2.0.0 terser: 5.36.0 + tsx: 4.21.0 - vitest@2.1.3(@types/node@18.19.57)(@vitest/ui@2.1.3)(jsdom@19.0.0)(sugarss@2.0.0)(terser@5.36.0): + vitest@2.1.3(@types/node@22.19.15)(@vitest/ui@2.1.3)(jsdom@19.0.0)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0): dependencies: '@vitest/expect': 2.1.3 - '@vitest/mocker': 2.1.3(vite@5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0)) + '@vitest/mocker': 2.1.3(vite@5.4.9(@types/node@22.19.15)(lightningcss@1.29.1)(terser@5.36.0)) '@vitest/pretty-format': 2.1.3 '@vitest/runner': 2.1.3 '@vitest/snapshot': 2.1.3 '@vitest/spy': 2.1.3 '@vitest/utils': 2.1.3 chai: 5.1.1 - debug: 4.3.7(supports-color@9.4.0) - magic-string: 0.30.12 + debug: 4.4.0 + magic-string: 0.30.17 pathe: 1.1.2 std-env: 3.7.0 tinybench: 2.9.0 tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.9(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0) - vite-node: 2.1.3(@types/node@18.19.57)(sugarss@2.0.0)(terser@5.36.0) + vite: 5.4.9(@types/node@22.19.15)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) + vite-node: 2.1.3(@types/node@22.19.15)(lightningcss@1.29.1)(sugarss@2.0.0)(terser@5.36.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 18.19.57 + '@types/node': 22.19.15 '@vitest/ui': 2.1.3(vitest@2.1.3) jsdom: 19.0.0 transitivePeerDependencies: @@ -17008,16 +12982,12 @@ snapshots: - supports-color - terser + vscode-uri@3.1.0: {} + w3c-hr-time@1.0.2: dependencies: browser-process-hrtime: 1.0.0 - w3c-xmlserializer@1.1.2: - dependencies: - domexception: 1.0.1 - webidl-conversions: 4.0.2 - xml-name-validator: 3.0.0 - w3c-xmlserializer@3.0.0: dependencies: xml-name-validator: 4.0.0 @@ -17026,20 +12996,11 @@ snapshots: dependencies: makeerror: 1.0.12 - watchpack@2.4.0: - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - watchpack@2.4.2: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 - wcwidth@1.0.1: - dependencies: - defaults: 1.0.4 - webidl-conversions@3.0.1: {} webidl-conversions@4.0.2: {} @@ -17078,16 +13039,10 @@ snapshots: - esbuild - uglify-js - whatwg-encoding@1.0.5: - dependencies: - iconv-lite: 0.4.24 - whatwg-encoding@2.0.0: dependencies: iconv-lite: 0.6.3 - whatwg-mimetype@2.3.0: {} - whatwg-mimetype@3.0.0: {} whatwg-url@10.0.0: @@ -17111,12 +13066,6 @@ snapshots: tr46: 1.0.1 webidl-conversions: 4.0.2 - whatwg-url@7.1.0: - dependencies: - lodash.sortby: 4.7.0 - tr46: 1.0.1 - webidl-conversions: 4.0.2 - which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 @@ -17147,8 +13096,6 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.3 - which-module@2.0.1: {} - which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 @@ -17172,17 +13119,6 @@ snapshots: word-wrap@1.2.5: {} - wrap-ansi@3.0.1: - dependencies: - string-width: 2.1.1 - strip-ansi: 4.0.0 - - wrap-ansi@6.2.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -17209,20 +13145,12 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 - write@1.0.3: - dependencies: - mkdirp: 0.5.6 - - ws@7.5.10: {} - ws@8.18.0: {} xml-js@1.6.11: dependencies: sax: 1.4.1 - xml-name-validator@3.0.0: {} - xml-name-validator@4.0.0: {} xml2js@0.4.23: @@ -17234,9 +13162,9 @@ snapshots: xmlchars@2.2.0: {} - xmldoc@1.3.0: + xmldoc@2.0.3: dependencies: - sax: 1.4.1 + sax: 1.5.0 xmldom@0.1.31: {} @@ -17257,14 +13185,6 @@ snapshots: xmldom: 0.1.31 xpath: 0.0.24 - xslt-processor@0.11.7: - dependencies: - he: 1.2.0 - - xslt@0.9.1: {} - - y18n@4.0.3: {} - y18n@5.0.8: {} yallist@3.1.1: {} @@ -17273,29 +13193,10 @@ snapshots: yaml@1.10.2: {} - yargs-parser@18.1.3: - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 - yargs-parser@20.2.9: {} yargs-parser@21.1.1: {} - yargs@15.4.1: - dependencies: - cliui: 6.0.0 - decamelize: 1.2.0 - find-up: 4.1.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - require-main-filename: 2.0.0 - set-blocking: 2.0.0 - string-width: 4.2.3 - which-module: 2.0.1 - y18n: 4.0.3 - yargs-parser: 18.1.3 - yargs@17.7.2: dependencies: cliui: 8.0.1 diff --git a/common/config/rush/version-policies.json b/common/config/rush/version-policies.json index aef78d3a..a2c39c8a 100644 --- a/common/config/rush/version-policies.json +++ b/common/config/rush/version-policies.json @@ -35,6 +35,12 @@ "version": "0.0.10-beta.4", "nextBump": "prerelease" }, + { + "policyName": "auth", + "definitionName": "lockStepVersion", + "version": "1.0.1", + "nextBump": "patch" + }, { "policyName": "curp", "definitionName": "lockStepVersion", @@ -100,5 +106,11 @@ "definitionName": "lockStepVersion", "version": "4.0.13", "nextBump": "patch" + }, + { + "policyName": "designs", + "definitionName": "lockStepVersion", + "version": "4.0.13", + "nextBump": "patch" } ] diff --git a/common/scripts/github-actions.js b/common/scripts/github-actions.js index 92478361..725eecb7 100644 --- a/common/scripts/github-actions.js +++ b/common/scripts/github-actions.js @@ -92,13 +92,31 @@ function getDependences(scope) { }, '2json': { '2json': true + }, + designs: { + designs: true + }, + sat: { + sat: true + }, + estado: { + estado: true + }, + validador: { + validador: true + }, + cleaner: { + cleaner: true + }, + auth: { + auth: true } }; return dependencies[scope] || {}; } function getScopes(commits = []) { - const list = ['catalogs','csd','csf','curp','pdf','rfc','utils','xml','complementos','openssl','saxon','xsd'] + const list = ['catalogs','csd','csf','curp','pdf','rfc','utils','xml','complementos','openssl','saxon','xsd', '2json','designs','sat','estado','validador','cleaner','auth'] const onlys = { 'only-complementos': 'complementos' } diff --git a/common/scripts/install-run-rush-pnpm.js b/common/scripts/install-run-rush-pnpm.js index 2356649f..0fcb0497 100644 --- a/common/scripts/install-run-rush-pnpm.js +++ b/common/scripts/install-run-rush-pnpm.js @@ -17,9 +17,9 @@ /******/ (() => { // webpackBootstrap /******/ "use strict"; var __webpack_exports__ = {}; -/*!*****************************************************!*\ - !*** ./lib-esnext/scripts/install-run-rush-pnpm.js ***! - \*****************************************************/ +/*!***************************************************************!*\ + !*** ./lib-intermediate-esm/scripts/install-run-rush-pnpm.js ***! + \***************************************************************/ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. diff --git a/common/scripts/install-run-rush.js b/common/scripts/install-run-rush.js index 20f33d19..4733f4d8 100644 --- a/common/scripts/install-run-rush.js +++ b/common/scripts/install-run-rush.js @@ -16,25 +16,25 @@ /******/ "use strict"; /******/ var __webpack_modules__ = ({ -/***/ 179896: -/*!*********************!*\ - !*** external "fs" ***! - \*********************/ -/***/ ((module) => { +/***/ 973024 +/*!**************************!*\ + !*** external "node:fs" ***! + \**************************/ +(module) { -module.exports = require("fs"); +module.exports = require("node:fs"); -/***/ }), +/***/ }, -/***/ 16928: -/*!***********************!*\ - !*** external "path" ***! - \***********************/ -/***/ ((module) => { +/***/ 176760 +/*!****************************!*\ + !*** external "node:path" ***! + \****************************/ +(module) { -module.exports = require("path"); +module.exports = require("node:path"); -/***/ }) +/***/ } /******/ }); /************************************************************************/ @@ -48,6 +48,12 @@ module.exports = require("path"); /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } +/******/ // Check if module exists (development only) +/******/ if (__webpack_modules__[moduleId] === undefined) { +/******/ var e = new Error("Cannot find module '" + moduleId + "'"); +/******/ e.code = 'MODULE_NOT_FOUND'; +/******/ throw e; +/******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed @@ -105,16 +111,16 @@ module.exports = require("path"); /******/ /************************************************************************/ var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk. (() => { -/*!************************************************!*\ - !*** ./lib-esnext/scripts/install-run-rush.js ***! - \************************************************/ +/*!**********************************************************!*\ + !*** ./lib-intermediate-esm/scripts/install-run-rush.js ***! + \**********************************************************/ __webpack_require__.r(__webpack_exports__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! path */ 16928); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ 179896); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! node:path */ 176760); +/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(node_path__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! node:fs */ 973024); +/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(node_fs__WEBPACK_IMPORTED_MODULE_1__); // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. /* eslint-disable no-console */ @@ -131,9 +137,9 @@ function _getRushVersion(logger) { return rushPreviewVersion; } const rushJsonFolder = findRushJsonFolder(); - const rushJsonPath = path__WEBPACK_IMPORTED_MODULE_0__.join(rushJsonFolder, RUSH_JSON_FILENAME); + const rushJsonPath = node_path__WEBPACK_IMPORTED_MODULE_0__.join(rushJsonFolder, RUSH_JSON_FILENAME); try { - const rushJsonContents = fs__WEBPACK_IMPORTED_MODULE_1__.readFileSync(rushJsonPath, 'utf-8'); + const rushJsonContents = node_fs__WEBPACK_IMPORTED_MODULE_1__.readFileSync(rushJsonPath, 'utf-8'); // Use a regular expression to parse out the rushVersion value because rush.json supports comments, // but JSON.parse does not and we don't want to pull in more dependencies than we need to in this script. const rushJsonMatches = rushJsonContents.match(/\"rushVersion\"\s*\:\s*\"([0-9a-zA-Z.+\-]+)\"/); @@ -159,7 +165,7 @@ function _run() { const [nodePath /* Ex: /bin/node */, scriptPath /* /repo/common/scripts/install-run-rush.js */, ...packageBinArgs /* [build, --to, myproject] */] = process.argv; // Detect if this script was directly invoked, or if the install-run-rushx script was invokved to select the // appropriate binary inside the rush package to run - const scriptName = path__WEBPACK_IMPORTED_MODULE_0__.basename(scriptPath); + const scriptName = node_path__WEBPACK_IMPORTED_MODULE_0__.basename(scriptPath); const bin = _getBin(scriptName); if (!nodePath || !scriptPath) { throw new Error('Unexpected exception: could not detect node path or script path'); diff --git a/common/scripts/install-run-rushx.js b/common/scripts/install-run-rushx.js index 6581521f..67d51a05 100644 --- a/common/scripts/install-run-rushx.js +++ b/common/scripts/install-run-rushx.js @@ -17,9 +17,9 @@ /******/ (() => { // webpackBootstrap /******/ "use strict"; var __webpack_exports__ = {}; -/*!*************************************************!*\ - !*** ./lib-esnext/scripts/install-run-rushx.js ***! - \*************************************************/ +/*!***********************************************************!*\ + !*** ./lib-intermediate-esm/scripts/install-run-rushx.js ***! + \***********************************************************/ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. diff --git a/common/scripts/install-run.js b/common/scripts/install-run.js index b3e92130..f5c278d7 100644 --- a/common/scripts/install-run.js +++ b/common/scripts/install-run.js @@ -16,21 +16,55 @@ /******/ "use strict"; /******/ var __webpack_modules__ = ({ -/***/ 832286: -/*!************************************************!*\ - !*** ./lib-esnext/utilities/npmrcUtilities.js ***! - \************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +/***/ 953844 +/*!**************************************************************!*\ + !*** ./lib-intermediate-esm/utilities/executionUtilities.js ***! + \**************************************************************/ +(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ IS_WINDOWS: () => (/* binding */ IS_WINDOWS), +/* harmony export */ escapeArgumentIfNeeded: () => (/* binding */ escapeArgumentIfNeeded) +/* harmony export */ }); +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. +const IS_WINDOWS = process.platform === 'win32'; +function escapeArgumentIfNeeded(command, isWindows = IS_WINDOWS) { + if (command.includes(' ')) { + if (isWindows) { + // Windows: use double quotes and escape internal double quotes + return `"${command.replace(/"/g, '""')}"`; + } + else { + // Unix: use JSON.stringify for proper escaping + return JSON.stringify(command); + } + } + else { + return command; + } +} +//# sourceMappingURL=executionUtilities.js.map + +/***/ }, + +/***/ 359480 +/*!**********************************************************!*\ + !*** ./lib-intermediate-esm/utilities/npmrcUtilities.js ***! + \**********************************************************/ +(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ isVariableSetInNpmrcFile: () => (/* binding */ isVariableSetInNpmrcFile), -/* harmony export */ syncNpmrc: () => (/* binding */ syncNpmrc) +/* harmony export */ syncNpmrc: () => (/* binding */ syncNpmrc), +/* harmony export */ trimNpmrcFileLines: () => (/* binding */ trimNpmrcFileLines) /* harmony export */ }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! fs */ 179896); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! path */ 16928); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! node:fs */ 973024); +/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(node_fs__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! node:path */ 176760); +/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(node_path__WEBPACK_IMPORTED_MODULE_1__); // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. // IMPORTANT - do not use any non-built-in libraries in this file @@ -46,7 +80,7 @@ __webpack_require__.r(__webpack_exports__); // create a global _combinedNpmrc for cache purpose const _combinedNpmrcMap = new Map(); function _trimNpmrcFile(options) { - const { sourceNpmrcPath, linesToPrepend, linesToAppend } = options; + const { sourceNpmrcPath, linesToPrepend, linesToAppend, supportEnvVarFallbackSyntax, filterNpmIncompatibleProperties, env = process.env } = options; const combinedNpmrcFromCache = _combinedNpmrcMap.get(sourceNpmrcPath); if (combinedNpmrcFromCache !== undefined) { return combinedNpmrcFromCache; @@ -55,13 +89,70 @@ function _trimNpmrcFile(options) { if (linesToPrepend) { npmrcFileLines.push(...linesToPrepend); } - if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) { - npmrcFileLines.push(...fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync(sourceNpmrcPath).toString().split('\n')); + if (node_fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) { + npmrcFileLines.push(...node_fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync(sourceNpmrcPath).toString().split('\n')); } if (linesToAppend) { npmrcFileLines.push(...linesToAppend); } npmrcFileLines = npmrcFileLines.map((line) => (line || '').trim()); + const resultLines = trimNpmrcFileLines(npmrcFileLines, env, supportEnvVarFallbackSyntax, filterNpmIncompatibleProperties); + const combinedNpmrc = resultLines.join('\n'); + //save the cache + _combinedNpmrcMap.set(sourceNpmrcPath, combinedNpmrc); + return combinedNpmrc; +} +/** + * List of npmrc properties that are not supported by npm but may be present in the config. + * These include pnpm-specific properties and deprecated npm properties. + */ +const NPM_INCOMPATIBLE_PROPERTIES = new Set([ + // pnpm-specific hoisting configuration + 'hoist', + 'hoist-pattern', + 'public-hoist-pattern', + 'shamefully-hoist', + // Deprecated or unknown npm properties that cause warnings + 'email', + 'publish-branch' +]); +/** + * List of registry-scoped npmrc property suffixes that are pnpm-specific. + * These are properties like "//registry.example.com/:tokenHelper" where "tokenHelper" + * is the suffix after the last colon. + */ +const NPM_INCOMPATIBLE_REGISTRY_SCOPED_PROPERTIES = new Set([ + // pnpm-specific token helper properties + 'tokenHelper', + 'urlTokenHelper' +]); +/** + * Regular expression to extract property names from .npmrc lines. + * Matches everything before '=', '[', or whitespace to capture the property name. + * Note: The 'g' flag is intentionally omitted since we only need the first match. + * Examples: + * "registry=https://..." -> matches "registry" + * "hoist-pattern[]=..." -> matches "hoist-pattern" + */ +const PROPERTY_NAME_REGEX = /^([^=\[\s]+)/; +/** + * Regular expression to extract environment variable names and optional fallback values. + * Matches patterns like: + * nameString -> group 1: nameString, group 2: undefined + * nameString-fallbackString -> group 1: nameString, group 2: fallbackString + * nameString:-fallbackString -> group 1: nameString, group 2: fallbackString + */ +const ENV_VAR_WITH_FALLBACK_REGEX = /^(?[^:-]+)(?::?-(?.+))?$/; +/** + * + * @param npmrcFileLines The npmrc file's lines + * @param env The environment variables object + * @param supportEnvVarFallbackSyntax Whether to support fallback values in the form of `${VAR_NAME:-fallback}` + * @param filterNpmIncompatibleProperties Whether to filter out properties that npm doesn't understand + * @returns An array of processed npmrc file lines with undefined environment variables and npm-incompatible properties commented out + */ +function trimNpmrcFileLines(npmrcFileLines, env, supportEnvVarFallbackSyntax, filterNpmIncompatibleProperties = false) { + var _a, _b, _c; const resultLines = []; // This finds environment variable tokens that look like "${VAR_NAME}" const expansionRegExp = /\$\{([^\}]+)\}/g; @@ -70,6 +161,7 @@ function _trimNpmrcFile(options) { // Trim out lines that reference environment variables that aren't defined for (let line of npmrcFileLines) { let lineShouldBeTrimmed = false; + let trimReason = ''; //remove spaces before or after key and value line = line .split('=') @@ -77,44 +169,102 @@ function _trimNpmrcFile(options) { .join('='); // Ignore comment lines if (!commentRegExp.test(line)) { - const environmentVariables = line.match(expansionRegExp); - if (environmentVariables) { - for (const token of environmentVariables) { - // Remove the leading "${" and the trailing "}" from the token - const environmentVariableName = token.substring(2, token.length - 1); - // Is the environment variable defined? - if (!process.env[environmentVariableName]) { - // No, so trim this line - lineShouldBeTrimmed = true; - break; + // Check if this is a property that npm doesn't understand + if (filterNpmIncompatibleProperties) { + // Extract the property name (everything before the '=' or '[') + const match = line.match(PROPERTY_NAME_REGEX); + if (match) { + const propertyName = match[1]; + // Check if this is a registry-scoped property (starts with "//" like "//registry.npmjs.org/:_authToken") + const isRegistryScoped = propertyName.startsWith('//'); + if (isRegistryScoped) { + // For registry-scoped properties, check if the suffix (after the last colon) is npm-incompatible + // Example: "//registry.example.com/:tokenHelper" -> suffix is "tokenHelper" + const lastColonIndex = propertyName.lastIndexOf(':'); + if (lastColonIndex !== -1) { + const registryPropertySuffix = propertyName.substring(lastColonIndex + 1); + if (NPM_INCOMPATIBLE_REGISTRY_SCOPED_PROPERTIES.has(registryPropertySuffix)) { + lineShouldBeTrimmed = true; + trimReason = 'NPM_INCOMPATIBLE_PROPERTY'; + } + } + } + else { + // For non-registry-scoped properties, check the full property name + if (NPM_INCOMPATIBLE_PROPERTIES.has(propertyName)) { + lineShouldBeTrimmed = true; + trimReason = 'NPM_INCOMPATIBLE_PROPERTY'; + } + } + } + } + // Check for undefined environment variables + if (!lineShouldBeTrimmed) { + const environmentVariables = line.match(expansionRegExp); + if (environmentVariables) { + for (const token of environmentVariables) { + /** + * Remove the leading "${" and the trailing "}" from the token + * + * ${nameString} -> nameString + * ${nameString-fallbackString} -> name-fallbackString + * ${nameString:-fallbackString} -> name:-fallbackString + */ + const nameWithFallback = token.slice(2, -1); + let environmentVariableName; + let fallback; + if (supportEnvVarFallbackSyntax) { + /** + * Get the environment variable name and fallback value. + * + * name fallback + * nameString -> nameString undefined + * nameString-fallbackString -> nameString fallbackString + * nameString:-fallbackString -> nameString fallbackString + */ + const matched = nameWithFallback.match(ENV_VAR_WITH_FALLBACK_REGEX); + environmentVariableName = (_b = (_a = matched === null || matched === void 0 ? void 0 : matched.groups) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : nameWithFallback; + fallback = (_c = matched === null || matched === void 0 ? void 0 : matched.groups) === null || _c === void 0 ? void 0 : _c.fallback; + } + else { + environmentVariableName = nameWithFallback; + } + // Is the environment variable and fallback value defined. + if (!env[environmentVariableName] && !fallback) { + // No, so trim this line + lineShouldBeTrimmed = true; + trimReason = 'MISSING_ENVIRONMENT_VARIABLE'; + break; + } } } } } if (lineShouldBeTrimmed) { - // Example output: - // "; MISSING ENVIRONMENT VARIABLE: //my-registry.com/npm/:_authToken=${MY_AUTH_TOKEN}" - resultLines.push('; MISSING ENVIRONMENT VARIABLE: ' + line); + // Comment out the line with appropriate reason + if (trimReason === 'NPM_INCOMPATIBLE_PROPERTY') { + // Example output: + // "; UNSUPPORTED BY NPM: email=test@example.com" + resultLines.push('; UNSUPPORTED BY NPM: ' + line); + } + else { + // Example output: + // "; MISSING ENVIRONMENT VARIABLE: //my-registry.com/npm/:_authToken=${MY_AUTH_TOKEN}" + resultLines.push('; MISSING ENVIRONMENT VARIABLE: ' + line); + } } else { resultLines.push(line); } } - const combinedNpmrc = resultLines.join('\n'); - //save the cache - _combinedNpmrcMap.set(sourceNpmrcPath, combinedNpmrc); - return combinedNpmrc; + return resultLines; } function _copyAndTrimNpmrcFile(options) { - const { logger, sourceNpmrcPath, targetNpmrcPath, linesToPrepend, linesToAppend } = options; + const { logger, sourceNpmrcPath, targetNpmrcPath } = options; logger.info(`Transforming ${sourceNpmrcPath}`); // Verbose logger.info(` --> "${targetNpmrcPath}"`); - const combinedNpmrc = _trimNpmrcFile({ - sourceNpmrcPath, - linesToPrepend, - linesToAppend - }); - fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(targetNpmrcPath, combinedNpmrc); + const combinedNpmrc = _trimNpmrcFile(options); + node_fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(targetNpmrcPath, combinedNpmrc); return combinedNpmrc; } function syncNpmrc(options) { @@ -123,86 +273,89 @@ function syncNpmrc(options) { info: console.log, // eslint-disable-next-line no-console error: console.error - }, createIfMissing = false, linesToAppend, linesToPrepend } = options; - const sourceNpmrcPath = path__WEBPACK_IMPORTED_MODULE_1__.join(sourceNpmrcFolder, !useNpmrcPublish ? '.npmrc' : '.npmrc-publish'); - const targetNpmrcPath = path__WEBPACK_IMPORTED_MODULE_1__.join(targetNpmrcFolder, '.npmrc'); + }, createIfMissing = false } = options; + const sourceNpmrcPath = node_path__WEBPACK_IMPORTED_MODULE_1__.join(sourceNpmrcFolder, !useNpmrcPublish ? '.npmrc' : '.npmrc-publish'); + const targetNpmrcPath = node_path__WEBPACK_IMPORTED_MODULE_1__.join(targetNpmrcFolder, '.npmrc'); try { - if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath) || createIfMissing) { + if (node_fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath) || createIfMissing) { // Ensure the target folder exists - if (!fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(targetNpmrcFolder)) { - fs__WEBPACK_IMPORTED_MODULE_0__.mkdirSync(targetNpmrcFolder, { recursive: true }); + if (!node_fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(targetNpmrcFolder)) { + node_fs__WEBPACK_IMPORTED_MODULE_0__.mkdirSync(targetNpmrcFolder, { recursive: true }); } return _copyAndTrimNpmrcFile({ sourceNpmrcPath, targetNpmrcPath, logger, - linesToAppend, - linesToPrepend + ...options }); } - else if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(targetNpmrcPath)) { + else if (node_fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(targetNpmrcPath)) { // If the source .npmrc doesn't exist and there is one in the target, delete the one in the target logger.info(`Deleting ${targetNpmrcPath}`); // Verbose - fs__WEBPACK_IMPORTED_MODULE_0__.unlinkSync(targetNpmrcPath); + node_fs__WEBPACK_IMPORTED_MODULE_0__.unlinkSync(targetNpmrcPath); } } catch (e) { throw new Error(`Error syncing .npmrc file: ${e}`); } } -function isVariableSetInNpmrcFile(sourceNpmrcFolder, variableKey) { +function isVariableSetInNpmrcFile(sourceNpmrcFolder, variableKey, supportEnvVarFallbackSyntax) { const sourceNpmrcPath = `${sourceNpmrcFolder}/.npmrc`; //if .npmrc file does not exist, return false directly - if (!fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) { + if (!node_fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) { return false; } - const trimmedNpmrcFile = _trimNpmrcFile({ sourceNpmrcPath }); + const trimmedNpmrcFile = _trimNpmrcFile({ + sourceNpmrcPath, + supportEnvVarFallbackSyntax, + filterNpmIncompatibleProperties: false + }); const variableKeyRegExp = new RegExp(`^${variableKey}=`, 'm'); return trimmedNpmrcFile.match(variableKeyRegExp) !== null; } //# sourceMappingURL=npmrcUtilities.js.map -/***/ }), +/***/ }, -/***/ 535317: -/*!********************************!*\ - !*** external "child_process" ***! - \********************************/ -/***/ ((module) => { +/***/ 731421 +/*!*************************************!*\ + !*** external "node:child_process" ***! + \*************************************/ +(module) { -module.exports = require("child_process"); +module.exports = require("node:child_process"); -/***/ }), +/***/ }, -/***/ 179896: -/*!*********************!*\ - !*** external "fs" ***! - \*********************/ -/***/ ((module) => { +/***/ 973024 +/*!**************************!*\ + !*** external "node:fs" ***! + \**************************/ +(module) { -module.exports = require("fs"); +module.exports = require("node:fs"); -/***/ }), +/***/ }, -/***/ 370857: -/*!*********************!*\ - !*** external "os" ***! - \*********************/ -/***/ ((module) => { +/***/ 848161 +/*!**************************!*\ + !*** external "node:os" ***! + \**************************/ +(module) { -module.exports = require("os"); +module.exports = require("node:os"); -/***/ }), +/***/ }, -/***/ 16928: -/*!***********************!*\ - !*** external "path" ***! - \***********************/ -/***/ ((module) => { +/***/ 176760 +/*!****************************!*\ + !*** external "node:path" ***! + \****************************/ +(module) { -module.exports = require("path"); +module.exports = require("node:path"); -/***/ }) +/***/ } /******/ }); /************************************************************************/ @@ -216,6 +369,12 @@ module.exports = require("path"); /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } +/******/ // Check if module exists (development only) +/******/ if (__webpack_modules__[moduleId] === undefined) { +/******/ var e = new Error("Cannot find module '" + moduleId + "'"); +/******/ e.code = 'MODULE_NOT_FOUND'; +/******/ throw e; +/******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed @@ -273,11 +432,11 @@ module.exports = require("path"); /******/ /************************************************************************/ var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk. (() => { -/*!*******************************************!*\ - !*** ./lib-esnext/scripts/install-run.js ***! - \*******************************************/ +/*!*****************************************************!*\ + !*** ./lib-intermediate-esm/scripts/install-run.js ***! + \*****************************************************/ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ RUSH_JSON_FILENAME: () => (/* binding */ RUSH_JSON_FILENAME), @@ -286,15 +445,16 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ installAndRun: () => (/* binding */ installAndRun), /* harmony export */ runWithErrorAndStatusCode: () => (/* binding */ runWithErrorAndStatusCode) /* harmony export */ }); -/* harmony import */ var child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! child_process */ 535317); -/* harmony import */ var child_process__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(child_process__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ 179896); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! os */ 370857); -/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(os__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! path */ 16928); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utilities/npmrcUtilities */ 832286); +/* harmony import */ var node_child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! node:child_process */ 731421); +/* harmony import */ var node_child_process__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(node_child_process__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! node:fs */ 973024); +/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(node_fs__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var node_os__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! node:os */ 848161); +/* harmony import */ var node_os__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(node_os__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! node:path */ 176760); +/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(node_path__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utilities/npmrcUtilities */ 359480); +/* harmony import */ var _utilities_executionUtilities__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utilities/executionUtilities */ 953844); // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. /* eslint-disable no-console */ @@ -303,6 +463,7 @@ __webpack_require__.r(__webpack_exports__); + const RUSH_JSON_FILENAME = 'rush.json'; const RUSH_TEMP_FOLDER_ENV_VARIABLE_NAME = 'RUSH_TEMP_FOLDER'; const INSTALL_RUN_LOCKFILE_PATH_VARIABLE = 'INSTALL_RUN_LOCKFILE_PATH'; @@ -341,34 +502,34 @@ let _npmPath = undefined; function getNpmPath() { if (!_npmPath) { try { - if (_isWindows()) { + if (_utilities_executionUtilities__WEBPACK_IMPORTED_MODULE_5__.IS_WINDOWS) { // We're on Windows - const whereOutput = child_process__WEBPACK_IMPORTED_MODULE_0__.execSync('where npm', { stdio: [] }).toString(); - const lines = whereOutput.split(os__WEBPACK_IMPORTED_MODULE_2__.EOL).filter((line) => !!line); + const whereOutput = node_child_process__WEBPACK_IMPORTED_MODULE_0__.execSync('where npm', { stdio: [] }).toString(); + const lines = whereOutput.split(node_os__WEBPACK_IMPORTED_MODULE_2__.EOL).filter((line) => !!line); // take the last result, we are looking for a .cmd command // see https://github.com/microsoft/rushstack/issues/759 _npmPath = lines[lines.length - 1]; } else { // We aren't on Windows - assume we're on *NIX or Darwin - _npmPath = child_process__WEBPACK_IMPORTED_MODULE_0__.execSync('command -v npm', { stdio: [] }).toString(); + _npmPath = node_child_process__WEBPACK_IMPORTED_MODULE_0__.execSync('command -v npm', { stdio: [] }).toString(); } } catch (e) { throw new Error(`Unable to determine the path to the NPM tool: ${e}`); } _npmPath = _npmPath.trim(); - if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(_npmPath)) { + if (!node_fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(_npmPath)) { throw new Error('The NPM executable does not exist'); } } return _npmPath; } function _ensureFolder(folderPath) { - if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(folderPath)) { - const parentDir = path__WEBPACK_IMPORTED_MODULE_3__.dirname(folderPath); + if (!node_fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(folderPath)) { + const parentDir = node_path__WEBPACK_IMPORTED_MODULE_3__.dirname(folderPath); _ensureFolder(parentDir); - fs__WEBPACK_IMPORTED_MODULE_1__.mkdirSync(folderPath); + node_fs__WEBPACK_IMPORTED_MODULE_1__.mkdirSync(folderPath); } } /** @@ -382,14 +543,14 @@ function _ensureAndJoinPath(baseFolder, ...pathSegments) { try { for (let pathSegment of pathSegments) { pathSegment = pathSegment.replace(/[\\\/]/g, '+'); - joinedPath = path__WEBPACK_IMPORTED_MODULE_3__.join(joinedPath, pathSegment); - if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(joinedPath)) { - fs__WEBPACK_IMPORTED_MODULE_1__.mkdirSync(joinedPath); + joinedPath = node_path__WEBPACK_IMPORTED_MODULE_3__.join(joinedPath, pathSegment); + if (!node_fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(joinedPath)) { + node_fs__WEBPACK_IMPORTED_MODULE_1__.mkdirSync(joinedPath); } } } catch (e) { - throw new Error(`Error building local installation folder (${path__WEBPACK_IMPORTED_MODULE_3__.join(baseFolder, ...pathSegments)}): ${e}`); + throw new Error(`Error building local installation folder (${node_path__WEBPACK_IMPORTED_MODULE_3__.join(baseFolder, ...pathSegments)}): ${e}`); } return joinedPath; } @@ -436,13 +597,16 @@ function _resolvePackageVersion(logger, rushCommonFolder, { name, version }) { // version resolves to try { const rushTempFolder = _getRushTempFolder(rushCommonFolder); - const sourceNpmrcFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushCommonFolder, 'config', 'rush'); + const sourceNpmrcFolder = node_path__WEBPACK_IMPORTED_MODULE_3__.join(rushCommonFolder, 'config', 'rush'); (0,_utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__.syncNpmrc)({ sourceNpmrcFolder, targetNpmrcFolder: rushTempFolder, - logger + logger, + supportEnvVarFallbackSyntax: false, + // Always filter npm-incompatible properties in install-run scripts. + // Any warnings will be shown when running Rush commands directly. + filterNpmIncompatibleProperties: true }); - const npmPath = getNpmPath(); // This returns something that looks like: // ``` // [ @@ -460,16 +624,11 @@ function _resolvePackageVersion(logger, rushCommonFolder, { name, version }) { // ``` // // if only a single version matches. - const spawnSyncOptions = { + const npmVersionSpawnResult = _runNpmConfirmSuccess(['view', `${name}@${version}`, 'version', '--no-update-notifier', '--json'], { cwd: rushTempFolder, stdio: [], - shell: _isWindows() - }; - const platformNpmPath = _getPlatformPath(npmPath); - const npmVersionSpawnResult = child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(platformNpmPath, ['view', `${name}@${version}`, 'version', '--no-update-notifier', '--json'], spawnSyncOptions); - if (npmVersionSpawnResult.status !== 0) { - throw new Error(`"npm view" returned error code ${npmVersionSpawnResult.status}`); - } + env: process.env + }, 'npm view'); const npmViewVersionOutput = npmVersionSpawnResult.stdout.toString(); const parsedVersionOutput = JSON.parse(npmViewVersionOutput); const versions = Array.isArray(parsedVersionOutput) @@ -501,15 +660,15 @@ function findRushJsonFolder() { let basePath = __dirname; let tempPath = __dirname; do { - const testRushJsonPath = path__WEBPACK_IMPORTED_MODULE_3__.join(basePath, RUSH_JSON_FILENAME); - if (fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(testRushJsonPath)) { + const testRushJsonPath = node_path__WEBPACK_IMPORTED_MODULE_3__.join(basePath, RUSH_JSON_FILENAME); + if (node_fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(testRushJsonPath)) { _rushJsonFolder = basePath; break; } else { basePath = tempPath; } - } while (basePath !== (tempPath = path__WEBPACK_IMPORTED_MODULE_3__.dirname(basePath))); // Exit the loop when we hit the disk root + } while (basePath !== (tempPath = node_path__WEBPACK_IMPORTED_MODULE_3__.dirname(basePath))); // Exit the loop when we hit the disk root if (!_rushJsonFolder) { throw new Error(`Unable to find ${RUSH_JSON_FILENAME}.`); } @@ -521,11 +680,11 @@ function findRushJsonFolder() { */ function _isPackageAlreadyInstalled(packageInstallFolder) { try { - const flagFilePath = path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, INSTALLED_FLAG_FILENAME); - if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(flagFilePath)) { + const flagFilePath = node_path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, INSTALLED_FLAG_FILENAME); + if (!node_fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(flagFilePath)) { return false; } - const fileContents = fs__WEBPACK_IMPORTED_MODULE_1__.readFileSync(flagFilePath).toString(); + const fileContents = node_fs__WEBPACK_IMPORTED_MODULE_1__.readFileSync(flagFilePath).toString(); return fileContents.trim() === process.version; } catch (e) { @@ -537,7 +696,7 @@ function _isPackageAlreadyInstalled(packageInstallFolder) { */ function _deleteFile(file) { try { - fs__WEBPACK_IMPORTED_MODULE_1__.unlinkSync(file); + node_fs__WEBPACK_IMPORTED_MODULE_1__.unlinkSync(file); } catch (err) { if (err.code !== 'ENOENT' && err.code !== 'ENOTDIR') { @@ -553,19 +712,19 @@ function _deleteFile(file) { */ function _cleanInstallFolder(rushTempFolder, packageInstallFolder, lockFilePath) { try { - const flagFile = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, INSTALLED_FLAG_FILENAME); + const flagFile = node_path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, INSTALLED_FLAG_FILENAME); _deleteFile(flagFile); - const packageLockFile = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, 'package-lock.json'); + const packageLockFile = node_path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, 'package-lock.json'); if (lockFilePath) { - fs__WEBPACK_IMPORTED_MODULE_1__.copyFileSync(lockFilePath, packageLockFile); + node_fs__WEBPACK_IMPORTED_MODULE_1__.copyFileSync(lockFilePath, packageLockFile); } else { // Not running `npm ci`, so need to cleanup _deleteFile(packageLockFile); - const nodeModulesFolder = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME); - if (fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(nodeModulesFolder)) { + const nodeModulesFolder = node_path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME); + if (node_fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(nodeModulesFolder)) { const rushRecyclerFolder = _ensureAndJoinPath(rushTempFolder, 'rush-recycler'); - fs__WEBPACK_IMPORTED_MODULE_1__.renameSync(nodeModulesFolder, path__WEBPACK_IMPORTED_MODULE_3__.join(rushRecyclerFolder, `install-run-${Date.now().toString()}`)); + node_fs__WEBPACK_IMPORTED_MODULE_1__.renameSync(nodeModulesFolder, node_path__WEBPACK_IMPORTED_MODULE_3__.join(rushRecyclerFolder, `install-run-${Date.now().toString()}`)); } } } @@ -585,8 +744,8 @@ function _createPackageJson(packageInstallFolder, name, version) { repository: "DON'T WARN", license: 'MIT' }; - const packageJsonPath = path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, PACKAGE_JSON_FILENAME); - fs__WEBPACK_IMPORTED_MODULE_1__.writeFileSync(packageJsonPath, JSON.stringify(packageJsonContents, undefined, 2)); + const packageJsonPath = node_path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, PACKAGE_JSON_FILENAME); + node_fs__WEBPACK_IMPORTED_MODULE_1__.writeFileSync(packageJsonPath, JSON.stringify(packageJsonContents, undefined, 2)); } catch (e) { throw new Error(`Unable to create package.json: ${e}`); @@ -595,20 +754,14 @@ function _createPackageJson(packageInstallFolder, name, version) { /** * Run "npm install" in the package install folder. */ -function _installPackage(logger, packageInstallFolder, name, version, command) { +function _installPackage(logger, packageInstallFolder, name, version, npmCommand) { try { logger.info(`Installing ${name}...`); - const npmPath = getNpmPath(); - const platformNpmPath = _getPlatformPath(npmPath); - const result = child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(platformNpmPath, [command], { + _runNpmConfirmSuccess([npmCommand], { stdio: 'inherit', cwd: packageInstallFolder, - env: process.env, - shell: _isWindows() - }); - if (result.status !== 0) { - throw new Error(`"npm ${command}" encountered an error`); - } + env: process.env + }, `npm ${npmCommand}`); logger.info(`Successfully installed ${name}@${version}`); } catch (e) { @@ -619,71 +772,113 @@ function _installPackage(logger, packageInstallFolder, name, version, command) { * Get the ".bin" path for the package. */ function _getBinPath(packageInstallFolder, binName) { - const binFolderPath = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin'); - const resolvedBinName = _isWindows() ? `${binName}.cmd` : binName; - return path__WEBPACK_IMPORTED_MODULE_3__.resolve(binFolderPath, resolvedBinName); -} -/** - * Returns a cross-platform path - windows must enclose any path containing spaces within double quotes. - */ -function _getPlatformPath(platformPath) { - return _isWindows() && platformPath.includes(' ') ? `"${platformPath}"` : platformPath; + const binFolderPath = node_path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin'); + const resolvedBinName = _utilities_executionUtilities__WEBPACK_IMPORTED_MODULE_5__.IS_WINDOWS ? `${binName}.cmd` : binName; + return node_path__WEBPACK_IMPORTED_MODULE_3__.resolve(binFolderPath, resolvedBinName); } -function _isWindows() { - return os__WEBPACK_IMPORTED_MODULE_2__.platform() === 'win32'; +function _buildShellCommand(command, args) { + const escapedCommand = (0,_utilities_executionUtilities__WEBPACK_IMPORTED_MODULE_5__.escapeArgumentIfNeeded)(command); + const escapedArgs = args.map((arg) => (0,_utilities_executionUtilities__WEBPACK_IMPORTED_MODULE_5__.escapeArgumentIfNeeded)(arg)); + return [escapedCommand, ...escapedArgs].join(' '); } /** * Write a flag file to the package's install directory, signifying that the install was successful. */ function _writeFlagFile(packageInstallFolder) { try { - const flagFilePath = path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, INSTALLED_FLAG_FILENAME); - fs__WEBPACK_IMPORTED_MODULE_1__.writeFileSync(flagFilePath, process.version); + const flagFilePath = node_path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, INSTALLED_FLAG_FILENAME); + node_fs__WEBPACK_IMPORTED_MODULE_1__.writeFileSync(flagFilePath, process.version); } catch (e) { throw new Error(`Unable to create installed.flag file in ${packageInstallFolder}`); } } +/** + * Run npm under the platform's shell and throw if it didn't succeed. + */ +function _runNpmConfirmSuccess(args, options, commandNameForLogging) { + const command = getNpmPath(); + let result; + if (_utilities_executionUtilities__WEBPACK_IMPORTED_MODULE_5__.IS_WINDOWS) { + result = node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(_buildShellCommand(command, args), { + ...options, + shell: true, + windowsVerbatimArguments: false + }); + } + else { + result = node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(command, args, options); + } + if (result.status !== 0) { + if (!result.status) { + // Is status null or undefined? + if (result.error) { + throw new Error(`"${commandNameForLogging}" failed: ${result.error.message.toString()}`); + } + else if (result.signal) { + throw new Error(`"${commandNameForLogging}" was terminated by signal: ${result.signal}`); + } + else { + throw new Error(`"${commandNameForLogging}" failed for an unknown reason`); + } + } + else { + throw new Error(`"${commandNameForLogging}" returned error code ${result.status}`); + } + } + return result; +} function installAndRun(logger, packageName, packageVersion, packageBinName, packageBinArgs, lockFilePath = process.env[INSTALL_RUN_LOCKFILE_PATH_VARIABLE]) { const rushJsonFolder = findRushJsonFolder(); - const rushCommonFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushJsonFolder, 'common'); + const rushCommonFolder = node_path__WEBPACK_IMPORTED_MODULE_3__.join(rushJsonFolder, 'common'); const rushTempFolder = _getRushTempFolder(rushCommonFolder); const packageInstallFolder = _ensureAndJoinPath(rushTempFolder, 'install-run', `${packageName}@${packageVersion}`); if (!_isPackageAlreadyInstalled(packageInstallFolder)) { // The package isn't already installed _cleanInstallFolder(rushTempFolder, packageInstallFolder, lockFilePath); - const sourceNpmrcFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushCommonFolder, 'config', 'rush'); + const sourceNpmrcFolder = node_path__WEBPACK_IMPORTED_MODULE_3__.join(rushCommonFolder, 'config', 'rush'); (0,_utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__.syncNpmrc)({ sourceNpmrcFolder, targetNpmrcFolder: packageInstallFolder, - logger + logger, + supportEnvVarFallbackSyntax: false, + // Always filter npm-incompatible properties in install-run scripts. + // Any warnings will be shown when running Rush commands directly. + filterNpmIncompatibleProperties: true }); _createPackageJson(packageInstallFolder, packageName, packageVersion); - const command = lockFilePath ? 'ci' : 'install'; - _installPackage(logger, packageInstallFolder, packageName, packageVersion, command); + const installCommand = lockFilePath ? 'ci' : 'install'; + _installPackage(logger, packageInstallFolder, packageName, packageVersion, installCommand); _writeFlagFile(packageInstallFolder); } const statusMessage = `Invoking "${packageBinName} ${packageBinArgs.join(' ')}"`; const statusMessageLine = new Array(statusMessage.length + 1).join('-'); logger.info('\n' + statusMessage + '\n' + statusMessageLine + '\n'); const binPath = _getBinPath(packageInstallFolder, packageBinName); - const binFolderPath = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin'); + const binFolderPath = node_path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin'); // Windows environment variables are case-insensitive. Instead of using SpawnSyncOptions.env, we need to // assign via the process.env proxy to ensure that we append to the right PATH key. const originalEnvPath = process.env.PATH || ''; let result; try { - // `npm` bin stubs on Windows are `.cmd` files - // Node.js will not directly invoke a `.cmd` file unless `shell` is set to `true` - const platformBinPath = _getPlatformPath(binPath); - process.env.PATH = [binFolderPath, originalEnvPath].join(path__WEBPACK_IMPORTED_MODULE_3__.delimiter); - result = child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(platformBinPath, packageBinArgs, { + process.env.PATH = [binFolderPath, originalEnvPath].join(node_path__WEBPACK_IMPORTED_MODULE_3__.delimiter); + const spawnOptions = { stdio: 'inherit', - windowsVerbatimArguments: false, - shell: _isWindows(), cwd: process.cwd(), env: process.env - }); + }; + if (_utilities_executionUtilities__WEBPACK_IMPORTED_MODULE_5__.IS_WINDOWS) { + result = node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(_buildShellCommand(binPath, packageBinArgs), { + ...spawnOptions, + windowsVerbatimArguments: false, + // `npm` bin stubs on Windows are `.cmd` files + // Node.js will not directly invoke a `.cmd` file unless `shell` is set to `true` + shell: true + }); + } + else { + result = node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(binPath, packageBinArgs, spawnOptions); + } } finally { process.env.PATH = originalEnvPath; @@ -708,9 +903,10 @@ function runWithErrorAndStatusCode(logger, fn) { function _run() { const [nodePath /* Ex: /bin/node */, scriptPath /* /repo/common/scripts/install-run-rush.js */, rawPackageSpecifier /* qrcode@^1.2.0 */, packageBinName /* qrcode */, ...packageBinArgs /* [-f, myproject/lib] */] = process.argv; if (!nodePath) { - throw new Error('Unexpected exception: could not detect node path'); + throw new Error('Could not detect node path'); } - if (path__WEBPACK_IMPORTED_MODULE_3__.basename(scriptPath).toLowerCase() !== 'install-run.js') { + const scriptFileName = node_path__WEBPACK_IMPORTED_MODULE_3__.basename(scriptPath).toLowerCase(); + if (scriptFileName !== 'install-run.js' && scriptFileName !== 'install-run') { // If install-run.js wasn't directly invoked, don't execute the rest of this function. Return control // to the script that (presumably) imported this file return; diff --git a/packages/cfdi/cancelacion/package.json b/packages/cfdi/cancelacion/package.json new file mode 100644 index 00000000..f03b6832 --- /dev/null +++ b/packages/cfdi/cancelacion/package.json @@ -0,0 +1,36 @@ +{ + "name": "@cfdi/cancelacion", + "version": "0.0.1", + "license": "MIT", + "main": "src/index.ts", + "module": "src/index.ts", + "types": "src/index.ts", + "source": "src/index.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "dependencies": {}, + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/cfdi/cancelacion/src/index.ts b/packages/cfdi/cancelacion/src/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/cfdi/cancelacion/src/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/cfdi/cancelacion/tsconfig.json b/packages/cfdi/cancelacion/tsconfig.json new file mode 100644 index 00000000..0aff00ce --- /dev/null +++ b/packages/cfdi/cancelacion/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "types": [ + "node" + ], + "outDir": "./dist", + "declaration": true, + "sourceMap": true, + "noUnusedLocals": false, + "resolveJsonModule": true, + "noUnusedParameters": false + } +} diff --git a/packages/cfdi/cancelacion/vitest.config.mts b/packages/cfdi/cancelacion/vitest.config.mts new file mode 100644 index 00000000..9152d739 --- /dev/null +++ b/packages/cfdi/cancelacion/vitest.config.mts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; + +export default defineConfig({ + test: {}, + plugins: [tsconfigPaths()], +}); diff --git a/packages/cfdi/catalogos/README.md b/packages/cfdi/catalogos/README.md index 1a911c37..f5fc3949 100644 --- a/packages/cfdi/catalogos/README.md +++ b/packages/cfdi/catalogos/README.md @@ -1 +1,56 @@ -catalogos +# @cfdi/catalogos + +Catalogos oficiales del SAT para CFDI 4.0. Contiene enums, tipos y listas de valores para formas de pago, metodos de pago, regimenes fiscales, tipos de comprobante, usos de CFDI, impuestos y exportacion. + +## Instalacion + +```bash +npm install @cfdi/catalogos +``` + +## Uso + +```typescript +import { + FormaPago, + MetodoPago, + RegimenFiscal, + TipoComprobante, + UsoCFDI, + Impuesto, + ExportacionEnum, + FormaPagoList, +} from '@cfdi/catalogos'; + +// Usar enums directamente +const pago = FormaPago.TRANSFERENCIA_ELECTRONICA; // '03' +const metodo = MetodoPago.PUE; // Pago en Una sola Exhibicion +const regimen = RegimenFiscal.GENERAL_DE_LEY; // Regimen general +const tipo = TipoComprobante.INGRESO; +const uso = UsoCFDI.GASTOS_EN_GENERAL; +const impuesto = Impuesto.IVA; +const exportacion = ExportacionEnum.NoAplica; // '01' + +// Listas para selects/dropdowns +console.log(FormaPagoList); +// [{ label: 'Efectivo', value: '01' }, { label: 'Cheque nominativo', value: '02' }, ...] +``` + +## API + +| Export | Tipo | Descripcion | +|--------|------|-------------| +| `FormaPago` | enum | Claves de forma de pago (01-99) | +| `FormaPagoList` | array | Lista con label/value para UI | +| `FormaPagoType` | type | Tipo union de claves validas | +| `MetodoPago` | enum | PUE, PPD | +| `RegimenFiscal` | enum | Regimenes fiscales del SAT | +| `TipoComprobante` | enum | Ingreso, Egreso, Traslado, Nomina, Pago | +| `UsoCFDI` | enum | Usos del CFDI | +| `Impuesto` | enum | IVA, ISR, IEPS | +| `ExportacionEnum` | enum | NoAplica, Definitiva, Temporal | +| `ExportacionType` | type | Tipo union de claves de exportacion | + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/catalogos/package.json b/packages/cfdi/catalogos/package.json index df63e4c7..eeb4085c 100644 --- a/packages/cfdi/catalogos/package.json +++ b/packages/cfdi/catalogos/package.json @@ -2,9 +2,9 @@ "name": "@cfdi/catalogos", "version": "4.0.15", "license": "MIT", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "module": "dist/utils.esm.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "release": { "branches": [ @@ -21,64 +21,22 @@ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build", + "build": "vite build --config node_modules/@recreando/vite/vite.config.lib.mts", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "author": "MisaelMa", - "size-limit": [ - { - "path": "dist/utils.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/utils.esm.js", - "limit": "10 KB" - } - ], "devDependencies": { "@recreando/vite": "workspace:*", "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", + "@types/node": "^22", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/cleaner/dist/CfdiCleaner.d.ts b/packages/cfdi/cleaner/dist/CfdiCleaner.d.ts new file mode 100644 index 00000000..addb0152 --- /dev/null +++ b/packages/cfdi/cleaner/dist/CfdiCleaner.d.ts @@ -0,0 +1,5 @@ +export declare class CfdiCleaner { + clean(xml: string): string; + cleanFile(filePath: string): string; +} +//# sourceMappingURL=CfdiCleaner.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/CfdiCleaner.d.ts.map b/packages/cfdi/cleaner/dist/CfdiCleaner.d.ts.map new file mode 100644 index 00000000..90ef71a7 --- /dev/null +++ b/packages/cfdi/cleaner/dist/CfdiCleaner.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"CfdiCleaner.d.ts","sourceRoot":"","sources":["../src/CfdiCleaner.ts"],"names":[],"mappings":"AAwBA,qBAAa,WAAW;IAOtB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAiB1B,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAIpC"} \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/collapseWhitespace.d.ts b/packages/cfdi/cleaner/dist/cleaners/collapseWhitespace.d.ts new file mode 100644 index 00000000..a56860a3 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/collapseWhitespace.d.ts @@ -0,0 +1,2 @@ +export declare function collapseWhitespace(xml: string): string; +//# sourceMappingURL=collapseWhitespace.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/collapseWhitespace.d.ts.map b/packages/cfdi/cleaner/dist/cleaners/collapseWhitespace.d.ts.map new file mode 100644 index 00000000..ccf30cf1 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/collapseWhitespace.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"collapseWhitespace.d.ts","sourceRoot":"","sources":["../../src/cleaners/collapseWhitespace.ts"],"names":[],"mappings":"AAOA,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKtD"} \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/index.d.ts b/packages/cfdi/cleaner/dist/cleaners/index.d.ts new file mode 100644 index 00000000..060bab7b --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/index.d.ts @@ -0,0 +1,8 @@ +export { SAT_NAMESPACES } from './satNamespaces'; +export { removeAddenda } from './removeAddenda'; +export { removeNonSatNamespaces } from './removeNonSatNamespaces'; +export { removeNonSatSchemaLocations } from './removeNonSatSchemaLocations'; +export { removeNonSatNodes } from './removeNonSatNodes'; +export { removeStylesheetAttributes } from './removeStylesheetAttributes'; +export { collapseWhitespace } from './collapseWhitespace'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/index.d.ts.map b/packages/cfdi/cleaner/dist/cleaners/index.d.ts.map new file mode 100644 index 00000000..0730ca58 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cleaners/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"} \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/removeAddenda.d.ts b/packages/cfdi/cleaner/dist/cleaners/removeAddenda.d.ts new file mode 100644 index 00000000..dc885f36 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/removeAddenda.d.ts @@ -0,0 +1,2 @@ +export declare function removeAddenda(xml: string): string; +//# sourceMappingURL=removeAddenda.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/removeAddenda.d.ts.map b/packages/cfdi/cleaner/dist/cleaners/removeAddenda.d.ts.map new file mode 100644 index 00000000..90672667 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/removeAddenda.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"removeAddenda.d.ts","sourceRoot":"","sources":["../../src/cleaners/removeAddenda.ts"],"names":[],"mappings":"AAOA,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKjD"} \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/removeNonSatNamespaces.d.ts b/packages/cfdi/cleaner/dist/cleaners/removeNonSatNamespaces.d.ts new file mode 100644 index 00000000..2a169539 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/removeNonSatNamespaces.d.ts @@ -0,0 +1,2 @@ +export declare function removeNonSatNamespaces(xml: string): string; +//# sourceMappingURL=removeNonSatNamespaces.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/removeNonSatNamespaces.d.ts.map b/packages/cfdi/cleaner/dist/cleaners/removeNonSatNamespaces.d.ts.map new file mode 100644 index 00000000..c67ad130 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/removeNonSatNamespaces.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"removeNonSatNamespaces.d.ts","sourceRoot":"","sources":["../../src/cleaners/removeNonSatNamespaces.ts"],"names":[],"mappings":"AASA,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAe1D"} \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/removeNonSatNodes.d.ts b/packages/cfdi/cleaner/dist/cleaners/removeNonSatNodes.d.ts new file mode 100644 index 00000000..a4e167d5 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/removeNonSatNodes.d.ts @@ -0,0 +1,2 @@ +export declare function removeNonSatNodes(xml: string): string; +//# sourceMappingURL=removeNonSatNodes.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/removeNonSatNodes.d.ts.map b/packages/cfdi/cleaner/dist/cleaners/removeNonSatNodes.d.ts.map new file mode 100644 index 00000000..df52ffe9 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/removeNonSatNodes.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"removeNonSatNodes.d.ts","sourceRoot":"","sources":["../../src/cleaners/removeNonSatNodes.ts"],"names":[],"mappings":"AAUA,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA6BrD"} \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/removeNonSatSchemaLocations.d.ts b/packages/cfdi/cleaner/dist/cleaners/removeNonSatSchemaLocations.d.ts new file mode 100644 index 00000000..3c7ffe12 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/removeNonSatSchemaLocations.d.ts @@ -0,0 +1,2 @@ +export declare function removeNonSatSchemaLocations(xml: string): string; +//# sourceMappingURL=removeNonSatSchemaLocations.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/removeNonSatSchemaLocations.d.ts.map b/packages/cfdi/cleaner/dist/cleaners/removeNonSatSchemaLocations.d.ts.map new file mode 100644 index 00000000..c50514d6 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/removeNonSatSchemaLocations.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"removeNonSatSchemaLocations.d.ts","sourceRoot":"","sources":["../../src/cleaners/removeNonSatSchemaLocations.ts"],"names":[],"mappings":"AASA,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAoB/D"} \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/removeStylesheetAttributes.d.ts b/packages/cfdi/cleaner/dist/cleaners/removeStylesheetAttributes.d.ts new file mode 100644 index 00000000..668b747e --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/removeStylesheetAttributes.d.ts @@ -0,0 +1,2 @@ +export declare function removeStylesheetAttributes(xml: string): string; +//# sourceMappingURL=removeStylesheetAttributes.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/removeStylesheetAttributes.d.ts.map b/packages/cfdi/cleaner/dist/cleaners/removeStylesheetAttributes.d.ts.map new file mode 100644 index 00000000..00cc5993 --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/removeStylesheetAttributes.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"removeStylesheetAttributes.d.ts","sourceRoot":"","sources":["../../src/cleaners/removeStylesheetAttributes.ts"],"names":[],"mappings":"AAMA,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9D"} \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/satNamespaces.d.ts b/packages/cfdi/cleaner/dist/cleaners/satNamespaces.d.ts new file mode 100644 index 00000000..a6d556fa --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/satNamespaces.d.ts @@ -0,0 +1,2 @@ +export declare const SAT_NAMESPACES: ReadonlySet; +//# sourceMappingURL=satNamespaces.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/cleaners/satNamespaces.d.ts.map b/packages/cfdi/cleaner/dist/cleaners/satNamespaces.d.ts.map new file mode 100644 index 00000000..3b9de14e --- /dev/null +++ b/packages/cfdi/cleaner/dist/cleaners/satNamespaces.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"satNamespaces.d.ts","sourceRoot":"","sources":["../../src/cleaners/satNamespaces.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAsC7C,CAAC"} \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/index.d.ts b/packages/cfdi/cleaner/dist/index.d.ts new file mode 100644 index 00000000..71d9e6e4 --- /dev/null +++ b/packages/cfdi/cleaner/dist/index.d.ts @@ -0,0 +1,3 @@ +export { CfdiCleaner } from './CfdiCleaner'; +export * from './cleaners'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/index.d.ts.map b/packages/cfdi/cleaner/dist/index.d.ts.map new file mode 100644 index 00000000..aa21257c --- /dev/null +++ b/packages/cfdi/cleaner/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,cAAc,YAAY,CAAC"} \ No newline at end of file diff --git a/packages/cfdi/cleaner/dist/index.mjs b/packages/cfdi/cleaner/dist/index.mjs new file mode 100644 index 00000000..8613f375 --- /dev/null +++ b/packages/cfdi/cleaner/dist/index.mjs @@ -0,0 +1,126 @@ +import l from "node:fs"; +const i = /* @__PURE__ */ new Set([ + "http://www.sat.gob.mx/cfd/3", + "http://www.sat.gob.mx/cfd/4", + "http://www.sat.gob.mx/TimbreFiscalDigital", + "http://www.sat.gob.mx/implocal", + "http://www.sat.gob.mx/Pagos", + "http://www.sat.gob.mx/Pagos20", + "http://www.sat.gob.mx/nomina12", + "http://www.sat.gob.mx/nomina", + "http://www.sat.gob.mx/ComercioExterior11", + "http://www.sat.gob.mx/ComercioExterior20", + "http://www.sat.gob.mx/CartaPorte20", + "http://www.sat.gob.mx/CartaPorte30", + "http://www.sat.gob.mx/CartaPorte31", + "http://www.sat.gob.mx/iedu", + "http://www.sat.gob.mx/donat", + "http://www.sat.gob.mx/divisas", + "http://www.sat.gob.mx/leyendasFiscales", + "http://www.sat.gob.mx/pfic", + "http://www.sat.gob.mx/TuristaPasajeroExtranjero", + "http://www.sat.gob.mx/registrofiscal", + "http://www.sat.gob.mx/pagoenespecie", + "http://www.sat.gob.mx/aerolineas", + "http://www.sat.gob.mx/valesdedespensa", + "http://www.sat.gob.mx/notariospublicos", + "http://www.sat.gob.mx/vehiculousado", + "http://www.sat.gob.mx/servicioparcialconstruccion", + "http://www.sat.gob.mx/renovacionysustitucionvehiculos", + "http://www.sat.gob.mx/certificadodestruccion", + "http://www.sat.gob.mx/arteantiguedades", + "http://www.sat.gob.mx/ine", + "http://www.sat.gob.mx/ventavehiculos", + "http://www.sat.gob.mx/detallista", + "http://www.sat.gob.mx/EstadoDeCuentaCombustible12", + "http://www.sat.gob.mx/ConsumoDeCombustibles11", + "http://www.sat.gob.mx/GastosHidrocarburos10", + "http://www.sat.gob.mx/IngresosHidrocarburos10", + "http://www.w3.org/2001/XMLSchema-instance" +]); +function g(e) { + return e.replace(//gi, ""); +} +function x(e) { + return e.replace( + /()/, + (a, t, o, r) => { + const s = o.replace( + /\s+xmlns:[a-zA-Z0-9_-]+="([^"]*)"/g, + (w, n) => i.has(n) ? w : "" + ); + return `${t}${s}${r}`; + } + ); +} +function b(e) { + return e.replace( + /xsi:schemaLocation="([^"]*)"/g, + (a, t) => { + const o = t.trim().split(/\s+/), r = []; + for (let s = 0; s < o.length - 1; s += 2) { + const w = o[s], n = o[s + 1]; + i.has(w) && r.push(w, n); + } + return `xsi:schemaLocation="${r.join(" ")}"`; + } + ); +} +function u(e) { + const a = {}, t = /xmlns:([a-zA-Z0-9_-]+)="([^"]*)"/g; + let o; + for (; (o = t.exec(e)) !== null; ) + a[o[1]] = o[2]; + return e.replace( + /(]*>)([\s\S]*?)(<\/cfdi:Complemento>)/g, + (r, s, w, n) => { + const m = w.replace( + /<([a-zA-Z0-9_-]+):([a-zA-Z0-9_-]+)([\s\S]*?)(?:<\/\1:\2>|\/>)/g, + (p, h) => { + const c = a[h]; + return !c || !i.has(c) ? "" : p; + } + ); + return `${s}${m}${n}`; + } + ); +} +function d(e) { + return e.replace(/<\?xml-stylesheet[^?]*\?>/gi, ""); +} +function f(e) { + return e.replace(/>[ \t\r\n]+ +<`).trim(); +} +class S { + /** + * Limpia un XML de CFDI en memoria. + * + * @param xml - Contenido XML del CFDI como string UTF-8 + * @returns XML limpio con solo contenido oficial del SAT + */ + clean(a) { + let t = a; + return t = d(t), t = g(t), t = u(t), t = x(t), t = b(t), t = f(t), t; + } + /** + * Limpia un CFDI leyendo el archivo desde disco. + * + * @param filePath - Ruta absoluta al archivo XML + * @returns XML limpio con solo contenido oficial del SAT + */ + cleanFile(a) { + const t = l.readFileSync(a, "utf-8"); + return this.clean(t); + } +} +export { + S as CfdiCleaner, + i as SAT_NAMESPACES, + f as collapseWhitespace, + g as removeAddenda, + x as removeNonSatNamespaces, + u as removeNonSatNodes, + b as removeNonSatSchemaLocations, + d as removeStylesheetAttributes +}; diff --git a/packages/cfdi/cleaner/package.json b/packages/cfdi/cleaner/package.json new file mode 100644 index 00000000..1d4fc534 --- /dev/null +++ b/packages/cfdi/cleaner/package.json @@ -0,0 +1,36 @@ +{ + "name": "@cfdi/cleaner", + "version": "0.0.1", + "license": "MIT", + "main": "./src/index.ts", + "module": "./src/index.ts", + "types": "./src/index.ts", + "source": "./src/index.ts", + "files": [ + "dist", + "src" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build --config node_modules/@recreando/vite/vite.config.lib.mts", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/cfdi/cleaner/src/CfdiCleaner.ts b/packages/cfdi/cleaner/src/CfdiCleaner.ts new file mode 100644 index 00000000..5241f0e0 --- /dev/null +++ b/packages/cfdi/cleaner/src/CfdiCleaner.ts @@ -0,0 +1,53 @@ +import fs from 'node:fs'; +import { + collapseWhitespace, + removeAddenda, + removeNonSatNamespaces, + removeNonSatNodes, + removeNonSatSchemaLocations, + removeStylesheetAttributes, +} from './cleaners'; + +/** + * Limpia XMLs de CFDI eliminando contenido no estandar del SAT. + * + * Las operaciones de limpieza se aplican en el siguiente orden: + * 1. Elimina processing instructions xml-stylesheet + * 2. Elimina addendas + * 3. Elimina nodos no-SAT dentro de cfdi:Complemento + * 4. Elimina declaraciones xmlns no-SAT del elemento raiz + * 5. Limpia pares no-SAT en xsi:schemaLocation + * 6. Normaliza whitespace entre tags + * + * El Sello, Certificado y UUID NO se modifican. + * Solo se elimina contenido, nunca se agrega. + */ +export class CfdiCleaner { + /** + * Limpia un XML de CFDI en memoria. + * + * @param xml - Contenido XML del CFDI como string UTF-8 + * @returns XML limpio con solo contenido oficial del SAT + */ + clean(xml: string): string { + let result = xml; + result = removeStylesheetAttributes(result); + result = removeAddenda(result); + result = removeNonSatNodes(result); + result = removeNonSatNamespaces(result); + result = removeNonSatSchemaLocations(result); + result = collapseWhitespace(result); + return result; + } + + /** + * Limpia un CFDI leyendo el archivo desde disco. + * + * @param filePath - Ruta absoluta al archivo XML + * @returns XML limpio con solo contenido oficial del SAT + */ + cleanFile(filePath: string): string { + const xml = fs.readFileSync(filePath, 'utf-8'); + return this.clean(xml); + } +} diff --git a/packages/cfdi/cleaner/src/cleaners/collapseWhitespace.ts b/packages/cfdi/cleaner/src/cleaners/collapseWhitespace.ts new file mode 100644 index 00000000..686eba88 --- /dev/null +++ b/packages/cfdi/cleaner/src/cleaners/collapseWhitespace.ts @@ -0,0 +1,13 @@ +/** + * Normaliza whitespace excesivo entre tags XML. + * + * Reemplaza multiples espacios/tabs/saltos de linea consecutivos entre + * el cierre de un tag y la apertura del siguiente por un espacio simple. + * Preserva el contenido de texto dentro de los nodos. + */ +export function collapseWhitespace(xml: string): string { + // Colapsa whitespace entre tags: > < -> >\n< + return xml + .replace(/>[ \t\r\n]+\n<') + .trim(); +} diff --git a/packages/cfdi/cleaner/src/cleaners/index.ts b/packages/cfdi/cleaner/src/cleaners/index.ts new file mode 100644 index 00000000..0406a748 --- /dev/null +++ b/packages/cfdi/cleaner/src/cleaners/index.ts @@ -0,0 +1,7 @@ +export { SAT_NAMESPACES } from './satNamespaces'; +export { removeAddenda } from './removeAddenda'; +export { removeNonSatNamespaces } from './removeNonSatNamespaces'; +export { removeNonSatSchemaLocations } from './removeNonSatSchemaLocations'; +export { removeNonSatNodes } from './removeNonSatNodes'; +export { removeStylesheetAttributes } from './removeStylesheetAttributes'; +export { collapseWhitespace } from './collapseWhitespace'; diff --git a/packages/cfdi/cleaner/src/cleaners/removeAddenda.ts b/packages/cfdi/cleaner/src/cleaners/removeAddenda.ts new file mode 100644 index 00000000..c3192b39 --- /dev/null +++ b/packages/cfdi/cleaner/src/cleaners/removeAddenda.ts @@ -0,0 +1,13 @@ +/** + * Elimina el nodo ... completo del XML. + * + * La Addenda es contenido no estándar permitido por el SAT solo para datos + * adicionales del emisor/receptor. No forma parte del CFDI oficial y no + * debe considerarse para la cadena original ni el sello. + */ +export function removeAddenda(xml: string): string { + // Elimina el bloque completo incluyendo atributos en el tag de apertura y + // cualquier contenido anidado, usando un patron que respeta nesting basico. + // El flag 's' (dotAll) permite que '.' coincida con saltos de linea. + return xml.replace(//gi, ''); +} diff --git a/packages/cfdi/cleaner/src/cleaners/removeNonSatNamespaces.ts b/packages/cfdi/cleaner/src/cleaners/removeNonSatNamespaces.ts new file mode 100644 index 00000000..9b9c212e --- /dev/null +++ b/packages/cfdi/cleaner/src/cleaners/removeNonSatNamespaces.ts @@ -0,0 +1,25 @@ +import { SAT_NAMESPACES } from './satNamespaces'; + +/** + * Elimina declaraciones xmlns:prefix="uri" del elemento raiz donde el URI + * no esta en la lista de namespaces oficiales del SAT. + * + * Solo procesa el elemento raiz (cfdi:Comprobante) para evitar tocar + * declaraciones inline en nodos hijos. + */ +export function removeNonSatNamespaces(xml: string): string { + // Captura la apertura del elemento raiz (hasta el primer '>') y procesa + // solo los xmlns dentro de ese bloque. + return xml.replace( + /()/, + (_match, open, attrs, close) => { + const cleaned = attrs.replace( + /\s+xmlns:[a-zA-Z0-9_-]+="([^"]*)"/g, + (declaration: string, uri: string) => { + return SAT_NAMESPACES.has(uri) ? declaration : ''; + } + ); + return `${open}${cleaned}${close}`; + } + ); +} diff --git a/packages/cfdi/cleaner/src/cleaners/removeNonSatNodes.ts b/packages/cfdi/cleaner/src/cleaners/removeNonSatNodes.ts new file mode 100644 index 00000000..d465408f --- /dev/null +++ b/packages/cfdi/cleaner/src/cleaners/removeNonSatNodes.ts @@ -0,0 +1,40 @@ +import { SAT_NAMESPACES } from './satNamespaces'; + +/** + * Dentro de , elimina nodos hijo cuyo namespace URI + * no este en la lista de namespaces oficiales del SAT. + * + * Estrategia: extrae el contenido interno de cfdi:Complemento y filtra + * cada nodo hijo de primer nivel por su prefix, resolviendo el URI + * contra los xmlns declarados en el XML. + */ +export function removeNonSatNodes(xml: string): string { + // Construye un mapa prefix -> URI a partir de todas las declaraciones xmlns + // presentes en el documento (pueden estar en el root o en nodos hijos). + const prefixToUri: Record = {}; + const xmlnsPattern = /xmlns:([a-zA-Z0-9_-]+)="([^"]*)"/g; + let m: RegExpExecArray | null; + while ((m = xmlnsPattern.exec(xml)) !== null) { + prefixToUri[m[1]] = m[2]; + } + + return xml.replace( + /(]*>)([\s\S]*?)(<\/cfdi:Complemento>)/g, + (_match, open, inner, close) => { + // Elimina nodos hijo cuyo prefix resuelve a un namespace no-SAT. + // Patron: ... o + const cleaned = inner.replace( + /<([a-zA-Z0-9_-]+):([a-zA-Z0-9_-]+)([\s\S]*?)(?:<\/\1:\2>|\/>)/g, + (nodeMatch: string, prefix: string) => { + const uri = prefixToUri[prefix]; + // Si no conocemos el URI o no es SAT, eliminamos el nodo + if (!uri || !SAT_NAMESPACES.has(uri)) { + return ''; + } + return nodeMatch; + } + ); + return `${open}${cleaned}${close}`; + } + ); +} diff --git a/packages/cfdi/cleaner/src/cleaners/removeNonSatSchemaLocations.ts b/packages/cfdi/cleaner/src/cleaners/removeNonSatSchemaLocations.ts new file mode 100644 index 00000000..44470a6d --- /dev/null +++ b/packages/cfdi/cleaner/src/cleaners/removeNonSatSchemaLocations.ts @@ -0,0 +1,30 @@ +import { SAT_NAMESPACES } from './satNamespaces'; + +/** + * Limpia el atributo xsi:schemaLocation eliminando pares URI+XSD donde el URI + * no sea un namespace oficial del SAT. + * + * El valor de xsi:schemaLocation es una lista de pares separados por espacios: + * "namespaceURI schemaURI namespaceURI2 schemaURI2 ..." + */ +export function removeNonSatSchemaLocations(xml: string): string { + return xml.replace( + /xsi:schemaLocation="([^"]*)"/g, + (_match, locations: string) => { + const tokens = locations.trim().split(/\s+/); + const kept: string[] = []; + + // Los tokens vienen en pares: [namespaceURI, xsdURI, namespaceURI2, ...] + for (let i = 0; i < tokens.length - 1; i += 2) { + const namespaceUri = tokens[i]; + const xsdUri = tokens[i + 1]; + if (SAT_NAMESPACES.has(namespaceUri)) { + kept.push(namespaceUri, xsdUri); + } + } + + // Si queda un token huerfano (numero impar) lo descartamos + return `xsi:schemaLocation="${kept.join(' ')}"`; + } + ); +} diff --git a/packages/cfdi/cleaner/src/cleaners/removeStylesheetAttributes.ts b/packages/cfdi/cleaner/src/cleaners/removeStylesheetAttributes.ts new file mode 100644 index 00000000..3c4598ec --- /dev/null +++ b/packages/cfdi/cleaner/src/cleaners/removeStylesheetAttributes.ts @@ -0,0 +1,9 @@ +/** + * Elimina processing instructions del XML. + * + * Estas instrucciones de procesamiento no son parte del estandar CFDI y + * pueden causar problemas en sistemas que validan el XML estrictamente. + */ +export function removeStylesheetAttributes(xml: string): string { + return xml.replace(/<\?xml-stylesheet[^?]*\?>/gi, ''); +} diff --git a/packages/cfdi/cleaner/src/cleaners/satNamespaces.ts b/packages/cfdi/cleaner/src/cleaners/satNamespaces.ts new file mode 100644 index 00000000..7fb1001f --- /dev/null +++ b/packages/cfdi/cleaner/src/cleaners/satNamespaces.ts @@ -0,0 +1,43 @@ +/** + * Namespaces oficiales del SAT que NO deben eliminarse. + * Incluye todos los complementos fiscales publicados en el Anexo 20. + */ +export const SAT_NAMESPACES: ReadonlySet = new Set([ + 'http://www.sat.gob.mx/cfd/3', + 'http://www.sat.gob.mx/cfd/4', + 'http://www.sat.gob.mx/TimbreFiscalDigital', + 'http://www.sat.gob.mx/implocal', + 'http://www.sat.gob.mx/Pagos', + 'http://www.sat.gob.mx/Pagos20', + 'http://www.sat.gob.mx/nomina12', + 'http://www.sat.gob.mx/nomina', + 'http://www.sat.gob.mx/ComercioExterior11', + 'http://www.sat.gob.mx/ComercioExterior20', + 'http://www.sat.gob.mx/CartaPorte20', + 'http://www.sat.gob.mx/CartaPorte30', + 'http://www.sat.gob.mx/CartaPorte31', + 'http://www.sat.gob.mx/iedu', + 'http://www.sat.gob.mx/donat', + 'http://www.sat.gob.mx/divisas', + 'http://www.sat.gob.mx/leyendasFiscales', + 'http://www.sat.gob.mx/pfic', + 'http://www.sat.gob.mx/TuristaPasajeroExtranjero', + 'http://www.sat.gob.mx/registrofiscal', + 'http://www.sat.gob.mx/pagoenespecie', + 'http://www.sat.gob.mx/aerolineas', + 'http://www.sat.gob.mx/valesdedespensa', + 'http://www.sat.gob.mx/notariospublicos', + 'http://www.sat.gob.mx/vehiculousado', + 'http://www.sat.gob.mx/servicioparcialconstruccion', + 'http://www.sat.gob.mx/renovacionysustitucionvehiculos', + 'http://www.sat.gob.mx/certificadodestruccion', + 'http://www.sat.gob.mx/arteantiguedades', + 'http://www.sat.gob.mx/ine', + 'http://www.sat.gob.mx/ventavehiculos', + 'http://www.sat.gob.mx/detallista', + 'http://www.sat.gob.mx/EstadoDeCuentaCombustible12', + 'http://www.sat.gob.mx/ConsumoDeCombustibles11', + 'http://www.sat.gob.mx/GastosHidrocarburos10', + 'http://www.sat.gob.mx/IngresosHidrocarburos10', + 'http://www.w3.org/2001/XMLSchema-instance', +]); diff --git a/packages/cfdi/cleaner/src/index.ts b/packages/cfdi/cleaner/src/index.ts new file mode 100644 index 00000000..f6d5d2ab --- /dev/null +++ b/packages/cfdi/cleaner/src/index.ts @@ -0,0 +1,2 @@ +export { CfdiCleaner } from './CfdiCleaner'; +export * from './cleaners'; diff --git a/packages/cfdi/cleaner/test/cleaner.test.ts b/packages/cfdi/cleaner/test/cleaner.test.ts new file mode 100644 index 00000000..95500177 --- /dev/null +++ b/packages/cfdi/cleaner/test/cleaner.test.ts @@ -0,0 +1,371 @@ +import path from 'node:path'; +import { describe, expect, it } from 'vitest'; +import { CfdiCleaner } from '../src/CfdiCleaner'; +import { + collapseWhitespace, + removeAddenda, + removeNonSatNamespaces, + removeNonSatNodes, + removeNonSatSchemaLocations, + removeStylesheetAttributes, +} from '../src/cleaners'; + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +const EXAMPLES_DIR = path.resolve( + __dirname, + '../../../files/xml/examples/cfdi40' +); + +// XML base limpio (sin addenda, sin namespaces no-SAT) +const XML_CLEAN = ` + + + + + + + + + +`; + +// XML con addenda +const XML_WITH_ADDENDA = ` + + + + + + + + PO-2024-001 + CC-100 + + +`; + +// XML con addenda multilinea +const XML_WITH_ADDENDA_MULTILINE = ` + + + + + + + dato 1 + dato 2 + + +`; + +// XML con namespaces no-SAT +const XML_WITH_NON_SAT_NS = ` + + +`; + +// XML con schemaLocations de terceros +const XML_WITH_NON_SAT_SCHEMA = ` + + +`; + +// XML con nodo no-SAT en Complemento +const XML_WITH_NON_SAT_COMPLEMENT_NODE = ` + + + + + +`; + +// XML con stylesheet PI +const XML_WITH_STYLESHEET = ` + + + +`; + +// --------------------------------------------------------------------------- +// Tests unitarios por cleaner +// --------------------------------------------------------------------------- + +describe('removeAddenda()', () => { + it('elimina bloque cfdi:Addenda completo', () => { + const result = removeAddenda(XML_WITH_ADDENDA); + expect(result).not.toContain(''); + }); + + it('elimina addenda multilinea con contenido anidado', () => { + const result = removeAddenda(XML_WITH_ADDENDA_MULTILINE); + expect(result).not.toContain('cfdi:Addenda'); + expect(result).not.toContain('extra:Info'); + expect(result).not.toContain('dato 1'); + }); + + it('preserva el Sello del Comprobante', () => { + const result = removeAddenda(XML_WITH_ADDENDA); + expect(result).toContain('Sello="ABC123"'); + }); + + it('preserva el UUID del TimbreFiscalDigital', () => { + const result = removeAddenda(XML_WITH_ADDENDA); + expect(result).toContain('UUID="A1B2C3D4-0000-0000-0000-000000000001"'); + }); + + it('no modifica un XML sin addenda', () => { + const result = removeAddenda(XML_CLEAN); + expect(result).toBe(XML_CLEAN); + }); +}); + +describe('removeNonSatNamespaces()', () => { + it('elimina declaraciones xmlns no-SAT del root', () => { + const result = removeNonSatNamespaces(XML_WITH_NON_SAT_NS); + expect(result).not.toContain('xmlns:vendor="http://www.proveedor.com/ns"'); + expect(result).not.toContain('xmlns:erp="http://erp.empresa.com/v1"'); + }); + + it('preserva namespaces oficiales del SAT', () => { + const result = removeNonSatNamespaces(XML_WITH_NON_SAT_NS); + expect(result).toContain('xmlns:cfdi="http://www.sat.gob.mx/cfd/4"'); + expect(result).toContain( + 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' + ); + }); + + it('no modifica un XML sin namespaces no-SAT', () => { + const result = removeNonSatNamespaces(XML_CLEAN); + expect(result).toBe(XML_CLEAN); + }); + + it('preserva el namespace tfd en el Complemento (declarado en nodo hijo)', () => { + // tfd esta declarado en el nodo TimbreFiscalDigital, no en el root + const result = removeNonSatNamespaces(XML_WITH_NON_SAT_NS); + // El XML de prueba no tiene tfd en root, solo en hijo; el cleaner + // solo actua sobre el root element + expect(result).toContain('xmlns:cfdi="http://www.sat.gob.mx/cfd/4"'); + }); +}); + +describe('removeNonSatSchemaLocations()', () => { + it('elimina pares URI+XSD no-SAT del schemaLocation', () => { + const result = removeNonSatSchemaLocations(XML_WITH_NON_SAT_SCHEMA); + // El URI del tercero no debe aparecer dentro del atributo schemaLocation + expect(result).not.toContain('http://proveedor.com/schema/vendor.xsd'); + // El schemaLocation resultante no debe incluir el namespace del proveedor + const schemaMatch = result.match(/xsi:schemaLocation="([^"]*)"/); + expect(schemaMatch).not.toBeNull(); + expect(schemaMatch![1]).not.toContain('http://proveedor.com/ns'); + }); + + it('preserva pares URI+XSD del SAT en schemaLocation', () => { + const result = removeNonSatSchemaLocations(XML_WITH_NON_SAT_SCHEMA); + expect(result).toContain('http://www.sat.gob.mx/cfd/4'); + expect(result).toContain( + 'http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd' + ); + }); + + it('mantiene el atributo xsi:schemaLocation aunque quede vacio de SAT', () => { + const xml = ``; + const result = removeNonSatSchemaLocations(xml); + expect(result).toContain('xsi:schemaLocation=""'); + }); + + it('no modifica un XML sin schemaLocation de terceros', () => { + const result = removeNonSatSchemaLocations(XML_CLEAN); + expect(result).toBe(XML_CLEAN); + }); +}); + +describe('removeNonSatNodes()', () => { + it('elimina nodos con namespace no-SAT dentro de cfdi:Complemento', () => { + const result = removeNonSatNodes(XML_WITH_NON_SAT_COMPLEMENT_NODE); + expect(result).not.toContain('vendor:DatosExtra'); + expect(result).not.toContain('Foo="bar"'); + }); + + it('preserva TimbreFiscalDigital (namespace SAT) en Complemento', () => { + const result = removeNonSatNodes(XML_WITH_NON_SAT_COMPLEMENT_NODE); + expect(result).toContain('tfd:TimbreFiscalDigital'); + expect(result).toContain('UUID="UUID-002"'); + }); + + it('no modifica nodos fuera de cfdi:Complemento', () => { + const result = removeNonSatNodes(XML_WITH_NON_SAT_COMPLEMENT_NODE); + expect(result).toContain(' { + const xmlSinComplemento = ``; + const result = removeNonSatNodes(xmlSinComplemento); + expect(result).toBe(xmlSinComplemento); + }); +}); + +describe('removeStylesheetAttributes()', () => { + it('elimina processing instruction xml-stylesheet', () => { + const result = removeStylesheetAttributes(XML_WITH_STYLESHEET); + expect(result).not.toContain(' { + const result = removeStylesheetAttributes(XML_WITH_STYLESHEET); + expect(result).toContain(' { + const result = removeStylesheetAttributes(XML_WITH_STYLESHEET); + expect(result).toContain(' { + const result = removeStylesheetAttributes(XML_CLEAN); + expect(result).toBe(XML_CLEAN); + }); + + it('elimina multiples PI xml-stylesheet', () => { + const xml = ``; + const result = removeStylesheetAttributes(xml); + expect(result).not.toContain(''); + }); +}); + +describe('collapseWhitespace()', () => { + it('colapsa multiples saltos de linea entre tags a uno solo', () => { + const xml = `\n\n\n \n\n`; + const result = collapseWhitespace(xml); + expect(result).not.toMatch(/>\s{2,} { + const xml = `Juan Garcia`; + const result = collapseWhitespace(xml); + expect(result).toContain('Juan Garcia'); + }); + + it('elimina whitespace al inicio y final del documento', () => { + const xml = ` \n `; + const result = collapseWhitespace(xml); + expect(result).toBe(''); + }); +}); + +// --------------------------------------------------------------------------- +// Tests de integracion: CfdiCleaner +// --------------------------------------------------------------------------- + +describe('CfdiCleaner', () => { + const cleaner = new CfdiCleaner(); + + describe('clean()', () => { + it('elimina addenda del XML sucio', () => { + const result = cleaner.clean(XML_WITH_ADDENDA); + expect(result).not.toContain('cfdi:Addenda'); + expect(result).not.toContain('PedidoInterno'); + }); + + it('preserva Sello, Certificado y UUID tras limpieza', () => { + const xmlConTodo = ` + + + + + + + + eliminar + +`; + + const result = cleaner.clean(xmlConTodo); + + // Contenido critico NO debe modificarse + expect(result).toContain('Sello="SELLO_ORIGINAL"'); + expect(result).toContain('Certificado="CERT_ORIGINAL"'); + expect(result).toContain('UUID="UUID-REAL-123"'); + expect(result).toContain('SelloCFD="SELLO_CFD"'); + expect(result).toContain('SelloSAT="SELLO_SAT"'); + + // Contenido no-SAT debe eliminarse + expect(result).not.toContain(' { + // Aplicar clean al XML limpio: puede cambiar whitespace pero no contenido + const result = cleaner.clean(XML_CLEAN); + + // El contenido esencial debe estar intacto + expect(result).toContain('Sello="ABC123"'); + expect(result).toContain('xmlns:cfdi="http://www.sat.gob.mx/cfd/4"'); + expect(result).toContain('UUID="A1B2C3D4-E5F6-7890-ABCD-EF1234567890"'); + expect(result).toContain('SelloCFD="ABC"'); + expect(result).toContain('SelloSAT="XYZ"'); + }); + + it('elimina nodo no-SAT en Complemento preservando tfd', () => { + const result = cleaner.clean(XML_WITH_NON_SAT_COMPLEMENT_NODE); + expect(result).not.toContain('vendor:DatosExtra'); + expect(result).toContain('tfd:TimbreFiscalDigital'); + }); + + it('elimina namespaces no-SAT del root', () => { + const result = cleaner.clean(XML_WITH_NON_SAT_NS); + expect(result).not.toContain('xmlns:vendor'); + expect(result).not.toContain('xmlns:erp'); + expect(result).toContain('xmlns:cfdi="http://www.sat.gob.mx/cfd/4"'); + }); + + it('elimina schemaLocation de terceros', () => { + const result = cleaner.clean(XML_WITH_NON_SAT_SCHEMA); + expect(result).not.toContain('http://proveedor.com'); + }); + + it('elimina stylesheet PI', () => { + const result = cleaner.clean(XML_WITH_STYLESHEET); + expect(result).not.toContain(' { + it('limpia archivo real de CFDI 4.0 (cfdi-validator-cfdi40-real.xml)', () => { + const filePath = `${EXAMPLES_DIR}/cfdi-validator-cfdi40-real.xml`; + const result = cleaner.cleanFile(filePath); + + // El archivo real es ya limpio: debe conservar sus elementos esenciales + expect(result).toContain('cfdi:Comprobante'); + expect(result).toContain('tfd:TimbreFiscalDigital'); + expect(result).not.toContain(' { + const filePath = `${EXAMPLES_DIR}/CfdiUtils-cfdi40-real.xml`; + const result = cleaner.cleanFile(filePath); + + // UUID del TimbreFiscalDigital debe estar intacto + expect(result).toContain('UUID="C2832671-DA6D-11EF-A83D-00155D012007"'); + // El sello del CFD debe estar intacto + expect(result).toContain('WZzQVFmM/0E21+v4Th3K9K3a8yfN8TPwkarBsD28YUb'); + }); + + it('lanza error si el archivo no existe', () => { + expect(() => + cleaner.cleanFile('/ruta/que/no/existe/factura.xml') + ).toThrow(); + }); + }); +}); diff --git a/packages/cfdi/cleaner/tsconfig.json b/packages/cfdi/cleaner/tsconfig.json new file mode 100644 index 00000000..65798cc2 --- /dev/null +++ b/packages/cfdi/cleaner/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "lib": ["dom", "esnext"], + "types": ["node"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "noUnusedLocals": false, + "noUnusedParameters": false + } +} diff --git a/packages/cfdi/cleaner/vitest.config.mts b/packages/cfdi/cleaner/vitest.config.mts new file mode 100644 index 00000000..9152d739 --- /dev/null +++ b/packages/cfdi/cleaner/vitest.config.mts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; + +export default defineConfig({ + test: {}, + plugins: [tsconfigPaths()], +}); diff --git a/packages/cfdi/complementos/README.md b/packages/cfdi/complementos/README.md index 9f7b855e..ce2f38d9 100644 --- a/packages/cfdi/complementos/README.md +++ b/packages/cfdi/complementos/README.md @@ -1,205 +1,119 @@ -# CFDI +# @cfdi/complementos -

- - Nest Logo -

-
    -
  • @cfdi/xml
  • +Complementos fiscales para CFDI 3.3 y 4.0. Proporciona las clases necesarias para agregar complementos al comprobante fiscal conforme a las especificaciones del SAT. -
  • @cfdi/catalogos
  • @cfdi/csd
  • @cfdi/utils
  • @cfdi/pdf
  • @cfdi/curp +## Instalacion -
  • @cfdi/csf
  • -
  • @cfdi/rfc
-Documentacion -

- Este módulo genera un CFDI a partir de clases lo que facilita la creacion de XMl y sellarlo sin nigun problema de compatibilidad de las versiones 2.0 del xml de complementos. -

- -
- - - - -
- -Instala las dependencias and devDependencies y comienza a crear xml CFDI 4.0. -Para Windows Lea la Documentacion - -# Dependeces - -JDK - -```sh - sudo apt install default-jre - sudo apt install default-jdk +```bash +npm install @cfdi/complementos ``` -Openssl +## Uso -```sh - Debian/Ubuntu: sudo apt-get install openssl - CentOS, Red Hat: yum install openssl - Archlinux: sudo pacman -S openssl -``` +### Complemento de Pagos 2.0 -Saxon-HE >=9.9.1.6J +```typescript +import { Pagos20, Pago20, Pago20Relacionado, Pago20Impuestos } from '@cfdi/complementos'; -```sh - - official: http://saxon.sourceforge.net/ - Archlinux: https://aur.archlinux.org/packages/saxon-he - - Automatic Installation Alternative - - https://github.com/MisaelMa/saxon-he - sudo chmod 777 saxon.sh - sudo ./saxon.sh - - ███████╗ █████╗ ██╗ ██╗ ██████╗ ███╗ ██╗ ██╗ ██╗███████╗ - ██╔════╝██╔══██╗╚██╗██╔╝██╔═══██╗████╗ ██║ ██║ ██║██╔════╝ - ███████╗███████║ ╚███╔╝ ██║ ██║██╔██╗ ██║ ███████║█████╗ - ╚════██║██╔══██║ ██╔██╗ ██║ ██║██║╚██╗██║ ██╔══██║██╔══╝ - ███████║██║ ██║██╔╝ ██╗╚██████╔╝██║ ╚████║ ██║ ██║███████╗ - ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝ -``` +const pagos = new Pagos20(); +const pago = new Pago20({ + FechaPago: '2024-01-15T12:00:00', + FormaDePagoP: '01', + MonedaP: 'MXN', + Monto: '1000.00', +}); -# Installation +const relacionado = new Pago20Relacionado({ + IdDocumento: 'UUID-DEL-CFDI', + MonedaDR: 'MXN', + NumParcialidad: '1', + ImpSaldoAnt: '1000.00', + ImpPagado: '1000.00', + ImpSaldoInsoluto: '0.00', +}); -```sh -npm i --save @cfdi/xml +const complemento = pagos.getComplement(); ``` -# Complementos - -## Información adicional para las Facturas - -- [x] :pushpin: Timbre fiscal digital (TFD). -- [ ] Estado de cuenta de combustibles de monederos electrónicos. -- [x] :pushpin: Donatarias. -- [x] :pushpin: Compra venta de divisas. -- [x] :pushpin: Otros derechos e impuestos. -- [x] :pushpin: Leyendas fiscales. -- [x] :pushpin: Persona física integrante de coordinado. -- [x] :pushpin: Turista pasajero extranjero. -- [x] :pushpin: Spei de tercero a tercero. -- [ ] Sector de ventas al detalle (Detallista). -- [x] :pushpin: CFDI Registro fiscal. -- [ ] Recibo de pago de nómina. -- [x] :pushpin: Pago en especie. -- [x] :pushpin: Vales de despensa. -- [x] :pushpin: Consumo de combustibles. versión 1.1 -- [x] :pushpin: Aerolíneas. -- [ ] Notarios Públicos. -- [x] :pushpin: Vehículo usado. -- [x] :pushpin: Servicios parciales de construcción. -- [x] :pushpin: Renovación y sustitución de vehículos. -- [x] :pushpin: Certificado de destrucción -- [x] :pushpin: Obras de arte plásticas y antigüedades -- [x] :pushpin: INE -- [x] :pushpin: Comercio Exterior versión 1.1 -- [x] :pushpin: Recepción de pagos -- [x] Hidrocarburos - - [x] :pushpin: IngresosHidrocarburos - - [x] :pushpin: GastosHidrocarburos10 - -## Complementos de Concepto - -- [x] :pushpin: Instituciones educativas privadas. -- [ ] Venta de vehículos. -- [ ] Terceros. -- [ ] Acreditamiento del IEPS - -# Informacion Oficial - -- Certificados de prueba - http://omawww.sat.gob.mx/tramitesyservicios/Paginas/certificado_sello_digital.htm -- Anexo 20 - http://omawww.sat.gob.mx/tramitesyservicios/Paginas/anexo_20_version3-3.htm -- Catálogo de productos y servicios - http://pys.sat.gob.mx/PyS/catPyS.aspx -- Catálogo de unidades de medida - http://pys.sat.gob.mx/PyS/catUnidades.aspx -- Consulta los complementos y complementos concepto de factura - -https://www.sat.gob.mx/consultas/49522/complementos-y-complementos-concepto-de-factura- - -https://www.sat.gob.mx/cs/Satellite?blobcol=urldata&blobkey=id&blobtable=MungoBlobs&blobwhere=1461173971924&ssbinary=true - -# Generar archivos .pem - -Lo primero que se necesita es tener instalada la librería OpenSSL (programa dedicado a la generación y tratado de claves, certificados y keyStore) para poder utilizar los comandos que nos ayudarán a crear las llaves de nuestros sellos digitales. +### Complemento Carta Porte 2.0 -## Linux +```typescript +import { CartaPorte20 } from '@cfdi/complementos'; -Instalar librería: +const cartaPorte = new CartaPorte20({ + TranspInternac: 'No', + TotalDistRec: '100.00', +}); -Debian/Ubuntu: #sudo apt-get install openssl - -CentOS, Red Hat: #yum install openssl - -Ejecutar las instrucciones: - -Archivo key.pem - -```sh -openssl pkcs8 -inform DER -in nombrearchivo.key -out nombrearchivo.key.pem -passin pass:contraseña +const complemento = cartaPorte.getComplement(); ``` -archivo cer.pem - -```sh -openssl x509 -inform DER -outform PEM -in ruta/nombreArchivo.cer -pubkey -out ruta/nombreArchivo.cer.pem -``` +### Timbre Fiscal Digital (TFD) -## Windows +```typescript +import { Tfd } from '@cfdi/complementos'; -Descargar libreria: http://slproweb.com/products/Win32OpenSSL.html - -Deberán descargar la versión según su sistema operativo, e instalar. - -Ejecutar desde terminal - -Archivo key.pem - -```sh -openssl.exe pkcs8 -inform DER -in ruta/nombreArchivo.key -passin pass:contraseña -out ruta/nombreArchivo.key.pem +const tfd = new Tfd({ + Version: '1.1', + UUID: 'DC2ED983-D108-402E-A2FD-C08EDDA23C47', + FechaTimbrado: '2024-01-15T18:05:05', + SelloCFD: '...', + SelloSAT: '...', + NoCertificadoSAT: '30001000000400002495', +}); ``` -archivo cer.pem +### Clase base Complemento -```sh -openssl.exe x509 -inform DER -outform PEM -in ruta/nombreArchivo.cer -pubkey -out ruta/nombreArchivo.cer.pem -``` +Todos los complementos extienden de la clase abstracta `Complemento`, que provee el metodo `getComplement()` para obtener la estructura XML del complemento. -# Generar QR +```typescript +import { Complemento } from '@cfdi/complementos'; -ESPECIFICACIÓN TÉCNICA DEL CÓDIGO DE BARRAS BIDIMENSIONAL A INCORPORAR EN LA REPRESENTACIÓN IMPRESA. - -Las representaciones impresas de los dos tipos de comprobantes fiscales digitales por Internet deben incluir un código de barras bidimensional conforme al formato de QR Code (Quick Response Code),usando la capacidad de corrección de error con nivel mínimo M, descrito en el estándar ISO/IEC18004, con base en los siguientes lineamientos. - -a) Debe contener los siguientes datos en la siguiente secuencia: - - *La URL del acceso al servicio que pueda mostrar los datos de la versión publica del comprobante. - *Numero de folio fiscal del comprobante (UUID). - *RFC del emisor. - *RFC del receptor. - *Ocho últimos caracteres del sello digital del emisor del comprobante. - -Donde se manejan / caracteres conformados de la siguiente manera: - -

- The house from the offer. -

- -De esta manera se generan los datos validos para realizar una consulta de un CFDI por medio de su expresión impresa. - -Ejemplo: - -https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=5803EB8D-81CD-4557-8719-26632D2FA434&re=XAXX010101000&rr=CARR861127SB0&tt=0000014300.000000&fe=rH8/bw== - -El código de barras bidimensional debe ser impreso en un cuadro con lados no menores a 2.75 centímetros. +// getComplement() retorna: +// { +// complement: T, // Datos del complemento +// key: string, // Clave del nodo XML +// schemaLocation: string[],// URLs del esquema XSD +// xmlns: string, // Namespace XML +// xmlnskey: string, // Prefijo del namespace +// } +``` -

-The house from the offer. -

+## API + +### Complementos CFDI 4.0 + +| Clase | Descripcion | +|-------|-------------| +| `Pagos20` / `Pago20` | Recepcion de pagos 2.0 | +| `CartaPorte20` | Carta porte 2.0 | +| `Aerolineas` | Aerolineas | +| `Ine` | Instituto Nacional Electoral | +| `Iedu` | Instituciones educativas | + +### Complementos CFDI 3.3 + +| Clase | Descripcion | +|-------|-------------| +| `Tfd` | Timbre fiscal digital | +| `Cce11` | Comercio exterior 1.1 | +| `Nomina12` | Nomina 1.2 | +| `Divisas` | Divisas | +| `Donat` | Donatarias | +| `LeyendaFisc` | Leyendas fiscales | +| `VehiculoUsado` | Vehiculo usado | +| `Destruccion` | Certificado de destruccion | +| `ObrasArte` | Obras de arte | +| `ServicioParcial` | Servicios parciales de construccion | +| `Implocal` | Impuestos locales | +| `Hidrocarburos` | Gastos e ingresos de hidrocarburos | +| `Detallista` | Detallista | +| `Spei` | SPEI | +| `ValesDeDespensa` | Vales de despensa | +| `ConsumoDeCombustibles11` | Consumo de combustibles 1.1 | +| `VentaVehiculos` | Venta de vehiculos | + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/complementos/config/index.js b/packages/cfdi/complementos/config/index.js deleted file mode 100644 index 9eb0a286..00000000 --- a/packages/cfdi/complementos/config/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict' -module.exports = require('./complementos.cjs.production.min.js') diff --git a/packages/cfdi/complementos/package.json b/packages/cfdi/complementos/package.json index d4b6024b..d4030fde 100644 --- a/packages/cfdi/complementos/package.json +++ b/packages/cfdi/complementos/package.json @@ -4,9 +4,9 @@ "description": "Libreria para generar complementos del cfdi V4.0", "homepage": "https://cfdi.recreando.dev", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/complementos.esm.production.min.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "release": { "branches": [ @@ -27,68 +27,24 @@ "url": "https://github.com/MisaelMa/recreando" }, "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build --env production --minify && rimraf ./dist/index.js ./dist/*.cjs.development.* && npm run cp", - "cp": "cp ./config/index.js ./dist", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/complementos.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/complementos.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "xml-js": "^1.6.11" }, "devDependencies": { - "rimraf": "^6.0.1", "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", "@recreando/vite": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", + "@types/node": "^22", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/complementos/vite.config.mts b/packages/cfdi/complementos/vite.config.mts new file mode 100644 index 00000000..78f30cf9 --- /dev/null +++ b/packages/cfdi/complementos/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xml-js'], + }, + }, +})); diff --git a/packages/cfdi/csd/README.md b/packages/cfdi/csd/README.md index 3104ea14..b3af5ffc 100644 --- a/packages/cfdi/csd/README.md +++ b/packages/cfdi/csd/README.md @@ -1 +1,84 @@ -csd +# @cfdi/csd + +Manejo de Certificados de Sello Digital (CSD) del SAT. Permite leer archivos `.cer` y `.key`, extraer informacion del certificado y firmar cadenas originales. + +## Instalacion + +```bash +npm install @cfdi/csd +``` + +## Uso + +### Certificado (.cer) + +```typescript +import { cer } from '@cfdi/csd'; + +// Cargar archivo de certificado +cer.setFile('/ruta/al/certificado.cer'); + +// Obtener PEM +const pem = cer.getPem(); +const pemSinHeaders = cer.getPem({ begin: true }); // Sin BEGIN/END + +// Informacion del certificado +const noCertificado = cer.getNoCer(); // Numero de certificado +const serial = cer.serial(); // Numero de serie hex +const fechas = cer.date(); // { startDate, endDate } +const vigencia = cer.validity(); // { notBefore, notAfter } +const sujeto = cer.subject(); // Datos del titular +const emisor = cer.issuer(); // Datos del emisor +const llave = cer.pubkey(); // Llave publica PEM +const huella = cer.fingerPrint(); // Huella digital + +// Verificar si el certificado expira en N segundos +const expira = cer.checkend(86400); // Verificar si expira en 24 horas +``` + +### Llave privada (.key) + +```typescript +import { key } from '@cfdi/csd'; + +// Cargar archivo de llave con contrasena +key.setFile('/ruta/a/llave.key', 'contrasena123'); + +// Obtener PEM +const pem = key.getPem(); + +// Firmar cadena original +const firma = key.signatureHexForge('cadena original'); // Firma con node-forge +const firma2 = key.signatureHexCripto('cadena original'); // Firma con crypto nativo +``` + +## API + +### Modulo `cer` + +| Funcion | Descripcion | +|---------|-------------| +| `setFile(path)` | Carga un archivo .cer o .pem | +| `getPem(options?)` | Retorna el certificado en formato PEM | +| `getNoCer()` | Retorna el numero de certificado | +| `serial()` | Retorna el numero de serie hexadecimal | +| `date(format?)` | Retorna fechas de inicio y fin de vigencia | +| `validity()` | Retorna `{ notBefore, notAfter }` como objetos Date | +| `checkend(seconds)` | Verifica si el certificado expira en N segundos | +| `subject()` | Retorna los datos del titular del certificado | +| `issuer()` | Retorna los datos del emisor del certificado | +| `pubkey(options?)` | Retorna la llave publica en formato PEM | +| `fingerPrint()` | Retorna la huella digital del certificado | + +### Modulo `key` + +| Funcion | Descripcion | +|---------|-------------| +| `setFile(path, password?)` | Carga un archivo .key con contrasena | +| `getPem(options?)` | Retorna la llave privada en formato PEM | +| `signatureHexForge(message)` | Firma SHA256 usando node-forge, retorna base64 | +| `signatureHexCripto(message)` | Firma SHA256 usando crypto nativo, retorna base64 | + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/csd/config/index.js b/packages/cfdi/csd/config/index.js deleted file mode 100644 index ad4eb9d6..00000000 --- a/packages/cfdi/csd/config/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict' -module.exports = require('./csd.cjs.production.min.js') diff --git a/packages/cfdi/csd/package.json b/packages/cfdi/csd/package.json index ea8db676..5345b2ba 100644 --- a/packages/cfdi/csd/package.json +++ b/packages/cfdi/csd/package.json @@ -2,82 +2,36 @@ "name": "@cfdi/csd", "version": "4.0.15", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/csd.esm.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "files": [ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build --env production --minify && rimraf ./dist/index.js ./dist/csd.cjs.development.* && npm run cp", - "cp": "cp ./config/index.js ./dist", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "author": "MisaelMa", - "size-limit": [ - { - "path": "dist/csd.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/csd.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "@clir/openssl": "workspace:*", - "curp": "^1.2.0", "moment": "^2.29.4", - "node-forge": "^1.3.1", - "validate-rfc": "^2.0.2" + "node-forge": "^1.3.1" }, "devDependencies": { - "rimraf": "^6.0.1", "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", "@recreando/vite": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", + "@types/node": "^22", "@types/node-forge": "^1.0.4", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/csd/src/Certificate.ts b/packages/cfdi/csd/src/Certificate.ts new file mode 100644 index 00000000..e0203a80 --- /dev/null +++ b/packages/cfdi/csd/src/Certificate.ts @@ -0,0 +1,309 @@ +import crypto from 'crypto'; +import { readFileSync } from 'fs'; +import { promises as fs } from 'fs'; +import pkg from 'node-forge'; + +const { pki, asn1, util } = pkg; + +/** + * Wrapper de certificado X.509 para CSD y FIEL del SAT. + * Usa crypto nativo de Node 22 para operaciones principales + * y node-forge para parseo de extensiones X.509. + */ +export class Certificate { + private readonly _forgeCert: pkg.pki.Certificate; + private readonly _pem: string; + + private constructor(pem: string) { + this._pem = pem; + this._forgeCert = pki.certificateFromPem(pem); + } + + /** + * Crea un Certificate a partir de un buffer DER (binario .cer) + */ + static fromDer(derBuffer: Buffer): Certificate { + const derStr = util.binary.raw.encode(new Uint8Array(derBuffer)); + const asnObj = asn1.fromDer(derStr); + const forgeCert = pki.certificateFromAsn1(asnObj); + const pem = pki.certificateToPem(forgeCert); + return new Certificate(pem); + } + + /** + * Crea un Certificate a partir de un PEM string + */ + static fromPem(pem: string): Certificate { + return new Certificate(pem); + } + + /** + * Crea un Certificate leyendo un archivo .cer (DER) o .pem + */ + static async fromFile(filePath: string): Promise { + const buf = await fs.readFile(filePath); + const isPem = + buf.toString('utf8', 0, 10).includes('-----') || + filePath.toLowerCase().endsWith('.pem'); + if (isPem) { + return Certificate.fromPem(buf.toString('ascii')); + } + return Certificate.fromDer(buf); + } + + /** + * Crea un Certificate leyendo un archivo de forma sincrona + */ + static fromFileSync(filePath: string): Certificate { + const buf = readFileSync(filePath); + const isPem = + buf.toString('utf8', 0, 10).includes('-----') || + filePath.toLowerCase().endsWith('.pem'); + if (isPem) { + return Certificate.fromPem(buf.toString('ascii')); + } + return Certificate.fromDer(buf); + } + + /** Retorna el certificado en formato PEM */ + toPem(): string { + return this._pem; + } + + /** Retorna el certificado en formato DER (Buffer) */ + toDer(): Buffer { + const derStr = asn1.toDer(pki.certificateToAsn1(this._forgeCert)).getBytes(); + return Buffer.from(derStr, 'binary'); + } + + /** + * Numero de serie del certificado (hex string). + * Para certificados del SAT se convierte a decimal ASCII (numero de certificado). + */ + serialNumber(): string { + return this._forgeCert.serialNumber; + } + + /** + * Numero de certificado SAT: convierte el serial hex a string decimal legible. + * El SAT codifica el numero de certificado como ASCII en hex. + */ + noCertificado(): string { + const hex = this._forgeCert.serialNumber; + // Si el serial son pares de hex que representan digitos ASCII (48-57 = '0'-'9') + if (hex.length % 2 === 0) { + const pairs = hex.match(/.{1,2}/g) ?? []; + const allDigits = pairs.every(p => { + const code = parseInt(p, 16); + return code >= 48 && code <= 57; + }); + if (allDigits) { + return pairs.map(p => String.fromCharCode(parseInt(p, 16))).join(''); + } + } + return hex; + } + + /** + * RFC del titular extraido del subject del certificado. + * + * El SAT codifica el RFC en distintos OIDs segun el tipo de certificado: + * - OID 2.5.4.45 (x500UniqueIdentifier): "RFC / CURP" (CSD persona fisica) + * o "RFC / CURP" (FIEL) + * - OID 2.5.4.5 (serialNumber): " / CURP" o solo CURP (algunos CSD) + * + * La estrategia es buscar el valor que tenga formato de RFC valido (12-13 chars + * alfanumericos) en los atributos del subject. + */ + rfc(): string { + const attrs = this._forgeCert.subject.attributes; + + // OID 2.5.4.45 - x500UniqueIdentifier: contiene "RFC / CURP" + const x500UniqueId = attrs.find(a => a.type === '2.5.4.45'); + if (x500UniqueId?.value) { + const raw = String(x500UniqueId.value).trim(); + // Formato "RFC / CURP" o solo "RFC" + const rfcPart = raw.split('/')[0].trim(); + if (rfcPart && this._isValidRfc(rfcPart)) return rfcPart; + } + + // OID 2.5.4.5 - serialNumber: puede contener " / CURP" (el RFC esta antes) + const serialAttr = attrs.find( + a => a.type === '2.5.4.5' || a.shortName === 'serialNumber' + ); + if (serialAttr?.value) { + const raw = String(serialAttr.value).trim(); + const rfcPart = raw.split('/')[0].trim(); + if (rfcPart && this._isValidRfc(rfcPart)) return rfcPart; + } + + // OID 0.9.2342.19200300.100.1.1 - uid + const uidAttr = attrs.find(a => a.type === '0.9.2342.19200300.100.1.1'); + if (uidAttr?.value) { + const val = String(uidAttr.value).trim(); + if (this._isValidRfc(val)) return val; + } + + // Busqueda en todos los atributos (fallback) + for (const attr of attrs) { + if (attr.value) { + const val = String(attr.value).trim(); + const part = val.split('/')[0].trim(); + if (this._isValidRfc(part)) return part; + } + } + + return ''; + } + + /** + * Valida formato basico de RFC mexicano (12 PM, 13 PF). + */ + private _isValidRfc(value: string): boolean { + // RFC: 3-4 letras, 6 digitos de fecha, 3 homoclave + return /^[A-Z&Ñ]{3,4}\d{6}[A-Z\d]{3}$/i.test(value); + } + + /** + * Nombre legal del titular extraido del subject (commonName o givenName) + */ + legalName(): string { + const attrs = this._forgeCert.subject.attributes; + + // CN (commonName) + const cn = attrs.find(a => a.shortName === 'CN' || a.type === '2.5.4.3'); + if (cn?.value) return String(cn.value); + + // givenName + const gn = attrs.find(a => a.type === '2.5.4.42'); + if (gn?.value) return String(gn.value); + + return ''; + } + + /** Retorna todos los atributos del issuer como objeto clave-valor */ + issuer(): Record { + return this._attributesToRecord(this._forgeCert.issuer.attributes); + } + + /** Retorna todos los atributos del subject como objeto clave-valor */ + subject(): Record { + return this._attributesToRecord(this._forgeCert.subject.attributes); + } + + /** Fecha de inicio de vigencia */ + validFrom(): Date { + return this._forgeCert.validity.notBefore; + } + + /** Fecha de fin de vigencia */ + validTo(): Date { + return this._forgeCert.validity.notAfter; + } + + /** Verdadero si el certificado esta vencido */ + isExpired(): boolean { + return new Date() > this._forgeCert.validity.notAfter; + } + + /** + * Fingerprint SHA-1 del certificado (formato AA:BB:CC:...) + */ + fingerprint(): string { + const derBuf = this.toDer(); + const hash = crypto.createHash('sha1').update(derBuf).digest('hex'); + return hash + .toUpperCase() + .match(/.{1,2}/g)! + .join(':'); + } + + /** + * Fingerprint SHA-256 del certificado + */ + fingerprintSha256(): string { + const derBuf = this.toDer(); + return crypto.createHash('sha256').update(derBuf).digest('hex').toUpperCase(); + } + + /** Llave publica en formato PEM */ + publicKey(): string { + return pki.publicKeyToPem(this._forgeCert.publicKey as pkg.pki.rsa.PublicKey); + } + + /** + * Detecta si es FIEL (eFirma). + * Los certificados FIEL del SAT tienen "FIEL" en el OU o en el CN, + * o el campo OU no contiene "CSD" ni "Prueba_CFDI". + * En la practica, los CSD tienen OU con "Prueba_CFDI" o similar, + * mientras que los FIEL tienen OU vacío o con "FIEL". + */ + isFiel(): boolean { + return !this.isCsd(); + } + + /** + * Detecta si es CSD (Certificado de Sello Digital). + * Los CSD del SAT incluyen en el subject OU un valor que indica + * su uso para sellos: "CSD", "Prueba_CFDI", etc. + * Tambien se puede verificar por el KeyUsage: digitalSignature sin + * nonRepudiation implica CSD; con nonRepudiation es FIEL. + */ + isCsd(): boolean { + const attrs = this._forgeCert.subject.attributes; + + // Buscar OU (organizationalUnitName) + const ou = attrs.find(a => a.shortName === 'OU' || a.type === '2.5.4.11'); + if (ou?.value) { + const ouVal = String(ou.value).toUpperCase(); + // CSD tiene OU con "CSD", "PRUEBA_CFDI", o similar + if ( + ouVal.includes('CSD') || + ouVal.includes('CFDI') || + ouVal.includes('SELLO') + ) { + return true; + } + // FIEL tiene OU con "FIEL" o "FIRMA" + if (ouVal.includes('FIEL') || ouVal.includes('FIRMA')) { + return false; + } + } + + // Verificar extensiones Key Usage + const keyUsageExt = this._forgeCert.extensions.find( + e => e.id === '2.5.29.15' || e.name === 'keyUsage' + ) as any; + + if (keyUsageExt) { + // CSD: digitalSignature = true, nonRepudiation = false + // FIEL: ambos true + if (keyUsageExt.digitalSignature && !keyUsageExt.nonRepudiation) { + return true; + } + } + + // Por defecto, si tiene serialNumber con " / " (RFC / CURP) es probablemente CSD + const serialAttr = attrs.find( + a => a.type === '2.5.4.5' || a.shortName === 'serialNumber' + ); + if (serialAttr?.value && String(serialAttr.value).includes('/')) { + return true; + } + + return false; + } + + private _attributesToRecord( + attributes: pkg.pki.CertificateField[] + ): Record { + const obj: Record = {}; + for (const attr of attributes) { + const key = attr.shortName || attr.name || String(attr.type); + if (key) { + obj[key] = String(attr.value ?? ''); + } + } + return obj; + } +} diff --git a/packages/cfdi/csd/src/Credential.ts b/packages/cfdi/csd/src/Credential.ts new file mode 100644 index 00000000..ce14f81a --- /dev/null +++ b/packages/cfdi/csd/src/Credential.ts @@ -0,0 +1,137 @@ +import crypto from 'crypto'; +import { Certificate } from './Certificate'; +import { PrivateKey } from './PrivateKey'; + +/** + * Une un certificado X.509 con su llave privada correspondiente. + * Soporta CSD (Certificado de Sello Digital) y FIEL (eFirma). + */ +export class Credential { + private constructor( + private readonly _certificate: Certificate, + private readonly _privateKey: PrivateKey + ) {} + + /** + * Crea un Credential cargando archivos desde el sistema de archivos. + * El archivo .cer puede ser DER o PEM; el .key siempre es DER cifrado del SAT. + */ + static async create( + cerPath: string, + keyPath: string, + password: string + ): Promise { + const [cert, key] = await Promise.all([ + Certificate.fromFile(cerPath), + PrivateKey.fromFile(keyPath, password), + ]); + return new Credential(cert, key); + } + + /** + * Crea un Credential a partir de strings PEM (sin cifrado). + * Util cuando ya se tiene el PEM del certificado y la llave. + */ + static fromPem(cerPem: string, keyPem: string): Credential { + const cert = Certificate.fromPem(cerPem); + const key = PrivateKey.fromPem(keyPem); + return new Credential(cert, key); + } + + /** + * Verdadero si el certificado es FIEL (eFirma). + */ + isFiel(): boolean { + return this._certificate.isFiel(); + } + + /** + * Verdadero si el certificado es CSD (Certificado de Sello Digital). + */ + isCsd(): boolean { + return this._certificate.isCsd(); + } + + /** + * RFC del titular extraido del subject del certificado. + */ + rfc(): string { + return this._certificate.rfc(); + } + + /** + * Nombre legal del titular. + */ + legalName(): string { + return this._certificate.legalName(); + } + + /** + * Numero de serie del certificado (hex). + */ + serialNumber(): string { + return this._certificate.serialNumber(); + } + + /** + * Numero de certificado SAT (decimal ASCII derivado del serial hex). + */ + noCertificado(): string { + return this._certificate.noCertificado(); + } + + /** + * Firma datos usando la llave privada con SHA-256 por defecto. + * Retorna la firma en base64. + */ + sign(data: string, algorithm = 'SHA256'): string { + return this._privateKey.sign(data, algorithm); + } + + /** + * Verifica una firma contra los datos usando la llave publica del certificado. + */ + verify(data: string, signature: string, algorithm = 'SHA256'): boolean { + try { + const pubKeyPem = this._certificate.publicKey(); + const pubKey = crypto.createPublicKey({ key: pubKeyPem, format: 'pem' }); + const verifier = crypto.createVerify(`RSA-${algorithm}`); + verifier.update(data, 'utf8'); + return verifier.verify(pubKey, signature, 'base64'); + } catch { + return false; + } + } + + /** + * Verdadero si el certificado no esta vencido. + */ + isValid(): boolean { + return !this._certificate.isExpired(); + } + + /** + * Verifica si el certificado pertenece al RFC dado. + */ + belongsTo(rfc: string): boolean { + return this._certificate.rfc().toUpperCase() === rfc.toUpperCase(); + } + + /** + * Verifica que la llave privada corresponda al certificado + * (compara llaves publicas). + */ + keyMatchesCertificate(): boolean { + return this._privateKey.belongsToCertificate(this._certificate); + } + + /** Acceso al certificado */ + get certificate(): Certificate { + return this._certificate; + } + + /** Acceso a la llave privada */ + get privateKey(): PrivateKey { + return this._privateKey; + } +} diff --git a/packages/cfdi/csd/src/PrivateKey.ts b/packages/cfdi/csd/src/PrivateKey.ts new file mode 100644 index 00000000..d28b74b0 --- /dev/null +++ b/packages/cfdi/csd/src/PrivateKey.ts @@ -0,0 +1,110 @@ +import crypto from 'crypto'; +import { readFileSync } from 'fs'; +import { promises as fs } from 'fs'; +import { Certificate } from './Certificate'; + +/** + * Llave privada RSA para CSD o FIEL del SAT. + * Usa crypto nativo de Node 22 para firma y verificacion. + */ +export class PrivateKey { + private readonly _pem: string; + private readonly _keyObject: crypto.KeyObject; + + private constructor(pem: string) { + this._pem = pem; + this._keyObject = crypto.createPrivateKey({ key: pem, format: 'pem' }); + } + + /** + * Carga una llave privada desde un buffer DER cifrado (archivo .key del SAT) + * usando OpenSSL para descifrar con la contrasena proporcionada. + */ + static fromDer(derBuffer: Buffer, password: string): PrivateKey { + // El .key del SAT es un PKCS#8 encriptado en DER + // Usar crypto nativo de Node 22 + const keyObject = crypto.createPrivateKey({ + key: derBuffer, + format: 'der', + type: 'pkcs8', + passphrase: password, + }); + const pem = keyObject.export({ format: 'pem', type: 'pkcs8' }) as string; + return new PrivateKey(pem); + } + + /** + * Carga una llave privada desde un PEM string (no encriptado) + */ + static fromPem(pem: string): PrivateKey { + return new PrivateKey(pem); + } + + /** + * Carga una llave privada desde un archivo .key (DER cifrado) o .pem + */ + static async fromFile(filePath: string, password: string): Promise { + const buf = await fs.readFile(filePath); + const isPem = + buf.toString('utf8', 0, 10).includes('-----') || + filePath.toLowerCase().endsWith('.pem'); + if (isPem) { + return PrivateKey.fromPem(buf.toString('ascii')); + } + return PrivateKey.fromDer(buf, password); + } + + /** + * Carga una llave privada desde un archivo de forma sincrona + */ + static fromFileSync(filePath: string, password: string): PrivateKey { + const buf = readFileSync(filePath); + const isPem = + buf.toString('utf8', 0, 10).includes('-----') || + filePath.toLowerCase().endsWith('.pem'); + if (isPem) { + return PrivateKey.fromPem(buf.toString('ascii')); + } + return PrivateKey.fromDer(buf, password); + } + + /** Retorna la llave privada en formato PEM (PKCS#8, sin cifrado) */ + toPem(): string { + return this._pem; + } + + /** + * Firma datos usando SHA-256 por defecto. + * Retorna la firma en base64. + */ + sign(data: string, algorithm = 'SHA256'): string { + const signer = crypto.createSign(`RSA-${algorithm}`); + signer.update(data, 'utf8'); + return signer.sign(this._keyObject, 'base64'); + } + + /** + * Verifica si esta llave privada corresponde al certificado dado, + * comparando la llave publica. + */ + belongsToCertificate(cert: Certificate): boolean { + try { + const certPubKeyPem = cert.publicKey(); + const certPubKey = crypto.createPublicKey({ key: certPubKeyPem, format: 'pem' }); + const privPubKey = crypto.createPublicKey(this._keyObject); + + // Comparar las llaves exportadas como DER + const certDer = certPubKey.export({ format: 'der', type: 'spki' }); + const privDer = privPubKey.export({ format: 'der', type: 'spki' }); + + return certDer.equals(privDer); + } catch { + return false; + } + } + + /** Retorna el KeyObject de Node crypto (para uso avanzado) */ + get keyObject(): crypto.KeyObject { + return this._keyObject; + } +} diff --git a/packages/cfdi/csd/src/index.ts b/packages/cfdi/csd/src/index.ts index 2f925d6c..a7843045 100644 --- a/packages/cfdi/csd/src/index.ts +++ b/packages/cfdi/csd/src/index.ts @@ -1,3 +1,7 @@ import * as cer from './cer'; import * as key from './key'; export { cer, key }; + +export * from './Certificate'; +export * from './PrivateKey'; +export * from './Credential'; diff --git a/packages/cfdi/csd/src/utils/ExcepcionCSD.ts b/packages/cfdi/csd/src/utils/ExcepcionCSD.ts index a6463799..94ff3525 100644 --- a/packages/cfdi/csd/src/utils/ExcepcionCSD.ts +++ b/packages/cfdi/csd/src/utils/ExcepcionCSD.ts @@ -9,7 +9,9 @@ export class ExeptionCSD extends Error { * string * @param {...any} params */ - constructor(foo = 'bar', ...params) { + public foo: string; + public date: Date; + constructor(foo = 'bar', ...params: any[]) { // Pasa los argumentos restantes (incluidos los específicos del proveedor) al constructor padre super(...params); diff --git a/packages/cfdi/csd/test/Certificate.test.ts b/packages/cfdi/csd/test/Certificate.test.ts new file mode 100644 index 00000000..d498dbdc --- /dev/null +++ b/packages/cfdi/csd/test/Certificate.test.ts @@ -0,0 +1,194 @@ +import { describe, expect, it } from 'vitest'; +import { readFileSync } from 'fs'; +import { resolve } from 'path'; +import { Certificate } from '../src/Certificate'; + +const CERTS_DIR = resolve( + __dirname, + '../../../files/certificados' +); +const CSD_CER = resolve(CERTS_DIR, 'LAN7008173R5.cer'); +const CSD_CER_PEM = resolve(CERTS_DIR, 'LAN7008173R5.cer.pem'); + +describe('Certificate', () => { + describe('fromFile (DER)', () => { + it('carga el certificado desde archivo .cer (DER)', async () => { + const cert = await Certificate.fromFile(CSD_CER); + expect(cert).toBeInstanceOf(Certificate); + }); + + it('carga el certificado desde archivo .pem', async () => { + const cert = await Certificate.fromFile(CSD_CER_PEM); + expect(cert).toBeInstanceOf(Certificate); + }); + }); + + describe('fromPem', () => { + it('carga el certificado desde PEM string', () => { + const pem = readFileSync(CSD_CER_PEM, 'ascii'); + const cert = Certificate.fromPem(pem); + expect(cert).toBeInstanceOf(Certificate); + }); + }); + + describe('fromDer', () => { + it('carga el certificado desde buffer DER', () => { + const der = readFileSync(CSD_CER); + const cert = Certificate.fromDer(der); + expect(cert).toBeInstanceOf(Certificate); + }); + }); + + describe('serialNumber', () => { + it('retorna el numero de serie en hex', async () => { + const cert = await Certificate.fromFile(CSD_CER); + const serial = cert.serialNumber(); + expect(serial).toBeTruthy(); + expect(typeof serial).toBe('string'); + }); + }); + + describe('noCertificado', () => { + it('retorna el numero de certificado SAT legible (20 digitos)', async () => { + const cert = await Certificate.fromFile(CSD_CER); + const noCer = cert.noCertificado(); + // El numero de certificado SAT tiene 20 caracteres numericos + expect(noCer).toMatch(/^\d{20}$/); + }); + + it('el numero de certificado coincide en DER y PEM', async () => { + const certDer = await Certificate.fromFile(CSD_CER); + const certPem = await Certificate.fromFile(CSD_CER_PEM); + expect(certDer.noCertificado()).toBe(certPem.noCertificado()); + }); + }); + + describe('rfc', () => { + it('extrae el RFC del subject', async () => { + const cert = await Certificate.fromFile(CSD_CER); + const rfc = cert.rfc(); + expect(rfc).toBeTruthy(); + // RFC persona moral: 12 chars, persona fisica: 13 chars + expect(rfc.length).toBeGreaterThanOrEqual(12); + expect(rfc.length).toBeLessThanOrEqual(13); + }); + + it('el RFC del CSD es LAN7008173R5', async () => { + const cert = await Certificate.fromFile(CSD_CER); + expect(cert.rfc()).toBe('LAN7008173R5'); + }); + }); + + describe('legalName', () => { + it('extrae el nombre legal del subject', async () => { + const cert = await Certificate.fromFile(CSD_CER); + const name = cert.legalName(); + expect(name).toBeTruthy(); + expect(typeof name).toBe('string'); + }); + + it('el nombre legal contiene CINDEMEX', async () => { + const cert = await Certificate.fromFile(CSD_CER); + expect(cert.legalName().toUpperCase()).toContain('CINDEMEX'); + }); + }); + + describe('subject e issuer', () => { + it('retorna subject como objeto', async () => { + const cert = await Certificate.fromFile(CSD_CER); + const sub = cert.subject(); + expect(typeof sub).toBe('object'); + expect(Object.keys(sub).length).toBeGreaterThan(0); + }); + + it('retorna issuer como objeto', async () => { + const cert = await Certificate.fromFile(CSD_CER); + const iss = cert.issuer(); + expect(typeof iss).toBe('object'); + expect(Object.keys(iss).length).toBeGreaterThan(0); + }); + }); + + describe('validFrom / validTo', () => { + it('retorna fecha de inicio de vigencia como Date', async () => { + const cert = await Certificate.fromFile(CSD_CER); + expect(cert.validFrom()).toBeInstanceOf(Date); + }); + + it('retorna fecha de fin de vigencia como Date', async () => { + const cert = await Certificate.fromFile(CSD_CER); + expect(cert.validTo()).toBeInstanceOf(Date); + }); + + it('la fecha de fin es posterior a la de inicio', async () => { + const cert = await Certificate.fromFile(CSD_CER); + expect(cert.validTo().getTime()).toBeGreaterThan(cert.validFrom().getTime()); + }); + }); + + describe('isExpired', () => { + it('el certificado de prueba del SAT esta vencido', async () => { + // El CSD de prueba vence en 2020, por lo que debe estar vencido + const cert = await Certificate.fromFile(CSD_CER); + expect(cert.isExpired()).toBe(true); + }); + }); + + describe('fingerprint', () => { + it('retorna fingerprint SHA-1 en formato XX:XX:XX', async () => { + const cert = await Certificate.fromFile(CSD_CER); + const fp = cert.fingerprint(); + expect(fp).toMatch(/^[0-9A-F]{2}(:[0-9A-F]{2})+$/); + // SHA-1 produce 20 bytes = 40 hex chars = 59 con separadores + expect(fp.length).toBe(59); + }); + + it('fingerprint es consistente entre llamadas', async () => { + const cert = await Certificate.fromFile(CSD_CER); + expect(cert.fingerprint()).toBe(cert.fingerprint()); + }); + }); + + describe('publicKey', () => { + it('retorna la llave publica en PEM', async () => { + const cert = await Certificate.fromFile(CSD_CER); + const pk = cert.publicKey(); + expect(pk).toContain('-----BEGIN PUBLIC KEY-----'); + }); + }); + + describe('isCsd / isFiel', () => { + it('el certificado LAN7008173R5 es CSD', async () => { + const cert = await Certificate.fromFile(CSD_CER); + expect(cert.isCsd()).toBe(true); + }); + + it('isFiel retorna false para un CSD', async () => { + const cert = await Certificate.fromFile(CSD_CER); + expect(cert.isFiel()).toBe(false); + }); + }); + + describe('toPem / toDer', () => { + it('toPem retorna string PEM valido', async () => { + const cert = await Certificate.fromFile(CSD_CER); + const pem = cert.toPem(); + expect(pem).toContain('-----BEGIN CERTIFICATE-----'); + expect(pem).toContain('-----END CERTIFICATE-----'); + }); + + it('toDer retorna Buffer', async () => { + const cert = await Certificate.fromFile(CSD_CER); + const der = cert.toDer(); + expect(der).toBeInstanceOf(Buffer); + expect(der.length).toBeGreaterThan(0); + }); + + it('round-trip DER -> Certificate -> DER produce el mismo contenido', async () => { + const cert1 = await Certificate.fromFile(CSD_CER); + const der1 = cert1.toDer(); + const cert2 = Certificate.fromDer(der1); + expect(cert2.noCertificado()).toBe(cert1.noCertificado()); + }); + }); +}); diff --git a/packages/cfdi/csd/test/Credential.test.ts b/packages/cfdi/csd/test/Credential.test.ts new file mode 100644 index 00000000..debb7fdb --- /dev/null +++ b/packages/cfdi/csd/test/Credential.test.ts @@ -0,0 +1,169 @@ +import { describe, expect, it } from 'vitest'; +import { readFileSync } from 'fs'; +import { resolve } from 'path'; +import { Credential } from '../src/Credential'; + +const CERTS_DIR = resolve( + __dirname, + '../../../files/certificados' +); +const CSD_CER = resolve(CERTS_DIR, 'LAN7008173R5.cer'); +const CSD_KEY = resolve(CERTS_DIR, 'LAN7008173R5.key'); +const CSD_CER_PEM = resolve(CERTS_DIR, 'LAN7008173R5.cer.pem'); +const CSD_KEY_PEM = resolve(CERTS_DIR, 'LAN7008173R5.key.pem'); +const KEY_PASSWORD = '12345678a'; +const RFC_ESPERADO = 'LAN7008173R5'; + +describe('Credential', () => { + describe('create', () => { + it('crea un Credential desde archivos .cer y .key', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred).toBeInstanceOf(Credential); + }); + + it('crea un Credential desde archivos PEM', async () => { + const cred = await Credential.create(CSD_CER_PEM, CSD_KEY_PEM, KEY_PASSWORD); + expect(cred).toBeInstanceOf(Credential); + }); + + it('lanza error con contrasena incorrecta', async () => { + await expect( + Credential.create(CSD_CER, CSD_KEY, 'mal_password') + ).rejects.toThrow(); + }); + }); + + describe('fromPem', () => { + it('crea un Credential desde strings PEM', () => { + const cerPem = readFileSync(CSD_CER_PEM, 'ascii'); + const keyPem = readFileSync(CSD_KEY_PEM, 'ascii'); + const cred = Credential.fromPem(cerPem, keyPem); + expect(cred).toBeInstanceOf(Credential); + }); + }); + + describe('isCsd / isFiel', () => { + it('el Credential con CSD de prueba es CSD', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.isCsd()).toBe(true); + }); + + it('isFiel es false para un CSD', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.isFiel()).toBe(false); + }); + }); + + describe('rfc', () => { + it('retorna el RFC del titular', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.rfc()).toBe(RFC_ESPERADO); + }); + }); + + describe('legalName', () => { + it('retorna el nombre legal del titular', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + const name = cred.legalName(); + expect(name).toBeTruthy(); + expect(name.toUpperCase()).toContain('CINDEMEX'); + }); + }); + + describe('serialNumber / noCertificado', () => { + it('serialNumber retorna el numero de serie hex', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.serialNumber()).toBeTruthy(); + }); + + it('noCertificado retorna 20 digitos', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.noCertificado()).toMatch(/^\d{20}$/); + }); + }); + + describe('sign / verify', () => { + it('firma datos y verifica la firma', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + const data = '||cadena|original|de|prueba||'; + const signature = cred.sign(data); + + expect(typeof signature).toBe('string'); + expect(signature.length).toBeGreaterThan(0); + expect(cred.verify(data, signature)).toBe(true); + }); + + it('verifica firma incorrecta retorna false', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + const data = 'datos originales'; + cred.sign(data); + const firmaFalsa = Buffer.from('firma_falsa').toString('base64'); + expect(cred.verify(data, firmaFalsa)).toBe(false); + }); + + it('firma con datos diferentes no verifica como firma de datos originales', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + const firmaOtrosDatos = cred.sign('datos diferentes'); + expect(cred.verify('datos originales', firmaOtrosDatos)).toBe(false); + }); + + it('firma desde PEM equivale a firma desde DER', async () => { + const credDer = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + const cerPem = readFileSync(CSD_CER_PEM, 'ascii'); + const keyPem = readFileSync(CSD_KEY_PEM, 'ascii'); + const credPem = Credential.fromPem(cerPem, keyPem); + + const data = 'cadena de prueba'; + const sigPem = credPem.sign(data); + + // La firma del PEM debe verificar usando el Credential del DER + expect(credDer.verify(data, sigPem)).toBe(true); + }); + }); + + describe('isValid', () => { + it('el certificado de prueba del SAT esta vencido', async () => { + // El certificado de prueba vence en 2020 + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.isValid()).toBe(false); + }); + }); + + describe('belongsTo', () => { + it('pertenece al RFC correcto', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.belongsTo(RFC_ESPERADO)).toBe(true); + }); + + it('pertenece al RFC en minusculas (case insensitive)', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.belongsTo(RFC_ESPERADO.toLowerCase())).toBe(true); + }); + + it('no pertenece a un RFC diferente', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.belongsTo('XAXX010101000')).toBe(false); + }); + }); + + describe('keyMatchesCertificate', () => { + it('la llave coincide con el certificado', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.keyMatchesCertificate()).toBe(true); + }); + }); + + describe('acceso a certificate y privateKey', () => { + it('expone el certificado', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.certificate).toBeDefined(); + expect(cred.certificate.rfc()).toBe(RFC_ESPERADO); + }); + + it('expone la llave privada', async () => { + const cred = await Credential.create(CSD_CER, CSD_KEY, KEY_PASSWORD); + expect(cred.privateKey).toBeDefined(); + expect(cred.privateKey.toPem()).toContain('-----BEGIN PRIVATE KEY-----'); + }); + }); +}); diff --git a/packages/cfdi/csd/test/PrivateKey.test.ts b/packages/cfdi/csd/test/PrivateKey.test.ts new file mode 100644 index 00000000..1f3bd9ba --- /dev/null +++ b/packages/cfdi/csd/test/PrivateKey.test.ts @@ -0,0 +1,118 @@ +import { describe, expect, it } from 'vitest'; +import { readFileSync } from 'fs'; +import { resolve } from 'path'; +import { PrivateKey } from '../src/PrivateKey'; +import { Certificate } from '../src/Certificate'; + +const CERTS_DIR = resolve( + __dirname, + '../../../files/certificados' +); +const CSD_CER = resolve(CERTS_DIR, 'LAN7008173R5.cer'); +const CSD_KEY = resolve(CERTS_DIR, 'LAN7008173R5.key'); +const CSD_KEY_PEM = resolve(CERTS_DIR, 'LAN7008173R5.key.pem'); +const KEY_PASSWORD = '12345678a'; + +describe('PrivateKey', () => { + describe('fromFile (DER cifrado)', () => { + it('carga la llave privada desde archivo .key con contrasena', async () => { + const key = await PrivateKey.fromFile(CSD_KEY, KEY_PASSWORD); + expect(key).toBeInstanceOf(PrivateKey); + }); + + it('lanza error con contrasena incorrecta', async () => { + await expect( + PrivateKey.fromFile(CSD_KEY, 'contrasena_incorrecta') + ).rejects.toThrow(); + }); + }); + + describe('fromPem', () => { + it('carga la llave privada desde PEM sin cifrado', () => { + const pem = readFileSync(CSD_KEY_PEM, 'ascii'); + const key = PrivateKey.fromPem(pem); + expect(key).toBeInstanceOf(PrivateKey); + }); + }); + + describe('fromDer', () => { + it('carga la llave privada desde buffer DER cifrado', () => { + const der = readFileSync(CSD_KEY); + const key = PrivateKey.fromDer(der, KEY_PASSWORD); + expect(key).toBeInstanceOf(PrivateKey); + }); + }); + + describe('toPem', () => { + it('retorna la llave privada en formato PEM', async () => { + const key = await PrivateKey.fromFile(CSD_KEY, KEY_PASSWORD); + const pem = key.toPem(); + expect(pem).toContain('-----BEGIN PRIVATE KEY-----'); + expect(pem).toContain('-----END PRIVATE KEY-----'); + }); + }); + + describe('sign', () => { + it('firma datos y retorna base64', async () => { + const key = await PrivateKey.fromFile(CSD_KEY, KEY_PASSWORD); + const data = 'cadena original de prueba'; + const signature = key.sign(data); + expect(typeof signature).toBe('string'); + expect(signature.length).toBeGreaterThan(0); + // Base64 valido + expect(() => Buffer.from(signature, 'base64')).not.toThrow(); + }); + + it('firmas de la misma cadena son verificables', async () => { + const keyFile = await PrivateKey.fromFile(CSD_KEY, KEY_PASSWORD); + const cert = await Certificate.fromFile(CSD_CER); + const data = 'datos a firmar'; + const signature = keyFile.sign(data); + + // Verificar con crypto nativo + const crypto = await import('crypto'); + const pubKey = crypto.createPublicKey({ key: cert.publicKey(), format: 'pem' }); + const verifier = crypto.createVerify('RSA-SHA256'); + verifier.update(data, 'utf8'); + expect(verifier.verify(pubKey, signature, 'base64')).toBe(true); + }); + + it('la firma cambia con datos diferentes', async () => { + const key = await PrivateKey.fromFile(CSD_KEY, KEY_PASSWORD); + const sig1 = key.sign('datos 1'); + const sig2 = key.sign('datos 2'); + expect(sig1).not.toBe(sig2); + }); + + it('firma con algoritmo alternativo SHA512', async () => { + const key = await PrivateKey.fromFile(CSD_KEY, KEY_PASSWORD); + const sig = key.sign('datos', 'SHA512'); + expect(typeof sig).toBe('string'); + expect(sig.length).toBeGreaterThan(0); + }); + }); + + describe('belongsToCertificate', () => { + it('la llave pertenece al certificado correspondiente', async () => { + const key = await PrivateKey.fromFile(CSD_KEY, KEY_PASSWORD); + const cert = await Certificate.fromFile(CSD_CER); + expect(key.belongsToCertificate(cert)).toBe(true); + }); + + it('la llave PEM pertenece al certificado correspondiente', () => { + const keyPem = readFileSync(CSD_KEY_PEM, 'ascii'); + const key = PrivateKey.fromPem(keyPem); + const certPem = readFileSync(`${CSD_CER}.pem`, 'ascii'); + const cert = Certificate.fromPem(certPem); + expect(key.belongsToCertificate(cert)).toBe(true); + }); + + it('llave y certificado son consistentes entre DER y PEM', async () => { + const keyDer = await PrivateKey.fromFile(CSD_KEY, KEY_PASSWORD); + const keyPem = PrivateKey.fromPem(readFileSync(CSD_KEY_PEM, 'ascii')); + const cert = await Certificate.fromFile(CSD_CER); + expect(keyDer.belongsToCertificate(cert)).toBe(true); + expect(keyPem.belongsToCertificate(cert)).toBe(true); + }); + }); +}); diff --git a/packages/cfdi/csd/vite.config.mts b/packages/cfdi/csd/vite.config.mts new file mode 100644 index 00000000..f3e8756d --- /dev/null +++ b/packages/cfdi/csd/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['moment', 'node-forge'], + }, + }, +})); diff --git a/packages/cfdi/csf/README.md b/packages/cfdi/csf/README.md index 9487075c..05f2cae2 100644 --- a/packages/cfdi/csf/README.md +++ b/packages/cfdi/csf/README.md @@ -1 +1,57 @@ -utils +# @cfdi/csf + +Extraccion de datos de la Constancia de Situacion Fiscal (CSF) del SAT a partir de un archivo PDF. Parsea el documento y retorna los datos estructurados del contribuyente. + +## Instalacion + +```bash +npm install @cfdi/csf +``` + +## Uso + +```typescript +import { csf } from '@cfdi/csf'; + +// Extraer datos estructurados +const datos = await csf('/ruta/a/constancia.pdf'); +console.log(datos); +// { +// id_cif: '...', +// rfc: 'XAXX010101000', +// curp: 'XAXX010101HDFRRR09', +// nombre: 'NOMBRE', +// primer_apellido: 'APELLIDO', +// segundo_apellido: 'APELLIDO', +// fecha_inicio_de_operaciones: '01/01/2020', +// cp: '06600', +// tipo_de_vialidad: 'CALLE', +// nombre_de_vialidad: '...', +// numero_exterior: '10', +// numero_interior: '', +// nombre_de_la_colonia: '...', +// nombre_de_la_localidad: '...', +// nombre_del_municipio: '...', +// nombre_de_la_entidad_federativa: '...', +// regimen: '...', +// ... +// } + +// Obtener datos crudos del PDF (array de strings) +const datosCrudos = await csf('/ruta/a/constancia.pdf', true); +``` + +## API + +### `csf(constancia, onlyData?)` + +| Parametro | Tipo | Descripcion | +|-----------|------|-------------| +| `constancia` | `string` | Ruta al archivo PDF de la constancia | +| `onlyData` | `boolean` | Si es `true`, retorna el array crudo de textos extraidos. Por defecto `false` | + +**Retorna:** Un objeto con los campos del contribuyente (RFC, CURP, nombre, domicilio, regimen, etc.) o un array de strings si `onlyData` es `true`. + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/csf/package.json b/packages/cfdi/csf/package.json index 161252e6..dabfd703 100644 --- a/packages/cfdi/csf/package.json +++ b/packages/cfdi/csf/package.json @@ -2,32 +2,22 @@ "name": "@cfdi/csf", "version": "4.0.15", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/csf.esm.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "files": [ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "publishConfig": { "registry": "https://registry.npmjs.org/", @@ -37,27 +27,11 @@ "type": "git", "url": "https://github.com/MisaelMa/recreando" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, "author": { "name": "Amir Misael Marin Coh, Signati", "email": "amisael.amir.misae@gmail.com, signatidev@gmail.com,", "url": "" }, - "size-limit": [ - { - "path": "dist/csf.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/csf.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "xml-js": "^1.6.11", "pdf-parse": "^1.1.1" @@ -65,17 +39,10 @@ "devDependencies": { "@recreando/vite": "workspace:*", "@types/pdf-parse": "^1.1.4", - "rimraf": "^6.0.1", "@recreando/eslint-settings": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@types/node": "^18.11.3", + "@types/node": "^22", "eslint": "^8.57.0", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/csf/vite.config.mts b/packages/cfdi/csf/vite.config.mts new file mode 100644 index 00000000..f4ee0581 --- /dev/null +++ b/packages/cfdi/csf/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xml-js', 'pdf-parse'], + }, + }, +})); diff --git a/packages/cfdi/curp/README.md b/packages/cfdi/curp/README.md deleted file mode 100644 index d5693f0d..00000000 --- a/packages/cfdi/curp/README.md +++ /dev/null @@ -1,2 +0,0 @@ -https://github.com/manuelmhtr/validate-curp/blob/main/src/index.js -https://github.com/sanchezcarlosjr/curp diff --git a/packages/cfdi/curp/package.json b/packages/cfdi/curp/package.json deleted file mode 100644 index 06a751fa..00000000 --- a/packages/cfdi/curp/package.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "@cfdi/curp", - "version": "0.0.10-beta.2", - "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/curp.esm.js", - "source": "./src/index.ts", - "files": [ - "dist" - ], - "engines": { - "node": ">=10" - }, - "scripts": { - "start": "tsdx watch", - "build": "tsdx build", - "test": "vitest", - "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "author": "MisaelMa", - "size-limit": [ - { - "path": "dist/utils.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/utils.esm.js", - "limit": "10 KB" - } - ], - "dependencies": { - "2captcha": "^3.0.5", - "axios": "^0.27.2" - }, - "devDependencies": { - "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", - "@recreando/vite": "workspace:*", - "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", - "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", - "typescript": "^5.6.3", - "vitest": "2.1.3", - "vite-tsconfig-paths": "~4.2.1", - "@vitest/coverage-v8": "2.1.3", - "@vitest/ui": "2.1.3" - } -} diff --git a/packages/cfdi/descarga/package.json b/packages/cfdi/descarga/package.json new file mode 100644 index 00000000..1cf195e5 --- /dev/null +++ b/packages/cfdi/descarga/package.json @@ -0,0 +1,35 @@ +{ + "name": "@cfdi/descarga", + "version": "0.0.1", + "license": "MIT", + "main": "src/index.ts", + "module": "src/index.ts", + "types": "src/index.ts", + "source": "src/index.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build --config node_modules/@recreando/vite/vite.config.lib.mts", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/cfdi/descarga/src/DescargaMasiva.ts b/packages/cfdi/descarga/src/DescargaMasiva.ts new file mode 100644 index 00000000..67353099 --- /dev/null +++ b/packages/cfdi/descarga/src/DescargaMasiva.ts @@ -0,0 +1,209 @@ +import type { + CredentialLike, + SatTokenLike, + SolicitudParams, + SolicitudResult, + VerificacionResult, +} from './types'; +import { + buildSolicitarRequest, + parseSolicitarResponse, +} from './soap/solicitar'; +import { + buildVerificarRequest, + parseVerificarResponse, +} from './soap/verificar'; +import { + buildDescargarRequest, + parseDescargarResponse, +} from './soap/descargar'; + +const URL_SOLICITAR = + 'https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/SolicitaDescargaService.svc'; +const URL_VERIFICAR = + 'https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/VerificaSolicitudDescargaService.svc'; +const URL_DESCARGAR = + 'https://cfdidescargamasiva.clouda.sat.gob.mx/DescargaMasivaService.svc'; + +const SOAP_ACTION_SOLICITAR = + 'http://DescargaMasivaTerceros.sat.gob.mx/ISolicitaDescargaService/SolicitaDescarga'; +const SOAP_ACTION_VERIFICAR = + 'http://DescargaMasivaTerceros.sat.gob.mx/IVerificaSolicitudDescargaService/VerificaSolicitudDescarga'; +const SOAP_ACTION_DESCARGAR = + 'http://DescargaMasivaTerceros.sat.gob.mx/IDescargaMasivaTercerosService/Descargar'; + +const TIMEOUT_MS = 60_000; + +/** + * Cliente para el webservice de Descarga Masiva del SAT. + * + * Implementa los 3 pasos del proceso: + * 1. solicitar() - Registra la solicitud y obtiene un IdSolicitud + * 2. verificar() - Consulta el estado y obtiene los IdsPaquetes cuando termina + * 3. descargar() - Descarga el ZIP de cada paquete + * + * El token de autenticacion debe obtenerse previamente con el paquete @sat/auth. + * La credencial FIEL se usa para firmar las peticiones SOAP. + * + * @example + * ```typescript + * const descarga = new DescargaMasiva(token, fiel); + * + * const solicitud = await descarga.solicitar({ + * rfcSolicitante: 'AAA010101AAA', + * fechaInicio: '2024-01-01', + * fechaFin: '2024-01-31', + * tipoSolicitud: TipoSolicitud.CFDI, + * tipoDescarga: TipoDescarga.Emitidos, + * }); + * + * // Esperar a que el SAT procese (puede tardar minutos u horas) + * const verificacion = await descarga.verificar(solicitud.idSolicitud); + * + * if (verificacion.estado === EstadoSolicitud.Terminada) { + * for (const idPaquete of verificacion.idsPaquetes) { + * const zip = await descarga.descargar(idPaquete); + * // Procesar el ZIP... + * } + * } + * ``` + */ +export class DescargaMasiva { + constructor( + private readonly _token: SatTokenLike, + private readonly _credential: CredentialLike + ) {} + + /** + * Paso 1: Solicita una descarga masiva de CFDIs al SAT. + * + * @param params - Parametros de la solicitud (RFC, fechas, tipo, etc.) + * @returns IdSolicitud para consultar el estado con verificar() + */ + async solicitar(params: SolicitudParams): Promise { + const { cert, signatureValue } = this._signComponents( + `SolicitudDescarga-${params.rfcSolicitante}` + ); + const body = buildSolicitarRequest( + params, + this._token.value, + cert, + signatureValue + ); + + const xml = await this._post(URL_SOLICITAR, SOAP_ACTION_SOLICITAR, body); + return parseSolicitarResponse(xml); + } + + /** + * Paso 2: Verifica el estado de una solicitud previa. + * + * Cuando estado === EstadoSolicitud.Terminada (3), la respuesta incluye + * los idsPaquetes listos para descargar. + * + * @param idSolicitud - ID obtenido en solicitar() + */ + async verificar(idSolicitud: string): Promise { + const rfc = this._credential.rfc(); + const { cert, signatureValue } = this._signComponents( + `VerificaSolicitud-${idSolicitud}` + ); + const body = buildVerificarRequest( + idSolicitud, + rfc, + this._token.value, + cert, + signatureValue + ); + + const xml = await this._post(URL_VERIFICAR, SOAP_ACTION_VERIFICAR, body); + return parseVerificarResponse(xml); + } + + /** + * Paso 3: Descarga un paquete ZIP de CFDIs por su ID. + * + * El ZIP contiene los XMLs de los CFDIs de la solicitud. + * + * @param idPaquete - ID del paquete obtenido en verificar() + * @returns Buffer con el contenido del ZIP + */ + async descargar(idPaquete: string): Promise { + const rfc = this._credential.rfc(); + const { cert, signatureValue } = this._signComponents( + `Descarga-${idPaquete}` + ); + const body = buildDescargarRequest( + idPaquete, + rfc, + this._token.value, + cert, + signatureValue + ); + + const xml = await this._post(URL_DESCARGAR, SOAP_ACTION_DESCARGAR, body); + return parseDescargarResponse(xml); + } + + /** + * Genera los componentes de firma (certificado y valor de firma) a partir + * del contenido a firmar y la credencial FIEL. + */ + private _signComponents(content: string): { + cert: string; + signatureValue: string; + } { + const signatureValue = this._credential.sign(content); + const pemCert = this._credential.certificate.toPem(); + const cert = pemCert + .replace(/-----BEGIN CERTIFICATE-----/g, '') + .replace(/-----END CERTIFICATE-----/g, '') + .replace(/\s+/g, ''); + + return { cert, signatureValue }; + } + + /** + * Realiza una peticion HTTP POST SOAP con timeout. + */ + private async _post( + url: string, + soapAction: string, + body: string + ): Promise { + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), TIMEOUT_MS); + + let response: Response; + try { + response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'text/xml; charset=utf-8', + SOAPAction: `"${soapAction}"`, + }, + body, + signal: controller.signal, + }); + } catch (err: unknown) { + if (err instanceof Error && err.name === 'AbortError') { + throw new Error( + `Timeout: el webservice del SAT no respondio en ${TIMEOUT_MS / 1000} segundos` + ); + } + throw new Error( + `Error de red al conectar con el SAT: ${err instanceof Error ? err.message : String(err)}` + ); + } finally { + clearTimeout(timer); + } + + if (!response.ok) { + throw new Error( + `El webservice del SAT retorno HTTP ${response.status}: ${response.statusText}` + ); + } + + return response.text(); + } +} diff --git a/packages/cfdi/descarga/src/index.ts b/packages/cfdi/descarga/src/index.ts new file mode 100644 index 00000000..70da1e70 --- /dev/null +++ b/packages/cfdi/descarga/src/index.ts @@ -0,0 +1,3 @@ +export * from './types'; +export * from './soap'; +export * from './DescargaMasiva'; diff --git a/packages/cfdi/descarga/src/soap/descargar.ts b/packages/cfdi/descarga/src/soap/descargar.ts new file mode 100644 index 00000000..d8049a88 --- /dev/null +++ b/packages/cfdi/descarga/src/soap/descargar.ts @@ -0,0 +1,111 @@ +/** + * Construye el envelope SOAP para descargar un paquete ZIP de CFDIs. + */ +export function buildDescargarRequest( + idPaquete: string, + rfc: string, + token: string, + cert: string, + signatureValue: string +): string { + return ` + + + + + ${token} + + + + + + + + + + + + + + ${signatureValue} + + + ${cert} + + + + + + + + + + + + + + + + + + + + + ${signatureValue} + + + ${cert} + + + + + + +`; +} + +/** + * Extrae el contenido de una etiqueta XML por nombre local (soporta namespaces). + */ +function extractTag(xml: string, localName: string): string { + const pattern = new RegExp( + `<(?:[a-zA-Z0-9_]+:)?${localName}[^>]*>([\\s\\S]*?)<\\/(?:[a-zA-Z0-9_]+:)?${localName}>`, + 'i' + ); + const match = xml.match(pattern); + return match ? match[1].trim() : ''; +} + +/** + * Parsea la respuesta SOAP del servicio DescargaMasiva. + * El paquete ZIP viene codificado en Base64 dentro del elemento Paquete. + * Retorna el contenido binario del ZIP como Buffer. + * + * @param xml - Cuerpo de la respuesta SOAP como string + * @throws Error si la respuesta contiene un SOAP Fault o no hay paquete + */ +export function parseDescargarResponse(xml: string): Buffer { + if (xml.includes('') || xml.includes(':Fault>')) { + const faultString = extractTag(xml, 'faultstring'); + throw new Error( + `SOAP Fault: ${faultString || 'Error desconocido del servicio'}` + ); + } + + const paqueteB64 = + extractTag(xml, 'Paquete') || + extractTag(xml, 'RespuestaDescargaMasivaTercerosSalida'); + + if (!paqueteB64) { + throw new Error( + 'La respuesta del SAT no contiene el elemento Paquete con el ZIP' + ); + } + + return Buffer.from(paqueteB64.replace(/\s+/g, ''), 'base64'); +} diff --git a/packages/cfdi/descarga/src/soap/index.ts b/packages/cfdi/descarga/src/soap/index.ts new file mode 100644 index 00000000..f7d37335 --- /dev/null +++ b/packages/cfdi/descarga/src/soap/index.ts @@ -0,0 +1,4 @@ +export * from './solicitar'; +export * from './verificar'; +export * from './descargar'; +export * from './signer'; diff --git a/packages/cfdi/descarga/src/soap/signer.ts b/packages/cfdi/descarga/src/soap/signer.ts new file mode 100644 index 00000000..1953626c --- /dev/null +++ b/packages/cfdi/descarga/src/soap/signer.ts @@ -0,0 +1,124 @@ +import { createHash } from 'crypto'; +import type { CredentialLike } from '../types'; + +/** + * Canonicaliza de forma simplificada un fragmento XML para su firma. + * El SAT acepta C14N exclusivo; esta implementacion cubre los casos del + * webservice de descarga masiva (atributos en orden de aparicion, sin + * normalizacion de espacios internos). + */ +export function canonicalize(xml: string): string { + // Eliminar la declaracion XML si existe + return xml.replace(/<\?xml[^?]*\?>\s*/g, '').trim(); +} + +/** + * Calcula el digest SHA-256 en Base64 del contenido canonicalizado. + */ +export function digestSha256(content: string): string { + return createHash('sha256').update(content, 'utf8').digest('base64'); +} + +/** + * Estructura con los componentes de firma SOAP necesarios para armar + * el header de seguridad WS-Security. + */ +export interface SoapSignatureComponents { + /** Digest Base64 del body canonicalizado */ + bodyDigest: string; + /** Firma RSA-SHA256 Base64 del SignedInfo canonicalizado */ + signatureValue: string; + /** Certificado X.509 en Base64 DER (sin encabezados PEM) */ + x509Certificate: string; + /** ID del body para referencia en SignedInfo */ + bodyId: string; +} + +/** + * Genera todos los componentes criptograficos necesarios para firmar + * un mensaje SOAP con WS-Security usando la FIEL. + * + * El patron es: + * 1. Calcular digest SHA-256 del body + * 2. Construir el SignedInfo con la referencia al body + * 3. Firmar el SignedInfo con RSA-SHA256 usando la llave privada de la FIEL + * + * @param bodyXml - Contenido XML del body SOAP (sin el elemento Body en si) + * @param credential - Credencial FIEL con metodos sign() y certificate + * @param bodyId - ID a asignar al body para la referencia (default: "_0") + */ +export function signSoapBody( + bodyXml: string, + credential: CredentialLike, + bodyId = '_0' +): SoapSignatureComponents { + const canonBody = canonicalize(bodyXml); + const bodyDigest = digestSha256(canonBody); + + const signedInfo = buildSignedInfo(bodyDigest, bodyId); + const canonSignedInfo = canonicalize(signedInfo); + const signatureValue = credential.sign(canonSignedInfo); + + const pemCert = credential.certificate.toPem(); + const x509Certificate = pemCert + .replace(/-----BEGIN CERTIFICATE-----/g, '') + .replace(/-----END CERTIFICATE-----/g, '') + .replace(/\s+/g, ''); + + return { + bodyDigest, + signatureValue, + x509Certificate, + bodyId, + }; +} + +/** + * Construye el elemento SignedInfo para WS-Security. + * Referencia al body SOAP identificado por bodyId. + */ +function buildSignedInfo(bodyDigest: string, bodyId: string): string { + return `` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + `${bodyDigest}` + + `` + + ``; +} + +/** + * Construye el header WS-Security completo con la firma y el certificado. + */ +export function buildSecurityHeader( + components: SoapSignatureComponents, + tokenValue: string +): string { + const { bodyDigest, signatureValue, x509Certificate, bodyId } = components; + const signedInfo = buildSignedInfo(bodyDigest, bodyId); + + return ` + + + ${tokenValue} + + + ${signedInfo} + ${signatureValue} + + + + ${x509Certificate.substring(0, 40)} + + + + + +`; +} diff --git a/packages/cfdi/descarga/src/soap/solicitar.ts b/packages/cfdi/descarga/src/soap/solicitar.ts new file mode 100644 index 00000000..0accf930 --- /dev/null +++ b/packages/cfdi/descarga/src/soap/solicitar.ts @@ -0,0 +1,162 @@ +import type { SolicitudParams, SolicitudResult } from '../types'; + +const NS_DM_SOLICITUD = + 'http://DescargaMasivaTerceros.sat.gob.mx/'; + +/** + * Construye el envelope SOAP para solicitar una descarga masiva. + * + * La firma digital y el token de autenticacion se incluyen en el header + * como Security WS-Security. El body contiene los parametros de la solicitud + * firmados por la FIEL del solicitante. + */ +export function buildSolicitarRequest( + params: SolicitudParams, + token: string, + cert: string, + signatureValue: string +): string { + const { + rfcSolicitante, + fechaInicio, + fechaFin, + tipoSolicitud, + tipoDescarga, + rfcEmisor, + rfcReceptor, + } = params; + + // Construir el atributo de filtro segun el tipo de descarga + const filtroAttr = + tipoDescarga === 'RfcEmisor' + ? `RfcEmisor="${rfcEmisor ?? rfcSolicitante}"` + : `RfcReceptor="${rfcReceptor ?? rfcSolicitante}"`; + + return ` + + + + + ${token} + + + + + + + + + + + + + + ${signatureValue} + + + ${cert} + + + + + + + + + + + + + + + + + + + + + ${signatureValue} + + + ${cert} + + + + + + +`; +} + +/** + * Extrae el contenido de una etiqueta XML por nombre local (soporta namespaces). + */ +function extractTag(xml: string, localName: string): string { + const pattern = new RegExp( + `<(?:[a-zA-Z0-9_]+:)?${localName}[^>]*>([\\s\\S]*?)<\\/(?:[a-zA-Z0-9_]+:)?${localName}>`, + 'i' + ); + const match = xml.match(pattern); + return match ? match[1].trim() : ''; +} + +/** + * Extrae la etiqueta de apertura completa (incluyendo atributos) de un + * elemento XML por nombre local. Soporta elementos de auto-cierre. + */ +function extractOpeningTag(xml: string, localName: string): string { + const pattern = new RegExp( + `<(?:[a-zA-Z0-9_]+:)?${localName}((?:\\s+[^>]*)?)(?:\\/>|>)`, + 'i' + ); + const match = xml.match(pattern); + return match ? match[0] : ''; +} + +/** + * Extrae el valor de un atributo XML por nombre. + */ +function extractAttr(xml: string, attrName: string): string { + const pattern = new RegExp(`${attrName}="([^"]*)"`, 'i'); + const match = xml.match(pattern); + return match ? match[1] : ''; +} + +/** + * Parsea la respuesta SOAP del servicio SolicitaDescarga. + * Lanza Error si la respuesta contiene un SOAP Fault. + */ +export function parseSolicitarResponse(xml: string): SolicitudResult { + if (xml.includes('') || xml.includes(':Fault>')) { + const faultString = extractTag(xml, 'faultstring'); + throw new Error( + `SOAP Fault: ${faultString || 'Error desconocido del servicio'}` + ); + } + + // Los atributos estan en el elemento de apertura (puede ser auto-cerrado />) + const openingTag = + extractOpeningTag(xml, 'SolicitaDescargaResult') || + extractOpeningTag( + xml, + 'RespuestaSolicitudDescMasivaTercerosSolicitud' + ); + + const context = openingTag || xml; + + const idSolicitud = extractAttr(context, 'IdSolicitud'); + const codEstatus = extractAttr(context, 'CodEstatus'); + const mensaje = extractAttr(context, 'Mensaje'); + + return { idSolicitud, codEstatus, mensaje }; +} + +export { NS_DM_SOLICITUD }; diff --git a/packages/cfdi/descarga/src/soap/verificar.ts b/packages/cfdi/descarga/src/soap/verificar.ts new file mode 100644 index 00000000..26b7aded --- /dev/null +++ b/packages/cfdi/descarga/src/soap/verificar.ts @@ -0,0 +1,165 @@ +import { EstadoSolicitud, ESTADO_DESCRIPCION } from '../types'; +import type { VerificacionResult } from '../types'; + +/** + * Construye el envelope SOAP para verificar el estado de una solicitud de + * descarga masiva. + */ +export function buildVerificarRequest( + idSolicitud: string, + rfc: string, + token: string, + cert: string, + signatureValue: string +): string { + return ` + + + + + ${token} + + + + + + + + + + + + + + ${signatureValue} + + + ${cert} + + + + + + + + + + + + + + + + + + + + + ${signatureValue} + + + ${cert} + + + + + + +`; +} + +/** + * Extrae el contenido de una etiqueta XML por nombre local (soporta namespaces). + */ +function extractTag(xml: string, localName: string): string { + const pattern = new RegExp( + `<(?:[a-zA-Z0-9_]+:)?${localName}[^>]*>([\\s\\S]*?)<\\/(?:[a-zA-Z0-9_]+:)?${localName}>`, + 'i' + ); + const match = xml.match(pattern); + return match ? match[1].trim() : ''; +} + +/** + * Extrae la etiqueta de apertura completa (incluyendo atributos) de un + * elemento XML por nombre local. + */ +function extractOpeningTag(xml: string, localName: string): string { + const pattern = new RegExp( + `<(?:[a-zA-Z0-9_]+:)?${localName}((?:\\s+[^>]*)?)(?:\\/?>|>)`, + 'i' + ); + const match = xml.match(pattern); + return match ? match[0] : ''; +} + +/** + * Extrae el valor de un atributo XML por nombre, buscando en el XML completo. + */ +function extractAttr(xml: string, attrName: string): string { + const pattern = new RegExp(`${attrName}="([^"]*)"`, 'i'); + const match = xml.match(pattern); + return match ? match[1] : ''; +} + +/** + * Extrae todos los valores de elementos repetidos (IdsPaquetes). + */ +function extractAllTags(xml: string, localName: string): string[] { + const pattern = new RegExp( + `<(?:[a-zA-Z0-9_]+:)?${localName}[^>]*>([\\s\\S]*?)<\\/(?:[a-zA-Z0-9_]+:)?${localName}>`, + 'gi' + ); + const results: string[] = []; + let match: RegExpExecArray | null; + while ((match = pattern.exec(xml)) !== null) { + const value = match[1].trim(); + if (value) results.push(value); + } + return results; +} + +/** + * Parsea la respuesta SOAP del servicio VerificaSolicitudDescarga. + * Lanza Error si la respuesta contiene un SOAP Fault. + */ +export function parseVerificarResponse(xml: string): VerificacionResult { + if (xml.includes('') || xml.includes(':Fault>')) { + const faultString = extractTag(xml, 'faultstring'); + throw new Error( + `SOAP Fault: ${faultString || 'Error desconocido del servicio'}` + ); + } + + // Los atributos del resultado estan en la etiqueta de apertura del elemento + const openingTag = + extractOpeningTag(xml, 'VerificaSolicitudDescargaResult') || + extractOpeningTag(xml, 'RespuestaVerificaSolicitudDescMasivaTercerosSolicitud'); + + const codEstatus = extractAttr(openingTag || xml, 'CodEstatus'); + const mensaje = extractAttr(openingTag || xml, 'Mensaje'); + const estadoRaw = extractAttr(openingTag || xml, 'EstadoSolicitud'); + const numeroCfdisRaw = extractAttr(openingTag || xml, 'NumeroCFDIs'); + + // Los IdsPaquetes pueden estar como elementos hijos + const idsPaquetes = extractAllTags(xml, 'IdsPaquetes'); + + const estadoNum = parseInt(estadoRaw, 10) as EstadoSolicitud; + const estado = Object.values(EstadoSolicitud).includes(estadoNum) + ? estadoNum + : EstadoSolicitud.Error; + + return { + estado, + estadoDescripcion: ESTADO_DESCRIPCION[estado] ?? 'Desconocido', + codEstatus, + mensaje, + idsPaquetes, + numeroCfdis: parseInt(numeroCfdisRaw, 10) || 0, + }; +} diff --git a/packages/cfdi/descarga/src/types.ts b/packages/cfdi/descarga/src/types.ts new file mode 100644 index 00000000..8d8c6a8a --- /dev/null +++ b/packages/cfdi/descarga/src/types.ts @@ -0,0 +1,77 @@ +export enum TipoSolicitud { + CFDI = 'CFDI', + Metadata = 'Metadata', +} + +export enum TipoDescarga { + Emitidos = 'RfcEmisor', + Recibidos = 'RfcReceptor', +} + +export enum EstadoSolicitud { + Aceptada = 1, + EnProceso = 2, + Terminada = 3, + Error = 4, + Rechazada = 5, + Vencida = 6, +} + +export interface SolicitudParams { + rfcSolicitante: string; + /** Fecha en formato YYYY-MM-DD */ + fechaInicio: string; + /** Fecha en formato YYYY-MM-DD */ + fechaFin: string; + tipoSolicitud: TipoSolicitud; + tipoDescarga: TipoDescarga; + /** RFC emisor para filtrar (opcional) */ + rfcEmisor?: string; + /** RFC receptor para filtrar (opcional) */ + rfcReceptor?: string; +} + +export interface SolicitudResult { + idSolicitud: string; + codEstatus: string; + mensaje: string; +} + +export interface VerificacionResult { + estado: EstadoSolicitud; + estadoDescripcion: string; + codEstatus: string; + mensaje: string; + idsPaquetes: string[]; + numeroCfdis: number; +} + +/** + * Duck type para el certificado/credencial FIEL. + * Compatible con las clases del paquete @cfdi/csd sin importarlo directamente. + */ +export interface CredentialLike { + certificate: { toDer(): Buffer; toPem(): string }; + sign(data: string): string; + rfc(): string; +} + +/** + * Duck type para el token SAT. + * Compatible con el resultado de @sat/auth sin importarlo directamente. + */ +export interface SatTokenLike { + value: string; + created: Date; + expires: Date; +} + +/** Descripcion textual del estado de solicitud */ +export const ESTADO_DESCRIPCION: Record = { + [EstadoSolicitud.Aceptada]: 'Aceptada', + [EstadoSolicitud.EnProceso]: 'En proceso', + [EstadoSolicitud.Terminada]: 'Terminada', + [EstadoSolicitud.Error]: 'Error', + [EstadoSolicitud.Rechazada]: 'Rechazada', + [EstadoSolicitud.Vencida]: 'Vencida', +}; diff --git a/packages/cfdi/descarga/test/descarga.test.ts b/packages/cfdi/descarga/test/descarga.test.ts new file mode 100644 index 00000000..6a661da8 --- /dev/null +++ b/packages/cfdi/descarga/test/descarga.test.ts @@ -0,0 +1,491 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { DescargaMasiva } from '../src/DescargaMasiva'; +import { + TipoSolicitud, + TipoDescarga, + EstadoSolicitud, + type SatTokenLike, + type CredentialLike, +} from '../src/types'; + +// --------------------------------------------------------------------------- +// Fixtures y mocks de infraestructura +// --------------------------------------------------------------------------- +const RFC = 'AAA010101AAA'; +const ID_SOLICITUD = 'a3d08a33-d0d8-4f36-a857-ab4b2a5edc7c'; +const ID_PAQUETE = 'a3d08a33-d0d8-4f36-a857-ab4b2a5edc7c_01'; + +const SOLICITUD_PARAMS = { + rfcSolicitante: RFC, + fechaInicio: '2024-01-01', + fechaFin: '2024-01-31', + tipoSolicitud: TipoSolicitud.CFDI, + tipoDescarga: TipoDescarga.Emitidos, +}; + +/** Token SAT de prueba */ +const mockToken: SatTokenLike = { + value: '2024-01-01T00:00:00Z', + created: new Date('2024-01-01T00:00:00Z'), + expires: new Date('2024-01-01T00:08:00Z'), +}; + +/** Certificado fake en PEM */ +const FAKE_PEM = + '-----BEGIN CERTIFICATE-----\nMIIFbase64certdataABCDEFGHIJ==\n-----END CERTIFICATE-----'; + +/** Credencial FIEL de prueba (duck type) */ +const mockCredential: CredentialLike = { + certificate: { + toDer: () => Buffer.from('fakecert'), + toPem: () => FAKE_PEM, + }, + sign: (_data: string) => 'base64signaturevalue==', + rfc: () => RFC, +}; + +// --------------------------------------------------------------------------- +// Responses SOAP de prueba +// --------------------------------------------------------------------------- +const RESPONSE_SOLICITAR_OK = ` + + + + + + +`; + +const RESPONSE_VERIFICAR_TERMINADA = ` + + + + + ${ID_PAQUETE} + + + +`; + +const RESPONSE_VERIFICAR_EN_PROCESO = ` + + + + + + +`; + +const ZIP_CONTENT = Buffer.from('PK\x03\x04fake zip content for testing'); +const ZIP_B64 = ZIP_CONTENT.toString('base64'); + +const RESPONSE_DESCARGAR_OK = ` + + + + ${ZIP_B64} + + +`; + +// --------------------------------------------------------------------------- +// Helpers de mock fetch +// --------------------------------------------------------------------------- +function mockFetchOk(body: string, status = 200) { + return vi.fn().mockResolvedValue({ + ok: status >= 200 && status < 300, + status, + statusText: status === 200 ? 'OK' : 'Internal Server Error', + text: () => Promise.resolve(body), + }); +} + +// --------------------------------------------------------------------------- +// Tests de DescargaMasiva +// --------------------------------------------------------------------------- +describe('DescargaMasiva', () => { + let descarga: DescargaMasiva; + + beforeEach(() => { + descarga = new DescargaMasiva(mockToken, mockCredential); + vi.stubGlobal('fetch', undefined); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + // ------------------------------------------------------------------------- + // solicitar() + // ------------------------------------------------------------------------- + describe('solicitar()', () => { + it('retorna el idSolicitud cuando la respuesta es exitosa', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_SOLICITAR_OK)); + + const result = await descarga.solicitar(SOLICITUD_PARAMS); + + expect(result.idSolicitud).toBe(ID_SOLICITUD); + }); + + it('retorna el codEstatus de la respuesta', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_SOLICITAR_OK)); + + const result = await descarga.solicitar(SOLICITUD_PARAMS); + + expect(result.codEstatus).toBe('5000'); + }); + + it('retorna el mensaje de la respuesta', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_SOLICITAR_OK)); + + const result = await descarga.solicitar(SOLICITUD_PARAMS); + + expect(result.mensaje).toBe('Solicitud Aceptada'); + }); + + it('llama a fetch con POST a la URL de solicitar', async () => { + const fetchMock = mockFetchOk(RESPONSE_SOLICITAR_OK); + vi.stubGlobal('fetch', fetchMock); + + await descarga.solicitar(SOLICITUD_PARAMS); + + expect(fetchMock).toHaveBeenCalledOnce(); + const [url] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect(url).toBe( + 'https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/SolicitaDescargaService.svc' + ); + }); + + it('envia el Content-Type text/xml en la peticion', async () => { + const fetchMock = mockFetchOk(RESPONSE_SOLICITAR_OK); + vi.stubGlobal('fetch', fetchMock); + + await descarga.solicitar(SOLICITUD_PARAMS); + + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect( + (options.headers as Record)['Content-Type'] + ).toContain('text/xml'); + }); + + it('envia el SOAPAction correcto', async () => { + const fetchMock = mockFetchOk(RESPONSE_SOLICITAR_OK); + vi.stubGlobal('fetch', fetchMock); + + await descarga.solicitar(SOLICITUD_PARAMS); + + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect( + (options.headers as Record)['SOAPAction'] + ).toContain('SolicitaDescarga'); + }); + + it('el body contiene el RFC solicitante', async () => { + const fetchMock = mockFetchOk(RESPONSE_SOLICITAR_OK); + vi.stubGlobal('fetch', fetchMock); + + await descarga.solicitar(SOLICITUD_PARAMS); + + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect(options.body as string).toContain(RFC); + }); + + it('el body contiene la fecha de inicio', async () => { + const fetchMock = mockFetchOk(RESPONSE_SOLICITAR_OK); + vi.stubGlobal('fetch', fetchMock); + + await descarga.solicitar(SOLICITUD_PARAMS); + + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect(options.body as string).toContain('2024-01-01'); + }); + + it('lanza error cuando HTTP retorna status de error', async () => { + vi.stubGlobal('fetch', mockFetchOk('Error', 500)); + + await expect(descarga.solicitar(SOLICITUD_PARAMS)).rejects.toThrow( + 'HTTP 500' + ); + }); + + it('lanza error cuando hay un error de red', async () => { + vi.stubGlobal( + 'fetch', + vi.fn().mockRejectedValue(new Error('ECONNREFUSED')) + ); + + await expect(descarga.solicitar(SOLICITUD_PARAMS)).rejects.toThrow( + 'Error de red' + ); + }); + + it('lanza error de timeout cuando fetch es abortado', async () => { + const abortError = new Error('The operation was aborted'); + abortError.name = 'AbortError'; + vi.stubGlobal('fetch', vi.fn().mockRejectedValue(abortError)); + + await expect(descarga.solicitar(SOLICITUD_PARAMS)).rejects.toThrow( + 'Timeout' + ); + }); + }); + + // ------------------------------------------------------------------------- + // verificar() + // ------------------------------------------------------------------------- + describe('verificar()', () => { + it('retorna estado Terminada (3) cuando la solicitud esta lista', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_VERIFICAR_TERMINADA)); + + const result = await descarga.verificar(ID_SOLICITUD); + + expect(result.estado).toBe(EstadoSolicitud.Terminada); + }); + + it('retorna la descripcion del estado', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_VERIFICAR_TERMINADA)); + + const result = await descarga.verificar(ID_SOLICITUD); + + expect(result.estadoDescripcion).toBe('Terminada'); + }); + + it('retorna los idsPaquetes cuando la solicitud esta terminada', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_VERIFICAR_TERMINADA)); + + const result = await descarga.verificar(ID_SOLICITUD); + + expect(result.idsPaquetes).toContain(ID_PAQUETE); + }); + + it('retorna el numero de CFDIs', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_VERIFICAR_TERMINADA)); + + const result = await descarga.verificar(ID_SOLICITUD); + + expect(result.numeroCfdis).toBe(50); + }); + + it('retorna estado EnProceso (2) cuando todavia procesa', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_VERIFICAR_EN_PROCESO)); + + const result = await descarga.verificar(ID_SOLICITUD); + + expect(result.estado).toBe(EstadoSolicitud.EnProceso); + }); + + it('retorna lista vacia de paquetes cuando esta en proceso', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_VERIFICAR_EN_PROCESO)); + + const result = await descarga.verificar(ID_SOLICITUD); + + expect(result.idsPaquetes).toHaveLength(0); + }); + + it('llama a fetch con POST a la URL de verificar', async () => { + const fetchMock = mockFetchOk(RESPONSE_VERIFICAR_TERMINADA); + vi.stubGlobal('fetch', fetchMock); + + await descarga.verificar(ID_SOLICITUD); + + const [url] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect(url).toBe( + 'https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/VerificaSolicitudDescargaService.svc' + ); + }); + + it('el body contiene el IdSolicitud', async () => { + const fetchMock = mockFetchOk(RESPONSE_VERIFICAR_TERMINADA); + vi.stubGlobal('fetch', fetchMock); + + await descarga.verificar(ID_SOLICITUD); + + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect(options.body as string).toContain(ID_SOLICITUD); + }); + + it('lanza error cuando HTTP retorna status de error', async () => { + vi.stubGlobal('fetch', mockFetchOk('Error', 500)); + + await expect(descarga.verificar(ID_SOLICITUD)).rejects.toThrow('HTTP 500'); + }); + }); + + // ------------------------------------------------------------------------- + // descargar() + // ------------------------------------------------------------------------- + describe('descargar()', () => { + it('retorna el ZIP como Buffer', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_DESCARGAR_OK)); + + const result = await descarga.descargar(ID_PAQUETE); + + expect(Buffer.isBuffer(result)).toBe(true); + }); + + it('el Buffer contiene el contenido correcto del ZIP', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_DESCARGAR_OK)); + + const result = await descarga.descargar(ID_PAQUETE); + + expect(result).toEqual(ZIP_CONTENT); + }); + + it('llama a fetch con POST a la URL de descargar', async () => { + const fetchMock = mockFetchOk(RESPONSE_DESCARGAR_OK); + vi.stubGlobal('fetch', fetchMock); + + await descarga.descargar(ID_PAQUETE); + + const [url] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect(url).toBe( + 'https://cfdidescargamasiva.clouda.sat.gob.mx/DescargaMasivaService.svc' + ); + }); + + it('el body contiene el IdPaquete', async () => { + const fetchMock = mockFetchOk(RESPONSE_DESCARGAR_OK); + vi.stubGlobal('fetch', fetchMock); + + await descarga.descargar(ID_PAQUETE); + + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect(options.body as string).toContain(ID_PAQUETE); + }); + + it('envia el SOAPAction correcto para descarga', async () => { + const fetchMock = mockFetchOk(RESPONSE_DESCARGAR_OK); + vi.stubGlobal('fetch', fetchMock); + + await descarga.descargar(ID_PAQUETE); + + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect( + (options.headers as Record)['SOAPAction'] + ).toContain('Descargar'); + }); + + it('lanza error cuando HTTP retorna status de error', async () => { + vi.stubGlobal('fetch', mockFetchOk('Error', 500)); + + await expect(descarga.descargar(ID_PAQUETE)).rejects.toThrow('HTTP 500'); + }); + }); + + // ------------------------------------------------------------------------- + // Flujo completo (los 3 pasos) + // ------------------------------------------------------------------------- + describe('flujo completo de descarga masiva', () => { + it('ejecuta los 3 pasos en orden y retorna el ZIP', async () => { + const fetchMock = vi + .fn() + .mockResolvedValueOnce({ + ok: true, + status: 200, + statusText: 'OK', + text: () => Promise.resolve(RESPONSE_SOLICITAR_OK), + }) + .mockResolvedValueOnce({ + ok: true, + status: 200, + statusText: 'OK', + text: () => Promise.resolve(RESPONSE_VERIFICAR_TERMINADA), + }) + .mockResolvedValueOnce({ + ok: true, + status: 200, + statusText: 'OK', + text: () => Promise.resolve(RESPONSE_DESCARGAR_OK), + }); + + vi.stubGlobal('fetch', fetchMock); + + const solicitud = await descarga.solicitar(SOLICITUD_PARAMS); + expect(solicitud.idSolicitud).toBe(ID_SOLICITUD); + + const verificacion = await descarga.verificar(solicitud.idSolicitud); + expect(verificacion.estado).toBe(EstadoSolicitud.Terminada); + expect(verificacion.idsPaquetes).toHaveLength(1); + + const zip = await descarga.descargar(verificacion.idsPaquetes[0]); + expect(Buffer.isBuffer(zip)).toBe(true); + expect(zip).toEqual(ZIP_CONTENT); + + expect(fetchMock).toHaveBeenCalledTimes(3); + }); + + it('las 3 llamadas van a URLs diferentes del SAT', async () => { + const fetchMock = vi + .fn() + .mockResolvedValueOnce({ + ok: true, + status: 200, + statusText: 'OK', + text: () => Promise.resolve(RESPONSE_SOLICITAR_OK), + }) + .mockResolvedValueOnce({ + ok: true, + status: 200, + statusText: 'OK', + text: () => Promise.resolve(RESPONSE_VERIFICAR_TERMINADA), + }) + .mockResolvedValueOnce({ + ok: true, + status: 200, + statusText: 'OK', + text: () => Promise.resolve(RESPONSE_DESCARGAR_OK), + }); + + vi.stubGlobal('fetch', fetchMock); + + await descarga.solicitar(SOLICITUD_PARAMS); + await descarga.verificar(ID_SOLICITUD); + await descarga.descargar(ID_PAQUETE); + + const urls = fetchMock.mock.calls.map( + (call: [string, RequestInit]) => call[0] + ); + + expect(urls[0]).toContain('SolicitaDescargaService.svc'); + expect(urls[1]).toContain('VerificaSolicitudDescargaService.svc'); + expect(urls[2]).toContain('DescargaMasivaService.svc'); + }); + }); +}); + +// --------------------------------------------------------------------------- +// Tests de EstadoSolicitud enum +// --------------------------------------------------------------------------- +describe('EstadoSolicitud', () => { + it('Aceptada tiene valor 1', () => { + expect(EstadoSolicitud.Aceptada).toBe(1); + }); + + it('EnProceso tiene valor 2', () => { + expect(EstadoSolicitud.EnProceso).toBe(2); + }); + + it('Terminada tiene valor 3', () => { + expect(EstadoSolicitud.Terminada).toBe(3); + }); + + it('Error tiene valor 4', () => { + expect(EstadoSolicitud.Error).toBe(4); + }); + + it('Rechazada tiene valor 5', () => { + expect(EstadoSolicitud.Rechazada).toBe(5); + }); + + it('Vencida tiene valor 6', () => { + expect(EstadoSolicitud.Vencida).toBe(6); + }); +}); diff --git a/packages/cfdi/descarga/test/soap.test.ts b/packages/cfdi/descarga/test/soap.test.ts new file mode 100644 index 00000000..4c76b951 --- /dev/null +++ b/packages/cfdi/descarga/test/soap.test.ts @@ -0,0 +1,577 @@ +import { describe, it, expect } from 'vitest'; +import { + buildSolicitarRequest, + parseSolicitarResponse, +} from '../src/soap/solicitar'; +import { + buildVerificarRequest, + parseVerificarResponse, +} from '../src/soap/verificar'; +import { + buildDescargarRequest, + parseDescargarResponse, +} from '../src/soap/descargar'; +import { digestSha256, canonicalize } from '../src/soap/signer'; +import { TipoSolicitud, TipoDescarga, EstadoSolicitud } from '../src/types'; + +// --------------------------------------------------------------------------- +// Fixtures +// --------------------------------------------------------------------------- +const RFC = 'AAA010101AAA'; +const TOKEN = '2024-01-01T00:00:00Z'; +const CERT = 'MIIFbase64certdata=='; +const SIGNATURE = 'base64signaturevalue=='; +const ID_SOLICITUD = 'a3d08a33-d0d8-4f36-a857-ab4b2a5edc7c'; +const ID_PAQUETE = 'a3d08a33-d0d8-4f36-a857-ab4b2a5edc7c_01'; + +const SOLICITUD_PARAMS = { + rfcSolicitante: RFC, + fechaInicio: '2024-01-01', + fechaFin: '2024-01-31', + tipoSolicitud: TipoSolicitud.CFDI, + tipoDescarga: TipoDescarga.Emitidos, +}; + +// --------------------------------------------------------------------------- +// Signer helpers +// --------------------------------------------------------------------------- +describe('canonicalize', () => { + it('elimina la declaracion XML', () => { + const result = canonicalize( + '' + ); + expect(result).toBe(''); + }); + + it('retorna el mismo string si no tiene declaracion XML', () => { + const result = canonicalize(''); + expect(result).toBe(''); + }); + + it('elimina espacios al inicio y final', () => { + const result = canonicalize(' '); + expect(result).toBe(''); + }); +}); + +describe('digestSha256', () => { + it('retorna un string Base64 valido', () => { + const digest = digestSha256('hola mundo'); + expect(digest).toMatch(/^[A-Za-z0-9+/]+=*$/); + expect(digest.length).toBeGreaterThan(20); + }); + + it('produce el mismo digest para la misma entrada', () => { + const a = digestSha256('contenido de prueba'); + const b = digestSha256('contenido de prueba'); + expect(a).toBe(b); + }); + + it('produce digests diferentes para entradas diferentes', () => { + const a = digestSha256('contenido A'); + const b = digestSha256('contenido B'); + expect(a).not.toBe(b); + }); +}); + +// --------------------------------------------------------------------------- +// buildSolicitarRequest +// --------------------------------------------------------------------------- +describe('buildSolicitarRequest', () => { + it('genera un envelope SOAP valido con los namespaces correctos', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain('xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"'); + expect(xml).toContain('xmlns:des="http://DescargaMasivaTerceros.sat.gob.mx/"'); + expect(xml).toContain('s:Envelope'); + expect(xml).toContain('s:Body'); + }); + + it('incluye el elemento SolicitaDescarga', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain('des:SolicitaDescarga'); + expect(xml).toContain('des:solicitud'); + }); + + it('incluye la fecha inicial en formato ISO', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain('FechaInicial="2024-01-01T00:00:00"'); + }); + + it('incluye la fecha final en formato ISO', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain('FechaFinal="2024-01-31T23:59:59"'); + }); + + it('incluye el RFC solicitante', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(`RfcSolicitante="${RFC}"`); + }); + + it('incluye el tipo de solicitud CFDI', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain('TipoSolicitud="CFDI"'); + }); + + it('incluye el tipo de solicitud Metadata cuando se especifica', () => { + const xml = buildSolicitarRequest( + { ...SOLICITUD_PARAMS, tipoSolicitud: TipoSolicitud.Metadata }, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain('TipoSolicitud="Metadata"'); + }); + + it('incluye RfcEmisor para descarga de emitidos', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(`RfcEmisor="${RFC}"`); + }); + + it('incluye RfcReceptor para descarga de recibidos', () => { + const xml = buildSolicitarRequest( + { + ...SOLICITUD_PARAMS, + tipoDescarga: TipoDescarga.Recibidos, + rfcReceptor: 'BBB020202BBB', + }, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain('RfcReceptor="BBB020202BBB"'); + }); + + it('incluye el certificado en el header de seguridad', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(CERT); + }); + + it('incluye el valor de firma', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(SIGNATURE); + }); + + it('incluye el token en el timestamp del header', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(TOKEN); + }); + + it('incluye los algoritmos de firma RSA-SHA256', () => { + const xml = buildSolicitarRequest( + SOLICITUD_PARAMS, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain( + 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' + ); + }); +}); + +// --------------------------------------------------------------------------- +// parseSolicitarResponse +// --------------------------------------------------------------------------- +const RESPONSE_SOLICITAR_OK = ` + + + + + + +`; + +const RESPONSE_SOLICITAR_FAULT = ` + + + + s:Client + RFC no valido + + +`; + +describe('parseSolicitarResponse', () => { + it('extrae el IdSolicitud de la respuesta exitosa', () => { + const result = parseSolicitarResponse(RESPONSE_SOLICITAR_OK); + expect(result.idSolicitud).toBe(ID_SOLICITUD); + }); + + it('extrae el CodEstatus de la respuesta exitosa', () => { + const result = parseSolicitarResponse(RESPONSE_SOLICITAR_OK); + expect(result.codEstatus).toBe('5000'); + }); + + it('extrae el Mensaje de la respuesta exitosa', () => { + const result = parseSolicitarResponse(RESPONSE_SOLICITAR_OK); + expect(result.mensaje).toBe('Solicitud Aceptada'); + }); + + it('lanza Error cuando la respuesta contiene un SOAP Fault', () => { + expect(() => parseSolicitarResponse(RESPONSE_SOLICITAR_FAULT)).toThrow( + 'SOAP Fault' + ); + }); + + it('incluye el mensaje del SOAP Fault en el error', () => { + expect(() => parseSolicitarResponse(RESPONSE_SOLICITAR_FAULT)).toThrow( + 'RFC no valido' + ); + }); +}); + +// --------------------------------------------------------------------------- +// buildVerificarRequest +// --------------------------------------------------------------------------- +describe('buildVerificarRequest', () => { + it('genera un envelope SOAP valido', () => { + const xml = buildVerificarRequest( + ID_SOLICITUD, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain('s:Envelope'); + expect(xml).toContain('s:Body'); + expect(xml).toContain('des:VerificaSolicitudDescarga'); + }); + + it('incluye el IdSolicitud en el body', () => { + const xml = buildVerificarRequest( + ID_SOLICITUD, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(`IdSolicitud="${ID_SOLICITUD}"`); + }); + + it('incluye el RFC solicitante', () => { + const xml = buildVerificarRequest( + ID_SOLICITUD, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(`RfcSolicitante="${RFC}"`); + }); + + it('incluye el certificado', () => { + const xml = buildVerificarRequest( + ID_SOLICITUD, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(CERT); + }); + + it('incluye el valor de firma', () => { + const xml = buildVerificarRequest( + ID_SOLICITUD, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(SIGNATURE); + }); +}); + +// --------------------------------------------------------------------------- +// parseVerificarResponse +// --------------------------------------------------------------------------- +const RESPONSE_VERIFICAR_TERMINADA = ` + + + + + ${ID_PAQUETE} + + + +`; + +const RESPONSE_VERIFICAR_EN_PROCESO = ` + + + + + + +`; + +const RESPONSE_VERIFICAR_FAULT = ` + + + + s:Client + Token invalido + + +`; + +describe('parseVerificarResponse', () => { + describe('solicitud terminada', () => { + it('extrae el estado Terminada (3)', () => { + const result = parseVerificarResponse(RESPONSE_VERIFICAR_TERMINADA); + expect(result.estado).toBe(EstadoSolicitud.Terminada); + }); + + it('extrae la descripcion del estado', () => { + const result = parseVerificarResponse(RESPONSE_VERIFICAR_TERMINADA); + expect(result.estadoDescripcion).toBe('Terminada'); + }); + + it('extrae el CodEstatus', () => { + const result = parseVerificarResponse(RESPONSE_VERIFICAR_TERMINADA); + expect(result.codEstatus).toBe('5000'); + }); + + it('extrae el Mensaje', () => { + const result = parseVerificarResponse(RESPONSE_VERIFICAR_TERMINADA); + expect(result.mensaje).toBe('Solicitud Terminada'); + }); + + it('extrae el NumeroCFDIs', () => { + const result = parseVerificarResponse(RESPONSE_VERIFICAR_TERMINADA); + expect(result.numeroCfdis).toBe(150); + }); + + it('extrae los IdsPaquetes', () => { + const result = parseVerificarResponse(RESPONSE_VERIFICAR_TERMINADA); + expect(result.idsPaquetes).toContain(ID_PAQUETE); + }); + }); + + describe('solicitud en proceso', () => { + it('extrae el estado EnProceso (2)', () => { + const result = parseVerificarResponse(RESPONSE_VERIFICAR_EN_PROCESO); + expect(result.estado).toBe(EstadoSolicitud.EnProceso); + }); + + it('la lista de paquetes esta vacia', () => { + const result = parseVerificarResponse(RESPONSE_VERIFICAR_EN_PROCESO); + expect(result.idsPaquetes).toHaveLength(0); + }); + + it('numeroCfdis es 0 mientras esta en proceso', () => { + const result = parseVerificarResponse(RESPONSE_VERIFICAR_EN_PROCESO); + expect(result.numeroCfdis).toBe(0); + }); + }); + + describe('SOAP Fault', () => { + it('lanza Error cuando la respuesta contiene un SOAP Fault', () => { + expect(() => parseVerificarResponse(RESPONSE_VERIFICAR_FAULT)).toThrow( + 'SOAP Fault' + ); + }); + + it('incluye el mensaje del fault', () => { + expect(() => parseVerificarResponse(RESPONSE_VERIFICAR_FAULT)).toThrow( + 'Token invalido' + ); + }); + }); +}); + +// --------------------------------------------------------------------------- +// buildDescargarRequest +// --------------------------------------------------------------------------- +describe('buildDescargarRequest', () => { + it('genera un envelope SOAP valido', () => { + const xml = buildDescargarRequest( + ID_PAQUETE, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain('s:Envelope'); + expect(xml).toContain('s:Body'); + expect(xml).toContain('des:PeticionDescargaMasivaTercerosEntrada'); + }); + + it('incluye el IdPaquete en el body', () => { + const xml = buildDescargarRequest( + ID_PAQUETE, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(`IdPaquete="${ID_PAQUETE}"`); + }); + + it('incluye el RFC solicitante', () => { + const xml = buildDescargarRequest( + ID_PAQUETE, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(`RfcSolicitante="${RFC}"`); + }); + + it('incluye el certificado', () => { + const xml = buildDescargarRequest( + ID_PAQUETE, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(CERT); + }); + + it('incluye el valor de firma', () => { + const xml = buildDescargarRequest( + ID_PAQUETE, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain(SIGNATURE); + }); + + it('incluye el namespace de descarga masiva', () => { + const xml = buildDescargarRequest( + ID_PAQUETE, + RFC, + TOKEN, + CERT, + SIGNATURE + ); + expect(xml).toContain( + 'xmlns:des="http://DescargaMasivaTerceros.sat.gob.mx/"' + ); + }); +}); + +// --------------------------------------------------------------------------- +// parseDescargarResponse +// --------------------------------------------------------------------------- +const ZIP_CONTENT = Buffer.from('PK\x03\x04fake zip content'); +const ZIP_B64 = ZIP_CONTENT.toString('base64'); + +const RESPONSE_DESCARGAR_OK = ` + + + + ${ZIP_B64} + + +`; + +const RESPONSE_DESCARGAR_FAULT = ` + + + + s:Client + Paquete no encontrado + + +`; + +const RESPONSE_DESCARGAR_SIN_PAQUETE = ` + + + + + +`; + +describe('parseDescargarResponse', () => { + it('retorna el contenido del ZIP como Buffer', () => { + const result = parseDescargarResponse(RESPONSE_DESCARGAR_OK); + expect(Buffer.isBuffer(result)).toBe(true); + }); + + it('el Buffer contiene el contenido correcto decodificado de Base64', () => { + const result = parseDescargarResponse(RESPONSE_DESCARGAR_OK); + expect(result).toEqual(ZIP_CONTENT); + }); + + it('lanza Error cuando la respuesta contiene un SOAP Fault', () => { + expect(() => parseDescargarResponse(RESPONSE_DESCARGAR_FAULT)).toThrow( + 'SOAP Fault' + ); + }); + + it('incluye el mensaje del fault en el error', () => { + expect(() => parseDescargarResponse(RESPONSE_DESCARGAR_FAULT)).toThrow( + 'Paquete no encontrado' + ); + }); + + it('lanza Error cuando no hay elemento Paquete en la respuesta', () => { + expect(() => + parseDescargarResponse(RESPONSE_DESCARGAR_SIN_PAQUETE) + ).toThrow('no contiene el elemento Paquete'); + }); +}); diff --git a/packages/cfdi/descarga/tsconfig.json b/packages/cfdi/descarga/tsconfig.json new file mode 100644 index 00000000..53e2475f --- /dev/null +++ b/packages/cfdi/descarga/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "lib": ["dom", "esnext"], + "types": [ "node" ], + "importHelpers": true, + // output .d.ts declaration files for consumers + "declaration": true, + // output .js.map sourcemap files for consumers + "sourceMap": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + } +} diff --git a/packages/cfdi/descarga/vitest.config.mts b/packages/cfdi/descarga/vitest.config.mts new file mode 100644 index 00000000..9152d739 --- /dev/null +++ b/packages/cfdi/descarga/vitest.config.mts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; + +export default defineConfig({ + test: {}, + plugins: [tsconfigPaths()], +}); diff --git a/packages/cfdi/designs/.gitignore b/packages/cfdi/designs/.gitignore new file mode 100644 index 00000000..9f874b7f --- /dev/null +++ b/packages/cfdi/designs/.gitignore @@ -0,0 +1,70 @@ +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.npmrc +# Runtime data +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ +dist/ +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# next.js build output +.next + +# OS X temporary files +.DS_Store + +# Rush temporary files +common/deploy/ +common/temp/ +common/autoinstallers/*/.npmrc +**/.rush/temp/ + +# Heft +.heft +maca961017759.cer +wsi1503194j6.cer diff --git a/packages/cfdi/designs/README.md b/packages/cfdi/designs/README.md new file mode 100644 index 00000000..b6d52985 --- /dev/null +++ b/packages/cfdi/designs/README.md @@ -0,0 +1,115 @@ +# @cfdi/designs + +Disenos y plantillas para generar representaciones en PDF de facturas CFDI. Incluye clases utilitarias para construir documentos PDF con pdfmake y disenos predefinidos listos para usar. + +## Instalacion + +```bash +npm install @cfdi/designs +``` + +## Uso + +### Usar un diseno predefinido + +```typescript +import { PDF117 } from '@cfdi/designs'; + +const plantilla = new PDF117(); +plantilla.design(); + +const pdf = plantilla.getPDF(); +const documento = pdf.toJSON(); +``` + +### Construir un diseno personalizado + +```typescript +import { PDF, Row, Column, Table, Cell, Text, Image, Style } from '@cfdi/designs'; + +const pdf = new PDF(); + +// Crear una fila con columnas +const encabezado = new Row() + .addColumn( + new Column({ + mode: 'stack', + children: new Image('base64...') + .setHeight(100) + .setWidth(100) + .toJSON(), + }) + ) + .addColumn( + new Column({ width: 200 }) + .setContent({ text: 'Mi Empresa SA de CV', style: { bold: true } }) + .setStyle(new Style({ fontSize: 9 })) + ); + +// Crear tabla de conceptos +const tabla = new Table(); +tabla.setWidths([50, 200, 80, 80]); +tabla.setStyle(new Style({ fontSize: 9 })); +tabla.setMargin([0, 10, 0, 10]); + +tabla.setHeader( + [ + new Cell('CANTIDAD').toJSON(), + new Cell('DESCRIPCION').toJSON(), + new Text('P.UNITARIO').toJSON(), + new Text('IMPORTE').toJSON(), + ], + new Style({ fillColor: 'black', color: 'white', fontSize: 9 }) +); + +tabla.addRow([ + new Cell('1').toJSON(), + new Text('Servicio de consultoria').toJSON(), + new Text('1000.00').toJSON(), + new Text('1000.00').toJSON(), +]); + +// Agregar texto con estilos +const total = new Text('TOTAL: ', new Style({ bold: true })) + .addText('$1,160.00', new Style({ fontSize: 12 })); + +// Construir el documento +pdf + .addContent(encabezado.toJSON()) + .addContent(tabla.toJSON()) + .addContent(total.toJSON()) + .setStyles({ header: { fontSize: 18, bold: true } }) + .setDefaultStyle({ fontSize: 10 }); +``` + +## API + +### Disenos predefinidos + +| Clase | Descripcion | +|-------|-------------| +| `PDF117` | Diseno de factura con encabezado, datos del cliente, tabla de conceptos, desglose de impuestos y datos fiscales del SAT | + +### Clases utilitarias + +| Clase | Descripcion | +|-------|-------------| +| `PDF` | Contenedor principal del documento. Metodos: `addContent()`, `setStyles()`, `setDefaultStyle()`, `toJSON()` | +| `Row` | Fila de columnas. Metodos: `addColumn()`, `setGap()`, `toJSON()` | +| `Column` | Columna dentro de una fila. Metodos: `setContent()`, `setStyle()`, `toJSON()` | +| `Table` | Tabla con filas y columnas. Metodos: `setHeader()`, `addRow()`, `setWidths()`, `setMargin()`, `setStyle()`, `toJSON()` | +| `Cell` | Celda de tabla. Metodos: `setColSpan()`, `setBorder()`, `setAlignment()`, `setStyle()`, `toJSON()` | +| `Text` | Texto con estilo. Metodos: `addText()`, `setBold()`, `setMargin()`, `setStyle()`, `toJSON()` | +| `Image` | Imagen (base64). Metodos: `setWidth()`, `setHeight()`, `setAlignment()`, `toJSON()` | +| `Style` | Estilo aplicable a cualquier elemento. Propiedades: `fontSize`, `bold`, `color`, `fillColor`, `margin`, `alignment` | +| `Grid` | Utilidad para crear layouts de cuadricula | + +### Clase abstracta `GeneradorPdf` + +Clase base para crear disenos personalizados. Define los metodos abstractos que cada diseno debe implementar: + +`logo()`, `folio()`, `datosEmisor()`, `receptor()`, `impuestos()`, `totalEnLetras()`, `certificadoEmisor()`, `folioFiscal()`, `qr()`, `detalles()`, `formaPago()`, `metodoPago()`, `moneda()`, `tipoComprobante()`, entre otros. + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/designs/package-lock.json b/packages/cfdi/designs/package-lock.json new file mode 100644 index 00000000..223df3c6 --- /dev/null +++ b/packages/cfdi/designs/package-lock.json @@ -0,0 +1,962 @@ +{ + "name": "design", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "design", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "esbuild": "^0.25.1", + "typescript": "^5.8.2", + "vite": "^6.2.2" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.36.0.tgz", + "integrity": "sha512-jgrXjjcEwN6XpZXL0HUeOVGfjXhPyxAbbhD0BlXUB+abTOpbPiN5Wb3kOT7yb+uEtATNYF5x5gIfwutmuBA26w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.36.0.tgz", + "integrity": "sha512-NyfuLvdPdNUfUNeYKUwPwKsE5SXa2J6bCt2LdB/N+AxShnkpiczi3tcLJrm5mA+eqpy0HmaIY9F6XCa32N5yzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.36.0.tgz", + "integrity": "sha512-JQ1Jk5G4bGrD4pWJQzWsD8I1n1mgPXq33+/vP4sk8j/z/C2siRuxZtaUA7yMTf71TCZTZl/4e1bfzwUmFb3+rw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.36.0.tgz", + "integrity": "sha512-6c6wMZa1lrtiRsbDziCmjE53YbTkxMYhhnWnSW8R/yqsM7a6mSJ3uAVT0t8Y/DGt7gxUWYuFM4bwWk9XCJrFKA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.36.0.tgz", + "integrity": "sha512-KXVsijKeJXOl8QzXTsA+sHVDsFOmMCdBRgFmBb+mfEb/7geR7+C8ypAml4fquUt14ZyVXaw2o1FWhqAfOvA4sg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.36.0.tgz", + "integrity": "sha512-dVeWq1ebbvByI+ndz4IJcD4a09RJgRYmLccwlQ8bPd4olz3Y213uf1iwvc7ZaxNn2ab7bjc08PrtBgMu6nb4pQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.36.0.tgz", + "integrity": "sha512-bvXVU42mOVcF4le6XSjscdXjqx8okv4n5vmwgzcmtvFdifQ5U4dXFYaCB87namDRKlUL9ybVtLQ9ztnawaSzvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.36.0.tgz", + "integrity": "sha512-JFIQrDJYrxOnyDQGYkqnNBtjDwTgbasdbUiQvcU8JmGDfValfH1lNpng+4FWlhaVIR4KPkeddYjsVVbmJYvDcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.36.0.tgz", + "integrity": "sha512-KqjYVh3oM1bj//5X7k79PSCZ6CvaVzb7Qs7VMWS+SlWB5M8p3FqufLP9VNp4CazJ0CsPDLwVD9r3vX7Ci4J56A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.36.0.tgz", + "integrity": "sha512-QiGnhScND+mAAtfHqeT+cB1S9yFnNQ/EwCg5yE3MzoaZZnIV0RV9O5alJAoJKX/sBONVKeZdMfO8QSaWEygMhw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.36.0.tgz", + "integrity": "sha512-1ZPyEDWF8phd4FQtTzMh8FQwqzvIjLsl6/84gzUxnMNFBtExBtpL51H67mV9xipuxl1AEAerRBgBwFNpkw8+Lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.36.0.tgz", + "integrity": "sha512-VMPMEIUpPFKpPI9GZMhJrtu8rxnp6mJR3ZzQPykq4xc2GmdHj3Q4cA+7avMyegXy4n1v+Qynr9fR88BmyO74tg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.36.0.tgz", + "integrity": "sha512-ttE6ayb/kHwNRJGYLpuAvB7SMtOeQnVXEIpMtAvx3kepFQeowVED0n1K9nAdraHUPJ5hydEMxBpIR7o4nrm8uA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.36.0.tgz", + "integrity": "sha512-4a5gf2jpS0AIe7uBjxDeUMNcFmaRTbNv7NxI5xOCs4lhzsVyGR/0qBXduPnoWf6dGC365saTiwag8hP1imTgag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.36.0.tgz", + "integrity": "sha512-5KtoW8UWmwFKQ96aQL3LlRXX16IMwyzMq/jSSVIIyAANiE1doaQsx/KRyhAvpHlPjPiSU/AYX/8m+lQ9VToxFQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.36.0.tgz", + "integrity": "sha512-sycrYZPrv2ag4OCvaN5js+f01eoZ2U+RmT5as8vhxiFz+kxwlHrsxOwKPSA8WyS+Wc6Epid9QeI/IkQ9NkgYyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.36.0.tgz", + "integrity": "sha512-qbqt4N7tokFwwSVlWDsjfoHgviS3n/vZ8LK0h1uLG9TYIRuUTJC88E1xb3LM2iqZ/WTqNQjYrtmtGmrmmawB6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.36.0.tgz", + "integrity": "sha512-t+RY0JuRamIocMuQcfwYSOkmdX9dtkr1PbhKW42AMvaDQa+jOdpUYysroTF/nuPpAaQMWp7ye+ndlmmthieJrQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.36.0.tgz", + "integrity": "sha512-aRXd7tRZkWLqGbChgcMMDEHjOKudo1kChb1Jt1IfR8cY/KIpgNviLeJy5FUb9IpSuQj8dU2fAYNMPW/hLKOSTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.10.tgz", + "integrity": "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.36.0.tgz", + "integrity": "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.36.0", + "@rollup/rollup-android-arm64": "4.36.0", + "@rollup/rollup-darwin-arm64": "4.36.0", + "@rollup/rollup-darwin-x64": "4.36.0", + "@rollup/rollup-freebsd-arm64": "4.36.0", + "@rollup/rollup-freebsd-x64": "4.36.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.36.0", + "@rollup/rollup-linux-arm-musleabihf": "4.36.0", + "@rollup/rollup-linux-arm64-gnu": "4.36.0", + "@rollup/rollup-linux-arm64-musl": "4.36.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.36.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0", + "@rollup/rollup-linux-riscv64-gnu": "4.36.0", + "@rollup/rollup-linux-s390x-gnu": "4.36.0", + "@rollup/rollup-linux-x64-gnu": "4.36.0", + "@rollup/rollup-linux-x64-musl": "4.36.0", + "@rollup/rollup-win32-arm64-msvc": "4.36.0", + "@rollup/rollup-win32-ia32-msvc": "4.36.0", + "@rollup/rollup-win32-x64-msvc": "4.36.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/typescript": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz", + "integrity": "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "postcss": "^8.5.3", + "rollup": "^4.30.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + } + } +} diff --git a/packages/cfdi/designs/package.json b/packages/cfdi/designs/package.json new file mode 100644 index 00000000..40202086 --- /dev/null +++ b/packages/cfdi/designs/package.json @@ -0,0 +1,25 @@ +{ + "name": "@cfdi/designs", + "version": "1.0.0", + "description": "Un paquete para Node con Vite y TypeScript", + "main": "dist/index.cjs.js", + "module": "dist/index.es.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "vite build", + "dev": "vite" + }, + "dependencies": { + "pdfmake": "^0.2.20", + "@cfdi/2json": "workspace:*", + "@cfdi/utils": "workspace:*" + }, + "devDependencies": { + "@types/pdfmake": "^0.2.11", + "vite-plugin-dts": "^4.5.3", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-url": "^8.0.2", + "typescript": "^5.6.3", + "vite": "^7.0.0" + } +} diff --git a/packages/cfdi/designs/pnpm-lock.yaml b/packages/cfdi/designs/pnpm-lock.yaml new file mode 100644 index 00000000..a9f505e5 --- /dev/null +++ b/packages/cfdi/designs/pnpm-lock.yaml @@ -0,0 +1,955 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@types/pdfmake': + specifier: ^0.2.11 + version: 0.2.11 + pdfmake: + specifier: ^0.2.18 + version: 0.2.18 + devDependencies: + typescript: + specifier: ^5.0.0 + version: 5.8.2 + vite: + specifier: ^5.0.0 + version: 5.4.14(@types/node@22.13.10) + +packages: + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@foliojs-fork/fontkit@1.9.2': + resolution: {integrity: sha512-IfB5EiIb+GZk+77TRB86AHroVaqfq8JRFlUbz0WEwsInyCG0epX2tCPOy+UfaWPju30DeVoUAXfzWXmhn753KA==} + + '@foliojs-fork/linebreak@1.1.2': + resolution: {integrity: sha512-ZPohpxxbuKNE0l/5iBJnOAfUaMACwvUIKCvqtWGKIMv1lPYoNjYXRfhi9FeeV9McBkBLxsMFWTVVhHJA8cyzvg==} + + '@foliojs-fork/pdfkit@0.15.3': + resolution: {integrity: sha512-Obc0Wmy3bm7BINFVvPhcl2rnSSK61DQrlHU8aXnAqDk9LCjWdUOPwhgD8Ywz5VtuFjRxmVOM/kQ/XLIBjDvltw==} + + '@foliojs-fork/restructure@2.0.2': + resolution: {integrity: sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==} + + '@rollup/rollup-android-arm-eabi@4.36.0': + resolution: {integrity: sha512-jgrXjjcEwN6XpZXL0HUeOVGfjXhPyxAbbhD0BlXUB+abTOpbPiN5Wb3kOT7yb+uEtATNYF5x5gIfwutmuBA26w==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.36.0': + resolution: {integrity: sha512-NyfuLvdPdNUfUNeYKUwPwKsE5SXa2J6bCt2LdB/N+AxShnkpiczi3tcLJrm5mA+eqpy0HmaIY9F6XCa32N5yzg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.36.0': + resolution: {integrity: sha512-JQ1Jk5G4bGrD4pWJQzWsD8I1n1mgPXq33+/vP4sk8j/z/C2siRuxZtaUA7yMTf71TCZTZl/4e1bfzwUmFb3+rw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.36.0': + resolution: {integrity: sha512-6c6wMZa1lrtiRsbDziCmjE53YbTkxMYhhnWnSW8R/yqsM7a6mSJ3uAVT0t8Y/DGt7gxUWYuFM4bwWk9XCJrFKA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.36.0': + resolution: {integrity: sha512-KXVsijKeJXOl8QzXTsA+sHVDsFOmMCdBRgFmBb+mfEb/7geR7+C8ypAml4fquUt14ZyVXaw2o1FWhqAfOvA4sg==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.36.0': + resolution: {integrity: sha512-dVeWq1ebbvByI+ndz4IJcD4a09RJgRYmLccwlQ8bPd4olz3Y213uf1iwvc7ZaxNn2ab7bjc08PrtBgMu6nb4pQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.36.0': + resolution: {integrity: sha512-bvXVU42mOVcF4le6XSjscdXjqx8okv4n5vmwgzcmtvFdifQ5U4dXFYaCB87namDRKlUL9ybVtLQ9ztnawaSzvg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.36.0': + resolution: {integrity: sha512-JFIQrDJYrxOnyDQGYkqnNBtjDwTgbasdbUiQvcU8JmGDfValfH1lNpng+4FWlhaVIR4KPkeddYjsVVbmJYvDcg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.36.0': + resolution: {integrity: sha512-KqjYVh3oM1bj//5X7k79PSCZ6CvaVzb7Qs7VMWS+SlWB5M8p3FqufLP9VNp4CazJ0CsPDLwVD9r3vX7Ci4J56A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.36.0': + resolution: {integrity: sha512-QiGnhScND+mAAtfHqeT+cB1S9yFnNQ/EwCg5yE3MzoaZZnIV0RV9O5alJAoJKX/sBONVKeZdMfO8QSaWEygMhw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.36.0': + resolution: {integrity: sha512-1ZPyEDWF8phd4FQtTzMh8FQwqzvIjLsl6/84gzUxnMNFBtExBtpL51H67mV9xipuxl1AEAerRBgBwFNpkw8+Lg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.36.0': + resolution: {integrity: sha512-VMPMEIUpPFKpPI9GZMhJrtu8rxnp6mJR3ZzQPykq4xc2GmdHj3Q4cA+7avMyegXy4n1v+Qynr9fR88BmyO74tg==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.36.0': + resolution: {integrity: sha512-ttE6ayb/kHwNRJGYLpuAvB7SMtOeQnVXEIpMtAvx3kepFQeowVED0n1K9nAdraHUPJ5hydEMxBpIR7o4nrm8uA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.36.0': + resolution: {integrity: sha512-4a5gf2jpS0AIe7uBjxDeUMNcFmaRTbNv7NxI5xOCs4lhzsVyGR/0qBXduPnoWf6dGC365saTiwag8hP1imTgag==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.36.0': + resolution: {integrity: sha512-5KtoW8UWmwFKQ96aQL3LlRXX16IMwyzMq/jSSVIIyAANiE1doaQsx/KRyhAvpHlPjPiSU/AYX/8m+lQ9VToxFQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.36.0': + resolution: {integrity: sha512-sycrYZPrv2ag4OCvaN5js+f01eoZ2U+RmT5as8vhxiFz+kxwlHrsxOwKPSA8WyS+Wc6Epid9QeI/IkQ9NkgYyQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.36.0': + resolution: {integrity: sha512-qbqt4N7tokFwwSVlWDsjfoHgviS3n/vZ8LK0h1uLG9TYIRuUTJC88E1xb3LM2iqZ/WTqNQjYrtmtGmrmmawB6A==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.36.0': + resolution: {integrity: sha512-t+RY0JuRamIocMuQcfwYSOkmdX9dtkr1PbhKW42AMvaDQa+jOdpUYysroTF/nuPpAaQMWp7ye+ndlmmthieJrQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.36.0': + resolution: {integrity: sha512-aRXd7tRZkWLqGbChgcMMDEHjOKudo1kChb1Jt1IfR8cY/KIpgNviLeJy5FUb9IpSuQj8dU2fAYNMPW/hLKOSTw==} + cpu: [x64] + os: [win32] + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/node@22.13.10': + resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} + + '@types/pdfkit@0.13.9': + resolution: {integrity: sha512-RDG8Yb1zT7I01FfpwK7nMSA433XWpblMqSCtA5vJlSyavWZb303HUYPCel6JTiDDFqwGLvtAnYbH8N/e0Cb89g==} + + '@types/pdfmake@0.2.11': + resolution: {integrity: sha512-gglgMQhnG6C2kco13DJlvokqTxL+XKxHwCejElH8fSCNF9ZCkRK6Mzo011jQ0zuug+YlIgn6BpcpZrARyWdW3Q==} + + base64-js@1.3.1: + resolution: {integrity: sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + brotli@1.3.3: + resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + deep-equal@1.1.2: + resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} + engines: {node: '>= 0.4'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + dfa@1.2.0: + resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + jpeg-exif@1.1.4: + resolution: {integrity: sha512-a+bKEcCjtuW5WTdgeXFzswSrdqi0jk4XlEtZlx5A94wCoBpFjfFTbo/Tra5SpNCl/YFZPvcV1dJc+TAYeg6ROQ==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + nanoid@3.3.10: + resolution: {integrity: sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + + pdfmake@0.2.18: + resolution: {integrity: sha512-Fe+GnMS8EVZu5rci/CDaQ+xmUoHvx8P+rvIlrwSYM6A5c7Aik8G6lpJbddhjBE2jXGjv6WcUCFCB06uZbjxkMw==} + engines: {node: '>=18'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + png-js@1.0.0: + resolution: {integrity: sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + rollup@4.36.0: + resolution: {integrity: sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + + typescript@5.8.2: + resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + unicode-properties@1.4.1: + resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} + + unicode-trie@2.0.0: + resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} + + vite@5.4.14: + resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + xmldoc@1.3.0: + resolution: {integrity: sha512-y7IRWW6PvEnYQZNZFMRLNJw+p3pezM4nKYPfr15g4OOW9i8VpeydycFuipE2297OvZnh3jSb2pxOt9QpkZUVng==} + +snapshots: + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@foliojs-fork/fontkit@1.9.2': + dependencies: + '@foliojs-fork/restructure': 2.0.2 + brotli: 1.3.3 + clone: 1.0.4 + deep-equal: 1.1.2 + dfa: 1.2.0 + tiny-inflate: 1.0.3 + unicode-properties: 1.4.1 + unicode-trie: 2.0.0 + + '@foliojs-fork/linebreak@1.1.2': + dependencies: + base64-js: 1.3.1 + unicode-trie: 2.0.0 + + '@foliojs-fork/pdfkit@0.15.3': + dependencies: + '@foliojs-fork/fontkit': 1.9.2 + '@foliojs-fork/linebreak': 1.1.2 + crypto-js: 4.2.0 + jpeg-exif: 1.1.4 + png-js: 1.0.0 + + '@foliojs-fork/restructure@2.0.2': {} + + '@rollup/rollup-android-arm-eabi@4.36.0': + optional: true + + '@rollup/rollup-android-arm64@4.36.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.36.0': + optional: true + + '@rollup/rollup-darwin-x64@4.36.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.36.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.36.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.36.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.36.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.36.0': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.36.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.36.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.36.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.36.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.36.0': + optional: true + + '@types/estree@1.0.6': {} + + '@types/node@22.13.10': + dependencies: + undici-types: 6.20.0 + + '@types/pdfkit@0.13.9': + dependencies: + '@types/node': 22.13.10 + + '@types/pdfmake@0.2.11': + dependencies: + '@types/node': 22.13.10 + '@types/pdfkit': 0.13.9 + + base64-js@1.3.1: {} + + base64-js@1.5.1: {} + + brotli@1.3.3: + dependencies: + base64-js: 1.5.1 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + clone@1.0.4: {} + + crypto-js@4.2.0: {} + + deep-equal@1.1.2: + dependencies: + is-arguments: 1.2.0 + is-date-object: 1.1.0 + is-regex: 1.2.1 + object-is: 1.1.6 + object-keys: 1.1.1 + regexp.prototype.flags: 1.5.4 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + dfa@1.2.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + functions-have-names@1.2.3: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + gopd@1.2.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + jpeg-exif@1.1.4: {} + + math-intrinsics@1.1.0: {} + + nanoid@3.3.10: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + pako@0.2.9: {} + + pdfmake@0.2.18: + dependencies: + '@foliojs-fork/linebreak': 1.1.2 + '@foliojs-fork/pdfkit': 0.15.3 + iconv-lite: 0.6.3 + xmldoc: 1.3.0 + + picocolors@1.1.1: {} + + png-js@1.0.0: {} + + postcss@8.5.3: + dependencies: + nanoid: 3.3.10 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + rollup@4.36.0: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.36.0 + '@rollup/rollup-android-arm64': 4.36.0 + '@rollup/rollup-darwin-arm64': 4.36.0 + '@rollup/rollup-darwin-x64': 4.36.0 + '@rollup/rollup-freebsd-arm64': 4.36.0 + '@rollup/rollup-freebsd-x64': 4.36.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.36.0 + '@rollup/rollup-linux-arm-musleabihf': 4.36.0 + '@rollup/rollup-linux-arm64-gnu': 4.36.0 + '@rollup/rollup-linux-arm64-musl': 4.36.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.36.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.36.0 + '@rollup/rollup-linux-riscv64-gnu': 4.36.0 + '@rollup/rollup-linux-s390x-gnu': 4.36.0 + '@rollup/rollup-linux-x64-gnu': 4.36.0 + '@rollup/rollup-linux-x64-musl': 4.36.0 + '@rollup/rollup-win32-arm64-msvc': 4.36.0 + '@rollup/rollup-win32-ia32-msvc': 4.36.0 + '@rollup/rollup-win32-x64-msvc': 4.36.0 + fsevents: 2.3.3 + + safer-buffer@2.1.2: {} + + sax@1.4.1: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + source-map-js@1.2.1: {} + + tiny-inflate@1.0.3: {} + + typescript@5.8.2: {} + + undici-types@6.20.0: {} + + unicode-properties@1.4.1: + dependencies: + base64-js: 1.5.1 + unicode-trie: 2.0.0 + + unicode-trie@2.0.0: + dependencies: + pako: 0.2.9 + tiny-inflate: 1.0.3 + + vite@5.4.14(@types/node@22.13.10): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.36.0 + optionalDependencies: + '@types/node': 22.13.10 + fsevents: 2.3.3 + + xmldoc@1.3.0: + dependencies: + sax: 1.4.1 diff --git a/packages/cfdi/designs/src/A111/index.ts b/packages/cfdi/designs/src/A111/index.ts new file mode 100644 index 00000000..3d523986 --- /dev/null +++ b/packages/cfdi/designs/src/A111/index.ts @@ -0,0 +1,153 @@ +import { PDF } from '../pdf/PDF'; +import { Style } from '../pdf/Style'; +import { Text } from '../pdf/Text'; +import { Column } from '../pdf/Column'; +import { Row } from '../pdf/Row'; +import { Table } from '../pdf/Table'; +import { Cell } from '../pdf/Cell'; + +export default class PDF111 { + public pdf = new PDF(); + + public design(): void { + const boldStyle = new Style({ fontSize: 10, bold: true }); + const regularStyle = new Style({ fontSize: 10 }); + + const text = new Text('\nORDEN DE COMPRA', new Style({ fontSize: 13 })); + + const text2 = new Text('\nSolicitante:', boldStyle).addText( + ' Sistemas', + regularStyle + ); + const text3 = new Text('\nProveedor:', boldStyle).addText( + ' Coppe', + regularStyle + ); + const text4 = new Text('\nEmpresa:', boldStyle).addText( + ' driana Salvador Jeronimo', + regularStyle + ); + + const column1 = new Column({ width: 200 }) + .setContent(text2.toJSON()) + .setContent(text3.toJSON()) + .setContent(text4.toJSON()); + + const text5 = new Text('\nArticulos Solicitados:', boldStyle).addText( + ' 1', + regularStyle + ); + const text6 = new Text('\nFecha de Pedido:', boldStyle).addText( + ' 06/07/2020', + regularStyle + ); + const text7 = new Text('\nFecha de Entrega:', boldStyle).addText( + ' 06/07/2020', + regularStyle + ); + + const column2 = new Column({ width: 250 }) + .setContent(new Text('').toJSON()) + .setContent(text5.toJSON()) + .setContent(text6.toJSON()) + .setContent(text7.toJSON()); + + const table = new Table(); + table.setHeader([ + new Cell('Folio').setBorder([true, true, true, true]).toJSON(), + ]); + table.addRow([new Cell('109209437').toJSON()]); + const column3 = new Column({ width: 150, mode: 'stack' }).setContent( + table.toJSON() + ); + + const row = new Row({ + children: [column1.toJSON(), column2.toJSON(), column3.toJSON()], + }); + + const table2 = new Table(); + table2.setWidths([40, 153, 50, 80, 60, 50, 50]); + table2.setHeaderRow(1); + table2.setHeader([ + new Cell('N') + .setStyle(new Style({ fillColor: '#dddddd' })) + .setBorder([true, true, true, true]) + .toJSON(), + new Cell('Concepto/Descricion') + .setStyle(new Style({ fillColor: '#dddddd' })) + .setBorder([true, true, true, true]) + .toJSON(), + + new Cell('C.pedida') + .setStyle(new Style({ fillColor: '#dddddd' })) + .setBorder([true, true, true, true]) + .toJSON(), + + new Cell('Unidad') + .setStyle(new Style({ fillColor: '#dddddd' })) + .setBorder([true, true, true, true]) + .toJSON(), + + new Cell('C.Recibida') + .setStyle(new Style({ fillColor: '#dddddd' })) + .setBorder([true, true, true, true]) + .toJSON(), + + new Cell('Precio') + .setStyle(new Style({ fillColor: '#dddddd' })) + .setBorder([true, true, true, true]) + .toJSON(), + new Cell('Valor') + .setStyle(new Style({ fillColor: '#dddddd' })) + .setBorder([true, true, true, true]) + .toJSON(), + + ]); + table2.addRow(['1', 'cat', 'nomina', 'servicio', '19891', '090', '090']) + + const header = new Text('\n\n\n\n ', new Style({ fontSize: 10, bold: true, color: '#a76d09' })); + const table3 = new Table(); + table3.setWidths([500]); + table3.setHeader([ + new Cell(header).setBorder( [false, false, false, true]).setAlignment('center').toJSON(), + ]); + this.pdf.addContent(text.toJSON()).addContent(row.toJSON()).addContent(table2.toJSON()).addContent(table3.toJSON()).addContent({ + style: 'tableExample', + table: { + widths: [280, 240], + body: [ + [ + { + border: [false, false, false, false], + text: [ + { + alignment: 'left', + text: 'AUTORIZADO POR (Nombre y Firma) ', + style: { + bold: true, + }, + }, + ], + }, + { + border: [false, false, false, false], + text: [ + { + alignment: 'right', + text: 'SOLICITADO POR (Nombre y Firma) ', + style: { + bold: true, + }, + }, + ], + }, + ], + ], + }, + },) + } + + public getPDF(): PDF { + return this.pdf; + } +} diff --git a/packages/cfdi/designs/src/A117/index.ts b/packages/cfdi/designs/src/A117/index.ts new file mode 100644 index 00000000..6bee48bf --- /dev/null +++ b/packages/cfdi/designs/src/A117/index.ts @@ -0,0 +1,412 @@ +import { Column } from '../pdf/Column'; +import { PDF } from '../pdf/PDF'; +import { Row } from '../pdf/Row'; +import { Style } from '../pdf/Style'; +import { Image } from '../pdf/Image'; +import { Text } from '../pdf/Text'; +import { Table } from '../pdf/Table'; +import { Cell } from '../pdf/Cell'; +import { logo} from '@cfdi/utils' +export default class PDF117 { + public pdf = new PDF(); + public design() { + const row = new Row() + .setGap(10) + .addColumn( + new Column({ + mode: 'stack', + children: new Image(logo) + .setHeight(100) + .setWidth(100) + .setAlignment('left') + .toJSON(), + }) + ) + .addColumn(new Column({ children: '', width: 40 })) + .addColumn( + new Column({ width: 200 }) + .setContent({ + text: 'HERRERIA & ELECTRICOS S DE CV\n', + style: { + bold: true, + color: '#a76d09', + }, + }) + .setContent({ + text: [ + { + text: 'R.F.C: ', + style: { + bold: true, + color: '#a76d09', + }, + }, + { text: 'H&E951128469\n' }, + ], + }) + .setContent({ + text: [ + { + text: 'REGIMEN: ', + style: { + bold: true, + color: '#a76d09', + }, + }, + { text: '601 - GENERAL DE LEY PERSONAS MORALES\n' }, + ], + }) + .setContent({ + text: [ + { + text: 'LUGAR DE EXPEDICION: ', + style: { + bold: true, + color: '#a76d09', + }, + }, + { + text: 'CONSTITUYENTES y 115 AV MZA.25 LT.2 Y 3, EJIDO NORTE, 77714 PLAYA DEL CARMEN, Q.R.\n', + }, + ], + }) + .setStyle(new Style({ fontSize: 9, color: '#a76d09' })) + ) + .addColumn( + new Column({ width: 200, mode: 'stack' }).setContent([ + { + alignment: 'center', + margin: [100, 0, 0, 0], + text: 'FACTURA', + style: { + fontSize: 9, + bold: true, + color: '#FF5733', + }, + }, + { + margin: [80, 0, 0, 10], + alignment: 'center', + width: 10, + table: { + body: [ + [ + { + text: 'FOLIO', + style: { + bold: true, + fontSize: 9, + alignment: 'center', + color: '#a76d09', + margin: [0, 0, 0, 0], + }, + }, + ], + [ + { + text: 'A - MYLF-26', + }, + ], + ], + }, + layout: { + // @ts-ignore + paddingLeft: (i: any, node: any) => { + return 20; + }, + // @ts-ignore + paddingRight: (i: any, node: any) => { + return 20; + }, + // @ts-ignore + paddingTop: (i: any, node: any) => { + return 0; + }, + // @ts-ignore + paddingBottom: (i: any, node: any) => { + return 0; + }, + // @ts-ignore + fillColor: (rowIndex: number, node: any, columnIndex: any) => { + return rowIndex === 0 ? '#eeeeee' : null; + }, + }, + }, + { + alignment: 'center', + margin: [80, 0, 0, 0], + table: { + heights: 10, + body: [ + [ + { + text: 'FECHA', + style: { + bold: true, + fontSize: 9, + alignment: 'center', + margin: [0, 0, 0, 0], + }, + }, + ], + [ + { + text: '2022-02-26T06:06:26', + }, + ], + ], + }, + layout: { + // @ts-ignore + paddingTop: (i: any, node: any) => { + return 0; + }, + // @ts-ignore + paddingBottom: (i: any, node: any) => { + return 0; + }, + // @ts-ignore + fillColor: (rowIndex: number, node: any, columnIndex: any) => { + return rowIndex === 0 ? '#eeeeee' : null; + }, + }, + }, + ]) + ); + + const styleInfo = new Style({ bold: true, color: 'purple' }); + const styleLabel = new Style({ bold: true, color: '#a76d09' }); + + const text = new Text('Datos del Cliente\n') + .setBold(true) + .setMargin([0, 20, 0, 10]) + .setStyle(new Style({ fontSize: 10, color: '#0941a7' })) + .addText('Razon Social: ', styleLabel) + .addText('PUBLIC EN GENERAL\n', styleInfo) + .addText('R.F.C.: ', styleLabel) + .addText('XAXX010101000\n', styleInfo) + .addText('Uso CFDI: ', styleLabel) + .addText('P01\n', styleInfo); + + const table = new Table(); + table.setStyle(new Style({ fontSize: 9 })); + table.setWidths([45, 10, 50, 160, 40, 50, 53, 40]); + table.setMargin([0, 7, 0, 7]); + + table.setHeader( + [ + new Cell('CANTIDAD').setColSpan(2).toJSON(), + new Cell('').toJSON(), + new Text('CLAVE SAT', new Style({ fillColor: '#C0C0C0' })).toJSON(), + new Cell('CONCEPTO/DESCRIPCIÓN').toJSON(), + new Text('UNIDAD').toJSON(), + new Text('P.UNITARIO').toJSON(), + new Text('DESCUENTO').toJSON(), + new Text('IMPORTE').toJSON(), + ], + new Style({ + fillColor: 'black', + color: '#a76d09', + fontSize: 9, + }) + ); + + table.addRow([ + new Cell('1', new Style({ fillColor: 'red' })).toJSON(), + new Cell('2').toJSON(), + new Text('10001000', new Style({ fillColor: 'purple' })).toJSON(), + new Text('HERRERIA & ELECTRICOS S DE CV').toJSON(), + new Text('UNIDAD').toJSON(), + new Text('100.00').toJSON(), + new Text('0.00').toJSON(), + new Text('100.00').toJSON(), + ]); + table.addRow([ + new Cell('1', new Style({ fillColor: 'red' })).toJSON(), + new Cell('2').toJSON(), + new Text('10001000', new Style({ fillColor: 'purple' })).toJSON(), + new Text('HERRERIA & ELECTRICOS S DE CV').toJSON(), + new Text('UNIDAD').toJSON(), + new Text('100.00').toJSON(), + new Text('0.00').toJSON(), + new Text('100.00').toJSON(), + ]); + + const labelStrong = new Style({ fontSize: 9, bold: true }); + const quality = new Text('CANTIDAD CON LETRA:\n', labelStrong).addText( + 'OCHOCIENTOS TREINTA Y NUEVE PESOS 99/100 M.N.', + new Style({ fontSize: 9 }) + ); + + const desglose = new Text('SUBTOTAL: ', labelStrong) + .addText('$17240009.13\n', new Style({ fontSize: 9 })) + .addText('DESCUENTO: ', labelStrong) + .addText('$0.00\n', new Style({ fontSize: 9 })) + .addText('IMPUESTOS: ', labelStrong) + .addText('$275.87\n', new Style({ fontSize: 9 })) + .addText('TOTAL: ', labelStrong) + .addText('$2000.00', new Style({ fontSize: 9 })); + + table.addRow([ + new Cell(quality).setColSpan(6).toJSON(), + new Cell('2', new Style({ fillColor: 'red' })).toJSON(), + new Text('10001000', new Style({ fillColor: 'purple' })).toJSON(), + new Text('HERRERIA & ELECTRICOS S DE CV').toJSON(), + new Text('UNIDAD').toJSON(), + new Text('100.00').toJSON(), + new Cell(desglose).setColSpan(2).toJSON(), + new Text('100.00').toJSON(), + ]); + + const styleDetails = new Style({ bold: true, color: '#a76d09' }); + const details = new Row() + .addColumn( + new Column({ width: '50%', mode: 'stack' }) + .setContent( + new Text('Forma de pago: ', styleDetails) + .addText('Efectivo') + .toJSON() + ) + .setContent( + new Text('Método de pago: ', styleDetails) + .addText('PUE - Pago en una sola exhibición') + .toJSON() + ) + .setContent( + new Text('No. de cuenta: ', styleDetails) + .addText('123456789') + .toJSON() + ) + ) + .addColumn( + new Column({ width: '50%', mode: 'stack' }) + .setContent(new Text('Moneda:', styleDetails).addText('MXN').toJSON()) + .setContent( + new Text('Tipo de comprobante: ', styleDetails) + .addText('I - Ingreso') + .toJSON() + ) + ); + + const table2 = new Table(); + table2.setWidths([250, 250]); + table2.setStyle(new Style({ fontSize: 9 })); + + table2.addRow( + [ + new Cell('No. CSD del Emisor') + .setBorder([false, false, false, false]) + .setStyle(new Style({ bold: true, color: 'orange' })) + .setAlignment('center') + .toJSON(), + new Cell('Fecha y hora de certificacion') + .setBorder([false, false, false, false]) + .setStyle(new Style({ bold: true, color: 'green' })) + .setAlignment('center') + .toJSON(), + ], + new Style({ + color: '#a76d09', + fontSize: 9, + }) + ); + table2.addRow( + [ + new Cell('30001000000400002463') + .setBorder([false, true, false, false]) + .setAlignment('center') + .toJSON(), + new Cell('2022-02-26T18:05:05') + .setBorder([false, true, false, false]) + .setAlignment('center') + .toJSON(), + ], + new Style({ + color: '#a76d09', + fontSize: 9, + }) + ); + + table2.addRow( + [ + new Cell('Folio Fiscal') + .setBorder([false, false, false, false]) + .setAlignment('center') + .toJSON(), + new Cell('No. CSD del SAT') + .setBorder([false, false, false, false]) + .setAlignment('center') + .toJSON(), + ], + new Style({ + color: '#a76d09', + fontSize: 9, + }) + ); + + table2.addRow( + [ + new Cell('DC2ED983-D108-402E-A2FD-C08EDDA23C47') + .setBorder([false, true, false, false]) + .setAlignment('center') + .toJSON(), + new Cell('30001000000400002495') + .setBorder([false, true, false, false]) + .setAlignment('center') + .toJSON(), + ], + new Style({ + color: '#a76d09', + fontSize: 9, + }) + ); + + const styleLabelDetailsSat = new Style({ bold: true, fontSize: 7, margin: [50, 50, 100, 50] }); + const styleDetailsSat = new Style({ fontSize: 7 }); + const detailsSat = new Row() + .addColumn( + new Column({ width: '20%', mode: 'stack' }) + .setContent({ + qr: 'https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=dc2ed983-d108-402e-a2fd-c08edda23c47&re=H&E951128469&rr=XAXX010101000&tt=000000000000002000.000000&fe=h8ZyAw==', + "fit": 100, // Tamaño en puntos (100pt = ~35mm) + "foreground": "#0941a7", // Color del QR + "alignment": "left" // Alineación opcional + }) + ) + .addColumn( + new Column({ width: '80%', mode: 'stack' }) + .setContent( + new Text('SELLO DIGITAL DEL EMISOR\n', styleLabelDetailsSat) + .addText(`YHV2O4OPL7jZIQiuKTgygUb75wrYXRNkgQjKWXPUr19MRfE60v+ug5xHe/bb8hW3DK8Iw9MGiqh/+z5dM2ACWlFk77SqJpEMnBVRkgwmWA/84ltCtSmtQP8roBJHy3JarVPVXwNWgo2qVAaK9Hch5XJZbASlMnPp0JESkze6deZTB22XJRdKkXa1kKZcSx/v/X/+5m99RMUNjtOKerU4jpG0cigO0M/q3j0evKjR6f1uTtW77nYEHZc/++PaExEgO7CaK4Hvk5QNHLD3gngd8UZEG5gTCcZm45B7EyiKJOSOKlF7CEXc7UgY1mYQhbeFQht2+AB9fHYIF1Zzh8ZyAw==\n`, styleDetailsSat) + .addText('SELLO DEL SAT\n', styleLabelDetailsSat) + .addText(`IUgJIUBUfH6d + +AmgqQMM370OpyNnlFwLguCoSHJ5qPmPdVjymZjvji1gQiEJSroQXtrZIOQzlADTjsBDespCLE9CQSIaGLJFrUsaH7tJXibft+cBwcLDbZ/ + TTsuff8AV87f06GcVDSXSm6EZKp/dbOVh3lA6/c3QqVCESfKDY+5XLwmG4CkQWlRGEcx7tCVOCLVICNUloz6tGkaHjNOFocKk/ + DFrrvN0fBy8U1vqXK438WIbTqbRNvgGF2Wzkv8GJuiDPjMJEiiHv5Vi0Al26nAZaFFhgu5k1dcfQwxjRgMc7hmEidJ2ngb+96VFhuqlM + +8lHkfoeFoprXjt+Zu4g==\n`, styleDetailsSat) + .addText(`CADENA ORIGINAL DEL COMPLEMENTO DE CERTIFICACION DIGITAL DEL SAT\n`, styleLabelDetailsSat) + .addText(`||1.1|dc2ed983-d108-402e-a2fd-c08edda23c47|2022-02-26T18:05:05|SPR190613I52| + YHV2O4OPL7jZIQiuKTgygUb75wrYXRNkgQjKWXPUr19MRfE60v+ug5xHe/bb8hW3DK8Iw9MGiqh/ + +z5dM2ACWlFk77SqJpEMnBVRkgwmWA/84ltCtSmtQP8roBJHy3JarVPVXwNWgo2qVAaK9Hch5XJZbASlMnPp0JESkze6deZTB22XJR + dKkXa1kKZcSx/v/X/+5m99RMUNjtOKerU4jpG0cigO0M/q3j0evKjR6f1uTtW77nYEHZc/+ + +PaExEgO7CaK4Hvk5QNHLD3gngd8UZEG5gTCcZm45B7EyiKJOSOKlF7CEXc7UgY1mYQhbeFQht2+AB9fHYIF1Zzh8ZyAw==| + 30001000000400002495||`, styleDetailsSat) + .toJSON() + ) + ); + + this.pdf + .addContent(row.toJSON()) + .addContent(text.toJSON()) + .addContent(table.toJSON()) + .addContent(details.toJSON()) + .addContent(table2.toJSON()) + .addContent(detailsSat.toJSON()) + .setStyles({ header: { fontSize: 18, bold: true } }) + .setDefaultStyle({ fontSize: 12 }); + } + + public getPDF(): PDF { + return this.pdf; + } +} diff --git a/packages/cfdi/pdf/src/templates/B111/B111.skeleton.ts b/packages/cfdi/designs/src/B111/index.ts similarity index 76% rename from packages/cfdi/pdf/src/templates/B111/B111.skeleton.ts rename to packages/cfdi/designs/src/B111/index.ts index 9410fec5..9bb3053a 100644 --- a/packages/cfdi/pdf/src/templates/B111/B111.skeleton.ts +++ b/packages/cfdi/designs/src/B111/index.ts @@ -1,11 +1,20 @@ -import { TDocumentDefinitions } from 'pdfmake/interfaces'; +import { PDF } from '../pdf/PDF'; +import { Style } from '../pdf/Style'; +import { Text } from '../pdf/Text'; +import { Column } from '../pdf/Column'; +import { Row } from '../pdf/Row'; +import { Table } from '../pdf/Table'; +import { Cell } from '../pdf/Cell'; import { logo } from '@cfdi/utils'; -export const B111ESKELETON: TDocumentDefinitions | any = { - pageSize: 'A4', - pageMargins: [20, 25, 20, 25], - content: [ - { +export default class PDFB111 { + public pdf = new PDF(); + + public design(): void { + const table = new Table(); + table.setWidths([230, 100, 200]); + + this.pdf.setContent({ style: 'tableExample', table: { widths: [230, 100, 200], @@ -104,7 +113,7 @@ export const B111ESKELETON: TDocumentDefinitions | any = { style: { bold: true, color: '#a76d09' }, }, ], - [], + [ { text: 'N° DE SERIE DE CERTIFICACION', @@ -112,7 +121,13 @@ export const B111ESKELETON: TDocumentDefinitions | any = { style: { bold: true, color: '#a76d09' }, }, ], - [{ text: 'F3EE54R', alignment: 'center', style: { color: 'red' } }], + [ + { + text: 'F3EE54R', + alignment: 'center', + style: { color: 'red' }, + }, + ], [ { text: 'FECHA Y HORA DE CERTIFICACION', @@ -120,7 +135,13 @@ export const B111ESKELETON: TDocumentDefinitions | any = { style: { bold: true, color: '#a76d09' }, }, ], - [{ text: '18:12:12 02/07/2020', alignment: 'center',style: { color: 'red' } }], + [ + { + text: '18:12:12 02/07/2020', + alignment: 'center', + style: { color: 'red' }, + }, + ], ], }, layout: { @@ -133,9 +154,9 @@ export const B111ESKELETON: TDocumentDefinitions | any = { ], ], }, - }, + }); - { + this.pdf.addContent({ style: 'tableExample', table: { widths: [270, 269], @@ -258,13 +279,12 @@ export const B111ESKELETON: TDocumentDefinitions | any = { ], ], }, - }, + }); - { + this.pdf.addContent({ style: 'tableExample', table: { widths: [50, 40, 173, 120, 60, 60], - headerRows: 1, body: [ [ { @@ -309,13 +329,12 @@ export const B111ESKELETON: TDocumentDefinitions | any = { ['1', 'cat', 'nomina', 'servicio', '19891', '090'], ], }, - }, - { - style: 'tableExample', + }) + this.pdf.addContent({ table: { widths: [99, 302, 129], - + body: [ [ { @@ -340,7 +359,6 @@ export const B111ESKELETON: TDocumentDefinitions | any = { { style: 'tableExample', table: { - headerRows: 1, alignment: 'center', body: [ [ @@ -365,57 +383,61 @@ export const B111ESKELETON: TDocumentDefinitions | any = { ], ], }, - }, + }); - { - style: 'tableExample', - table: { - widths: [548], - body: [ - [ - { - text: [ - { - text: 'SELLO DIGITAL\n', - style: { - bold: true, - color: '#0941a7', + this.pdf.addContent( { + style: 'tableExample', + table: { + widths: [548], + body: [ + [ + { + text: [ + { + text: 'SELLO DIGITAL\n', + style: { + bold: true, + color: '#0941a7', + }, }, - }, - { - text: 'aYjYNUhTvNVosLnPJsV5h/lAW/HSs45Qzhl2W5V2DPqrdoFfp9mH7wUcS5v3jP6Oql4Y7ncYOcLqakqfGeclJJP/6T1XmbcvPPdBq1DGWh6DaisHS2QCMOW3MGuv8Hc/0j7JwYbXFpTKKM3cudwTmzh76MUoqnssDUfuFIVJ8=`,\n\n', - }, - { - text: 'SELLO SAT\n', - style: { - bold: true, - color: '#0941a7', + { + text: 'aYjYNUhTvNVosLnPJsV5h/lAW/HSs45Qzhl2W5V2DPqrdoFfp9mH7wUcS5v3jP6Oql4Y7ncYOcLqakqfGeclJJP/6T1XmbcvPPdBq1DGWh6DaisHS2QCMOW3MGuv8Hc/0j7JwYbXFpTKKM3cudwTmzh76MUoqnssDUfuFIVJ8=`,\n\n', }, - }, - { - text: 'GlU7AYil3GqVeUD9oJvqVKc2Uq/K2R7lkc2m6WPuhddjYvWm0foFfMVwzn2KfS7o6KZIddDXdAglhknZsz3ub3X0/aPW4DSwvDYXOF2yCCqd64vbt5MfWqpPqN2zmjzJVFe5ntIPQ21jveXAjR44pJIHNG3rUUUdhVnag6NFTqviaAV75z6OywesoMQCFcsoEjvKozzKGpT7Imuoa94aGIhj0TP5m1hk4OnROOcEBPo11mPf4elDKBDzk+iuCw4wiV/GHaeL0D4zBcVOL/Igz12MKRmYtNdmBfSCv3TI7bJ7qQUV1RckO2Rj1CpFrpa7xr/Vw6lEwitpkCwQ00SKBg==\n\n', - }, - { - text: [ - { - text: 'CADENA ORIGINAL DEL COMPLEMENTO DE CERTIFICACION DIGITAL DEL SAT\n', - style: { - bold: true, - color: '#0941a7', - }, + { + text: 'SELLO SAT\n', + style: { + bold: true, + color: '#0941a7', }, - ], - }, - { - text: - '||1.1|5D178E7E-C81C-11E8-89A8-237CD11664D5|2018-10-04T16:27:58|FMO1007168C6|eaYjYNUhTvNVosLnPJsV5h/xlAW/HSs45Qzhl2W5V2DPqrdoFfp9mH7wUcS5v3jP6Oql4Y7ncYOcLqakqfGeclJJP/6T1XmbcvPPdBq1DGWh6DaisHS2QCMOW3MG\n' + - 'uv8Hc/0j7JwYbXFpTKKM3cudwTmzh76MUoqnssDUfuFIVJ8=|00001000000401477845||', - }, - ], - }, + }, + { + text: 'GlU7AYil3GqVeUD9oJvqVKc2Uq/K2R7lkc2m6WPuhddjYvWm0foFfMVwzn2KfS7o6KZIddDXdAglhknZsz3ub3X0/aPW4DSwvDYXOF2yCCqd64vbt5MfWqpPqN2zmjzJVFe5ntIPQ21jveXAjR44pJIHNG3rUUUdhVnag6NFTqviaAV75z6OywesoMQCFcsoEjvKozzKGpT7Imuoa94aGIhj0TP5m1hk4OnROOcEBPo11mPf4elDKBDzk+iuCw4wiV/GHaeL0D4zBcVOL/Igz12MKRmYtNdmBfSCv3TI7bJ7qQUV1RckO2Rj1CpFrpa7xr/Vw6lEwitpkCwQ00SKBg==\n\n', + }, + { + text: [ + { + text: 'CADENA ORIGINAL DEL COMPLEMENTO DE CERTIFICACION DIGITAL DEL SAT\n', + style: { + bold: true, + color: '#0941a7', + }, + }, + ], + }, + { + text: + '||1.1|5D178E7E-C81C-11E8-89A8-237CD11664D5|2018-10-04T16:27:58|FMO1007168C6|eaYjYNUhTvNVosLnPJsV5h/xlAW/HSs45Qzhl2W5V2DPqrdoFfp9mH7wUcS5v3jP6Oql4Y7ncYOcLqakqfGeclJJP/6T1XmbcvPPdBq1DGWh6DaisHS2QCMOW3MG\n' + + 'uv8Hc/0j7JwYbXFpTKKM3cudwTmzh76MUoqnssDUfuFIVJ8=|00001000000401477845||', + }, + ], + }, + ], ], - ], - }, - }, - ], -}; + }, + }) + } + + public getPDF(): PDF { + return this.pdf; + } +} diff --git a/packages/cfdi/designs/src/B112/index.ts b/packages/cfdi/designs/src/B112/index.ts new file mode 100644 index 00000000..407d54c0 --- /dev/null +++ b/packages/cfdi/designs/src/B112/index.ts @@ -0,0 +1,458 @@ +import { PDF } from '../pdf/PDF'; +import { Style } from '../pdf/Style'; +import { Text } from '../pdf/Text'; +import { Column } from '../pdf/Column'; +import { Row } from '../pdf/Row'; +import { Table } from '../pdf/Table'; +import { Cell } from '../pdf/Cell'; +import { logo } from '@cfdi/utils'; +export default class PDFB112 { + public pdf = new PDF(); + + public design(): void { + + this.pdf.setContent({ + + + style: 'tableExample', + table: { + + widths: [545], + body: [ + [ + { + border: [false, false, false, false], + fillColor: '#000080', + text: [ + + { + alignment: 'center', + text: 'FACTURA ELECTRÓNICA (CFDI)', + style: { + bold: true, + color: '#00FFFF', + fontSize: 13, + } + }, + + ] + } + ] + ] + } + }) + + + + this.pdf.addContent( + + { + + style: 'tableExample', + table: { + + widths: [545], + body: [ + [ + { + border: [false, false, false, false], + text: [ + + { + alignment: 'left', + text: '\nNOMBRE O RAZON SOCIAL DE LA EMPRESA', + style: { + bold: true, + fontSize: 12, + } + }, + + ] + } + ] + ] + } + }).addContent( + { + columns: [ + { + width: 100, + image: logo, + height: 100, + alignment: 'left' + }, + { + width: 20, + text: '' + }, + { + margin: [0, 0, 0, 0], + width: 243, + text: [ + + { + text: [ + { + text: 'R.F.C:\n ', + style: { + bold: true, + color: '#a76d09', + } + }, + { text: ' GUCE910701NHA\n' } + ] + }, + { + text: [ + { + text: 'Dirrecion:\n', + style: { + bold: true, + color: '#a76d09', + } + }, + { text: ' av oquideas entre ruta5\n' } + ] + }, + { + text: [ + { + text: 'Telefono:\n', + style: { + bold: true, + color: '#a76d09', + } + }, + { text: ' 98765436899\n' } + ] + }, + ] + }, + { + width: 500, + + style: 'tableExample', + table: { + body: [ + [{ text: 'FACTURA', alignment: 'right', style: { bold: true, color: '#a76d09' } }], + [{ text: 'F3EE54R', alignment: 'right' }], + [{ text: 'FOLIO FISCAL', alignment: 'right', style: { bold: true, color: '#a76d09' } }], + [{ text: 'XXXXXXXXXX', alignment: 'right' }], + [{ text: 'N° DE SERIE DE CERTIFICACION', alignment: 'right', style: { bold: true, color: '#a76d09' } }], + [{ text: 'XXXXXXXXX', alignment: 'right' }], + [{ text: 'FECHA Y HORA DE CERTIFICACION', alignment: 'right', style: { bold: true, color: '#a76d09' } }], + [{ text: '18:12:12 02/07/2020', alignment: 'right' }], + ] + }, + layout: 'noBorders' + }, + + + ] + }).addContent( + { + style: 'tableExample', + table: { + + body: [ + [ + { + border: [false, false, false, false], + style: { bold: true, color: '#a76d09' }, + text: 'Lugar de Expedicion: ' + }, + { + border: [false, false, false, false], + + text: 'solidaridad,playa del carmen ' + }, + ] + ] + } + }).addContent( + + { + + style: 'tableExample', + table: { + + widths: [545], + body: [ + [ + { + border: [false, true, false, false], + text: [ + { + border: [false, true, false, false], + linecolors: '#000080', + style: { bold: true, color: '#a76d09' }, + text: 'Receptor: ' + }, + { + border: [false, false, false, false], + text: 'PEMEX GAS Y PETROQUIMICA BASICA\n ' + }, + { + border: [false, false, false, false], + linecolors: '#000080', + style: { bold: true, color: '#a76d09' }, + text: 'RFC del Clinete: ' + }, + { + border: [false, false, false, false], + text: 'PGP920716MT6\n ' + }, + { + border: [false, false, false, false], + linecolors: '#000080', + style: { bold: true, color: '#a76d09' }, + text: 'Dirrecion: ' + }, + { + border: [false, false, false, false], + text: 'AVENIDA MARINA NACIONAL 329 PETROLEOS MEXICANOS,Distrito Federal C.P. 86125, México \n' + }, + { + border: [false, false, false, false], + linecolors: '#000080', + style: { bold: true, color: '#a76d09' }, + text: 'Telefono: ' + }, + { + border: [false, false, false, false], + text: '9890808090 \n' + }, + ] + } + ] + ] + } + }).addContent( + { + style: 'tableExample', + table: { + widths: [50, 40, 173, 120, 60, 60], + headerRows: 1, + body: [ + + [{ text: 'cantidad', fillColor: '#dddddd', border: [true, true, true, true] }, { text: 'Unidad', style: 'tableHeader', fillColor: '#dddddd', border: [true, true, true, true] }, { text: 'descricion', style: 'tableHeader', fillColor: '#dddddd', border: [true, true, true, true] }, { text: 'Clave servicio/producto', style: 'tableHeader', fillColor: '#dddddd', border: [true, true, true, true] }, { text: 'Precio Unitario', style: 'tableHeader', fillColor: '#dddddd', border: [true, true, true, true] }, { text: 'Importe', style: 'tableHeader', fillColor: '#dddddd', border: [true, true, true, true] }], + ['1', 'cat', 'nomina', 'servicio', '19891', '090'], + ['1', 'cat', 'nomina', 'servicio', '19891', '090'], + ['1', 'cat', 'nomina', 'servicio', '19891', '090'], + ['1', 'cat', 'nomina', 'servicio', '19891', '090'], + + ] + }, + + + }).addContent( + { + margin: [0, 7, 0, 7], + table: { + + widths: ['auto', '*', 'auto'], + body: [ + [ + { + border: [false, false, false, false], + alignment: 'center', + + table: { + body: [ + [ + + { + image: logo, + width: 100, + height: 100, + }, + + + ], + ] + }, + layout: 'noBorders' + }, + { + border: [false, false, false, false], + stack: [ + { + text: 'CANTIDAD CON LETRA', + style: { + bold: true, + fontSize: 9 + } + }, + { + text: 'OCHOCIENTOS TREINTA Y NUEVE PESOS 99/100 M.N.\n\n', + style: { + fontSize: 9 + } + }, + { + text: 'METODO DE PAGO', + style: { + bold: true, + fontSize: 9 + } + }, + { + text: 'NO INDENTIFICADO\n', + style: { + fontSize: 9 + } + }, + { + text: 'REGIMEN', + style: { + bold: true, + fontSize: 9 + } + }, + { + text: 'PERSONA MORAL', + style: { + fontSize: 9 + } + } + ] + }, + { + border: [false, false, false, false], + style: 'tableExample', + table: { + headerRows: 1, + alignment: 'center', + body: [ + [{ text: 'Subtotal', alignment: 'center', }, { text: 'FACTURA', alignment: 'center' }], + [{ text: 'Descuento', alignment: 'center' }, { text: 'F3EE54R', alignment: 'center' }], + [{ text: 'I.V.A 16%', alignment: 'center' }, { text: 'F3EE54R', alignment: 'center' }], + [{ text: 'Total', alignment: 'center' }, { text: 'F3EE54R', alignment: 'center' }], + + + ] + }, + layout: 'lightHorizontalLines' + + } + ], + ] + } + }).addContent( + { + style: 'tableExample', + table: { + widths: [548], + + body: [ + [{ + border: [false, false, false, false], + text: [ + + { + text: 'SELLO DIGITAL\n', + style: { + bold: true, + color: '#0941a7', + fontSize: 10, + } + }, + { fontSize: 10, text: 'aYjYNUhTvNVosLnPJsV5h/lAW/HSs45Qzhl2W5V2DPqrdoFfp9mH7wUcS5v3jP6Oql4Y7ncYOcLqakqfGeclJJP/6T1XmbcvPPdBq1DGWh6DaisHS2QCMOW3MGuv8Hc/0j7JwYbXFpTKKM3cudwTmzh76MUoqnssDUfuFIVJ8=`,\n\n' }, + { + text: 'SELLO SAT\n', + style: { + fontSize: 10, + bold: true, + color: '#0941a7', + } + + }, + { fontSize: 10, text: 'GlU7AYil3GqVeUD9oJvqVKc2Uq/K2R7lkc2m6WPuhddjYvWm0foFfMVwzn2KfS7o6KZIddDXdAglhknZsz3ub3X0/aPW4DSwvDYXOF2yCCqd64vbt5MfWqpPqN2zmjzJVFe5ntIPQ21jveXAjR44pJIHNG3rUUUdhVnag6NFTqviaAV75z6OywesoMQCFcsoEjvKozzKGpT7Imuoa94aGIhj0TP5m1hk4OnROOcEBPo11mPf4elDKBDzk+iuCw4wiV/GHaeL0D4zBcVOL/Igz12MKRmYtNdmBfSCv3TI7bJ7qQUV1RckO2Rj1CpFrpa7xr/Vw6lEwitpkCwQ00SKBg==\n\n' }, + { + text: [ + { + text: 'CADENA ORIGINAL DEL COMPLEMENTO DE CERTIFICACION DIGITAL DEL SAT\n', + style: { + bold: true, + color: '#0941a7', + fontSize: 10, + } + }, + ] + }, + { + fontSize: 10, text: '||1.1|5D178E7E-C81C-11E8-89A8-237CD11664D5|2018-10-04T16:27:58|FMO1007168C6|eaYjYNUhTvNVosLnPJsV5h/xlAW/HSs45Qzhl2W5V2DPqrdoFfp9mH7wUcS5v3jP6Oql4Y7ncYOcLqakqfGeclJJP/6T1XmbcvPPdBq1DGWh6DaisHS2QCMOW3MG\n' + + 'uv8Hc/0j7JwYbXFpTKKM3cudwTmzh76MUoqnssDUfuFIVJ8=|00001000000401477845||' + }, + + + ] + }, + ] + ] + } + }).addContent( + { + + style: 'tableExample', + table: { + + widths: [548], + + body: [ + [ + { + border: [false, false, false, true], + alignment: 'center', + text: [ + { + border: [false, false, true, false], + linecolors: '#000080', + style: { fontSize: 10, bold: true, color: '#a76d09' }, + text: ' N° DE SERIE DE CERTIFICACION:', + }, + { + border: [false, false, false, false], + fontSize: 10, + text: 'XXXXXXXXX\n ' + }, + { + border: [false, false, false, false], + linecolors: '#000080', + style: { fontSize: 10, bold: true, color: '#a76d09' }, + text: 'FECHA Y HORA DE CERTIFICACION:' + }, + { + border: [false, false, false, false], + fontSize: 10, + text: '03/07/2020\n ' + }, + ] + } + ] + ] + } + }).addContent( + { + style: 'tableExample', + table: { + widths: [180, 200, 150], + headerRows: 1, + body: [ + + [{ text: ' PAGO EN UNA SOLA EXHIBICION', fontSize: 7, alignment: 'left', border: [false, false, false, false] }, + { text: 'Esta es una representación impresa de un CFDI', fontSize: 7, alignment: 'center', border: [false, false, false, false] }, + { text: 'Efectos fscales al pago', fontSize: 7, alignment: 'right', border: [false, false, false, false] }] + + + ] + }, + + + }) + } + + public getPDF(): PDF { + return this.pdf; + } +} diff --git a/packages/cfdi/pdf/src/templates/B123/index.ts b/packages/cfdi/designs/src/B123/index.ts similarity index 93% rename from packages/cfdi/pdf/src/templates/B123/index.ts rename to packages/cfdi/designs/src/B123/index.ts index fa21499f..3957705e 100644 --- a/packages/cfdi/pdf/src/templates/B123/index.ts +++ b/packages/cfdi/designs/src/B123/index.ts @@ -1,18 +1,16 @@ -import { TDocumentDefinitions } from "pdfmake/interfaces"; -import { XmlCdfi } from "@cfdi/xml"; -import { XmlToJson } from "@cfdi/2json"; +import { PDF } from '../pdf/PDF'; +import { Style } from '../pdf/Style'; +import { Text } from '../pdf/Text'; +import { Column } from '../pdf/Column'; +import { Row } from '../pdf/Row'; +import { Table } from '../pdf/Table'; +import { Cell } from '../pdf/Cell'; import { logo } from '@cfdi/utils'; -import { createPdf, TCreatedPdf } from "pdfmake/build/pdfmake"; - - -export class B123 { - // @ts-ignore - private xml: XmlCdfi; - private docDefinition: TDocumentDefinitions = { - pageSize: 'A4', - pageMargins: [20, 25, 20, 25], - content: [ - { +export default class PDFB123 { + public pdf = new PDF(); + public design(): void { + + this.pdf.setContent({ columns: [ { text: [ @@ -45,7 +43,7 @@ export class B123 { ] } ] - }, + }).addContent( { columns: [ @@ -80,7 +78,7 @@ export class B123 { ] } ] - }, + }).addContent( { alignment: 'right', text: 'hora', @@ -89,8 +87,7 @@ export class B123 { color: '#a76d09', } - }, - + }).addContent( { columns: [ { @@ -186,9 +183,7 @@ export class B123 { }, ], - }, - - + }).addContent( { style: 'tableExample', table: { @@ -232,8 +227,7 @@ export class B123 { }, layout: 'noBorders' - }, - + }).addContent( { style: 'tableExample', color: '#444', @@ -268,9 +262,7 @@ export class B123 { ] } - }, - - + }).addContent( { style: 'tableExample', color: '#444', @@ -326,7 +318,7 @@ export class B123 { ], ] } - }, + }).addContent( { alignment: 'justify', @@ -356,8 +348,7 @@ export class B123 { ] - }, - + }).addContent( { alignment: 'justify', @@ -421,20 +412,9 @@ export class B123 { ] }, ] - }, - ], - - - } - - constructor(xml: string) { - // @ts-ignore - - this.xml = XmlToJson(xml) + }) } - - public async getDocument(): Promise { - return createPdf(this.docDefinition); + public getPDF(): PDF { + return this.pdf; } - } diff --git a/packages/cfdi/pdf/src/templates/B222/index.ts b/packages/cfdi/designs/src/B222/index.ts similarity index 95% rename from packages/cfdi/pdf/src/templates/B222/index.ts rename to packages/cfdi/designs/src/B222/index.ts index 2f8ebd71..5df5e0c9 100644 --- a/packages/cfdi/pdf/src/templates/B222/index.ts +++ b/packages/cfdi/designs/src/B222/index.ts @@ -1,22 +1,17 @@ -import { TDocumentDefinitions } from "pdfmake/interfaces"; -import { XmlCdfi } from "@cfdi/xml"; -import { XmlToJson } from "@cfdi/2json"; +import { PDF } from '../pdf/PDF'; +import { Style } from '../pdf/Style'; +import { Text } from '../pdf/Text'; +import { Column } from '../pdf/Column'; +import { Row } from '../pdf/Row'; +import { Table } from '../pdf/Table'; +import { Cell } from '../pdf/Cell'; import { logo } from '@cfdi/utils'; -import { createPdf, TCreatedPdf } from "pdfmake/build/pdfmake"; +export default class PDFB222 { + public pdf = new PDF(); - -export class B222 { - // @ts-ignore - private xml: XmlCdfi; - private docDefinition: TDocumentDefinitions = { - pageSize: 'A4', - pageMargins: [20, 25, 20, 25], - content: [ - - - - - { + public design(): void { + + this.pdf.setContent( { style: 'tableExample', @@ -52,7 +47,7 @@ export class B222 { ] ] } - }, + }).addContent( { columns: [ @@ -100,7 +95,7 @@ export class B222 { text: '' }, ] - }, + }).addContent( { columns: [ @@ -373,11 +368,11 @@ export class B222 { }, ] - }, + }).addContent( { width: 50, text: '\n' - }, + }).addContent( { style: 'tableExample', table: { @@ -391,7 +386,7 @@ export class B222 { }, - }, + }).addContent( { style: 'tableExample', @@ -426,7 +421,7 @@ export class B222 { }, layout: 'noBorders' - }, + }).addContent( { text: [ { @@ -439,7 +434,7 @@ export class B222 { }, ] - }, + }).addContent( { columns: [ @@ -470,7 +465,7 @@ export class B222 { ] }, ] - }, + }).addContent( { alignment: 'justify', @@ -523,36 +518,11 @@ export class B222 { }, ] - }, - - - - - - - - - - - - - - - - - - - - ], + }) } - constructor(xml: string) { - // @ts-ignore - - this.xml = XmlToJson(xml) - } - - public async getDocument(): Promise { - return createPdf(this.docDefinition); + public getPDF(): PDF { + return this.pdf; } } + diff --git a/packages/cfdi/pdf/src/templates/B333/index.ts b/packages/cfdi/designs/src/B333/index.ts similarity index 95% rename from packages/cfdi/pdf/src/templates/B333/index.ts rename to packages/cfdi/designs/src/B333/index.ts index c99ce2ba..a8f97484 100644 --- a/packages/cfdi/pdf/src/templates/B333/index.ts +++ b/packages/cfdi/designs/src/B333/index.ts @@ -1,17 +1,17 @@ -import { TDocumentDefinitions } from "pdfmake/interfaces"; -import { XmlCdfi } from "@cfdi/xml"; -import { XmlToJson } from "@cfdi/2json"; +import { PDF } from '../pdf/PDF'; +import { Style } from '../pdf/Style'; +import { Text } from '../pdf/Text'; +import { Column } from '../pdf/Column'; +import { Row } from '../pdf/Row'; +import { Table } from '../pdf/Table'; +import { Cell } from '../pdf/Cell'; import { logo } from '@cfdi/utils'; -import { createPdf, TCreatedPdf } from "pdfmake/build/pdfmake"; +export default class PDFB333 { + public pdf = new PDF(); - -export class B333 { - // @ts-ignore - private xml: XmlCdfi; - private docDefinition: TDocumentDefinitions = { - pageSize: 'A4', - pageMargins: [20, 25, 20, 25], - content: [ + public design(): void { + + this.pdf.setContent( { style: 'tableExample', @@ -210,8 +210,7 @@ export class B333 { },], ] } - }, - + }).addContent( { style: 'tableExample', table: { @@ -252,7 +251,7 @@ export class B333 { ] ] }, - }, + }).addContent( { style: 'tableExample', table: { @@ -294,13 +293,11 @@ export class B333 { ] ] }, - }, + }).addContent( { text: '\n' - }, - - + }).addContent( { style: 'tableExample', table: { @@ -316,7 +313,7 @@ export class B333 { }, - }, + }).addContent( { margin: [0, 7, 0, 7], table: { @@ -397,9 +394,7 @@ export class B333 { ], ] } - }, - - + }).addContent( { style: 'tableExample', table: { @@ -411,7 +406,7 @@ export class B333 { ] }, - }, + }).addContent( { style: 'tableExample', table: { @@ -423,7 +418,7 @@ export class B333 { ] }, - }, + }).addContent( { style: 'tableExample', table: { @@ -454,7 +449,7 @@ export class B333 { ] ] }, - }, + }).addContent( { style: 'tableExample', table: { @@ -466,7 +461,7 @@ export class B333 { [{ text: 'xxxxxxxxxxxxxxxx', alignment: 'center', border: [true, true, true, true] }, { text: 'xxxxxxxxxxxxxx', alignment: 'center', border: [true, true, true, true] }] ] }, - }, + }).addContent( { style: 'tableExample', table: { @@ -497,7 +492,7 @@ export class B333 { ] ] }, - }, + }).addContent( { style: 'tableExample', table: { @@ -528,30 +523,13 @@ export class B333 { ] ] }, - }, - - - - - - - - - ] - - - + }) + } + public getPDF(): PDF { + return this.pdf; + } } - - constructor(xml: string) { - // @ts-ignore - this.xml = XmlToJson(xml) - } - - public async getDocument(): Promise { - return createPdf(this.docDefinition); - } - -} + + diff --git a/packages/cfdi/designs/src/abstract-cfdi-pdf.ts b/packages/cfdi/designs/src/abstract-cfdi-pdf.ts new file mode 100644 index 00000000..e5f1be8f --- /dev/null +++ b/packages/cfdi/designs/src/abstract-cfdi-pdf.ts @@ -0,0 +1,41 @@ +export abstract class GeneradorPdf { + + constructor(xml: string) { + + } + + protected abstract logo(): void; + protected abstract folio(comprobante: CFDIComprobante): void; + protected abstract datosEmisor(emisor: XmlEmisorAttribute, lugarExpedicion: string): void; + protected abstract fecha(fecha: string): void; + protected abstract receptor(receptor: XmlReceptor): void; + protected abstract fechaTimbrado(tfd: XmlTfd): void; + protected abstract totales(comprobante: CFDIComprobante): void; + protected abstract impuestos(impuesto: XmlImpuestos): void; + protected abstract totalEnLetras(total: number): void; + protected abstract certificadoEmisor(noCertificado: string): void; + protected abstract detalles(concepto: XmlConcepto): void; + protected abstract formaPago(forma: string): void; + protected abstract metodoPago(metodo: string): void; + protected abstract moneda(moneda: string): void; + protected abstract tipoComprobante(tipo: string): void; + protected abstract certificadoSat(tfd: XmlTfd): void; + protected abstract folioFiscal(tfd: XmlTfd): void; + protected abstract selloEmisor(tfd: XmlTfd): void; + protected abstract selloSat(tfd: XmlTfd): void; + protected abstract cadenaOriginal(tfd: XmlTfd): void; + protected abstract qr( + tfd: XmlTfd, + emisor?: XmlEmisor, + receptor?: XmlReceptor, + total?: string + ): void; + + public async obtenerDocumento() { + /* const fuentesCombinadas = { ...this.fuentes, ...Pd.fonts, ...this.opciones.fuentes }; + console.log(fuentesCombinadas); + return createPdf(this.definicionDocumento); */ + } + + +} diff --git a/packages/cfdi/designs/src/index.ts b/packages/cfdi/designs/src/index.ts new file mode 100644 index 00000000..25aa6177 --- /dev/null +++ b/packages/cfdi/designs/src/index.ts @@ -0,0 +1,3 @@ +import PDF117 from './A117/index'; + +export { PDF117 }; \ No newline at end of file diff --git a/packages/cfdi/designs/src/pdf/Cell.ts b/packages/cfdi/designs/src/pdf/Cell.ts new file mode 100644 index 00000000..351c4987 --- /dev/null +++ b/packages/cfdi/designs/src/pdf/Cell.ts @@ -0,0 +1,39 @@ +import { Content, TableCell, TableCellProperties } from 'pdfmake/interfaces'; +import { Text } from './Text'; +import { Style } from './Style'; +type ICell = Content & TableCellProperties +export class Cell { + private cell: Partial = { + + } + + constructor(text: string | Text, style?: Style) { + this.cell = typeof text === 'string' ? { text, ...(style ?? {})} : { text: text.toJSON(), ...(style ?? {}) }; + } + + setColSpan(colSpan: number): this { + // @ts-ignore + this.cell.colSpan = colSpan; + return this; + } + + setStyle(style: Style): this { + // @ts-ignore + this.cell = { ...this.cell, ...style.toJSON() }; + return this; + } + + setBorder(border: [boolean, boolean, boolean, boolean]): this { + this.cell.border = border; + return this; + } + + setAlignment(alignment: 'left' | 'center' | 'right'): this { + // @ts-ignore + this.cell.alignment = alignment; + return this; + } + toJSON(): TableCell { + return this.cell; + } +} diff --git a/packages/cfdi/designs/src/pdf/Column.ts b/packages/cfdi/designs/src/pdf/Column.ts new file mode 100644 index 00000000..8ca236e5 --- /dev/null +++ b/packages/cfdi/designs/src/pdf/Column.ts @@ -0,0 +1,54 @@ +import { Content, ContentColumns, ContentStack } from 'pdfmake/interfaces'; +import { Style } from './Style'; +interface IColumn { + width: string | number; + text: Content; + style?: Style; +} +export class Column { + private columnConfig: IColumn = { width: 'auto', text: [] }; + private mode: 'text' | 'stack' | 'image' = 'text'; + constructor(options?: { + children?: Content | Content[]; + width?: string | number; + mode?: 'text' | 'stack' ; + }) { + const { children = [], width = 'auto', mode = 'text' } = options || {}; + this.mode = mode; + this.columnConfig[this.mode] = []; + this.columnConfig.width = width; + this.addContent(children); + } + + private addContent(content: Content | Content[]): this { + if (Array.isArray(content)) { + const currentContent = this.columnConfig[this.mode]; + this.columnConfig[this.mode] = [...currentContent, ...content]; + } else { + this.columnConfig[this.mode].push(content); + } + return this; + } + setContent(content: Content | Content[]): this { + this.addContent(content); + return this; + } + + setStack(content: Content | Content[]): this { + this.addContent(content); + return this; + } + setWidth(width: string | number): this { + this.columnConfig.width = width; + return this; + } + + setStyle(style: Style): this { + this.columnConfig.style = style; + return this; + } + + toJSON(): IColumn { + return this.columnConfig; + } +} diff --git a/packages/cfdi/designs/src/pdf/Grid.ts b/packages/cfdi/designs/src/pdf/Grid.ts new file mode 100644 index 00000000..70b18619 --- /dev/null +++ b/packages/cfdi/designs/src/pdf/Grid.ts @@ -0,0 +1,20 @@ +import { Content } from "pdfmake/interfaces"; +import { Row } from "./Row"; + +export class Grid { + private content: Content[] = []; + + addRow(row: Row): this { + this.content.push(row.toJSON()); + return this; + } + + addContent(content: string): this { + this.content.push(content); + return this; + } + + toJSON(): Content[] { + return this.content; + } + } \ No newline at end of file diff --git a/packages/cfdi/designs/src/pdf/Image.ts b/packages/cfdi/designs/src/pdf/Image.ts new file mode 100644 index 00000000..1c7b1022 --- /dev/null +++ b/packages/cfdi/designs/src/pdf/Image.ts @@ -0,0 +1,53 @@ +import { ContentImage } from 'pdfmake/interfaces'; + +export class Image { + private content: ContentImage; + + constructor(src: string) { + this.content = { image: src }; + } + + setWidth(width: number): this { + this.content.width = width; + return this; + } + + setHeight(height: number): this { + this.content.height = height; + return this; + } + + setFit(width: number, height: number): this { + this.content.fit = [width, height]; + return this; + } + + setAlignment(alignment: 'left' | 'center' | 'right'): this { + this.content.alignment = alignment; + return this; + } + + setMargin(margin: [number, number, number, number]): this { + this.content.margin = margin; + return this; + } + + setOpacity(opacity: number): this { + this.content.opacity = opacity; + return this; + } + + /* setBorder(top: boolean, right: boolean, bottom: boolean, left: boolean): this { + this.content.border = [top, right, bottom, left]; + return this; + } */ + + setStyle(style: string): this { + this.content.style = style; + return this; + } + + toJSON(): ContentImage { + return this.content; + } +} diff --git a/packages/cfdi/designs/src/pdf/PDF.ts b/packages/cfdi/designs/src/pdf/PDF.ts new file mode 100644 index 00000000..99d2edb3 --- /dev/null +++ b/packages/cfdi/designs/src/pdf/PDF.ts @@ -0,0 +1,109 @@ +import { TDocumentDefinitions, Content, BufferOptions } from 'pdfmake/interfaces'; +import pdfMake from "pdfmake/build/pdfmake"; +import pdfFonts from "pdfmake/build/vfs_fonts"; +// @ts-ignore +pdfMake.addVirtualFileSystem(pdfFonts); + + +interface ContentPDF extends TDocumentDefinitions{ + content: Content[]; +} +export class PDF { + definition: ContentPDF = { + pageSize: 'A4', + pageMargins: [20, 25, 20, 25], + content: [], + }; + + setContent(content: Content | Content[]): this { + this.definition.content = Array.isArray(content) ? content : [content]; + return this; + } + + addContent(content: Content | any): this { + this.definition.content.push(content); + return this; + } + + setStyles(styles: Record): this { + this.definition.styles = styles; + return this; + } + + setDefaultStyle(style: Record): this { + this.definition.defaultStyle = style; + return this; + } + + toJSON(): TDocumentDefinitions { + return this.definition; + } + + getDocument() { + //return pdfMake.createPdf(this.definition); + return pdfMake.createPdf(this.definition ); + + } + + public async save(path: string, name: string) { + const dir = path + `${name.replace('.pdf', '')}.pdf`; + try { + const buffer = await this.getBuffer(); + writeFileSync(dir, buffer, { encoding: 'binary' }); + return { + save: true, + path: dir, + }; + } catch (e) { + return { + save: false, + error: e, + }; + } + } + + public async getBlob(options?: BufferOptions): Promise { + return new Promise(async (resolve) => { + const doc = await this.getDocument(); + doc!.getBlob((result) => { + resolve(result); + }, options); + }); + } + + public async getBase64(options?: BufferOptions): Promise { + return new Promise(async (resolve) => { + const doc = await this.getDocument(); + doc!.getBase64((result) => { + resolve(result); + }, options); + }); + } + + public async getBuffer(options?: BufferOptions): Promise { + return new Promise(async (resolve) => { + const doc = await this.getDocument(); + doc!.getBuffer((result) => { + resolve(result); + }, options); + }); + } + + public async getDataUrl(options?: BufferOptions): Promise { + return new Promise(async (resolve) => { + const doc = await this.getDocument(); + doc!.getDataUrl((result) => { + resolve(result); + }, options); + }); + } + + public async getStream(options?: BufferOptions) { + const doc = await this.getDocument(); + return doc!.getStream(options); + } +} +function writeFileSync(dir: string, buffer: Buffer, arg2: { encoding: string; }) { + throw new Error('Function not implemented.'); +} + diff --git a/packages/cfdi/designs/src/pdf/Row.ts b/packages/cfdi/designs/src/pdf/Row.ts new file mode 100644 index 00000000..17cc2e5a --- /dev/null +++ b/packages/cfdi/designs/src/pdf/Row.ts @@ -0,0 +1,30 @@ +import { Content, ContentColumns, ContentStack } from 'pdfmake/interfaces'; +import { Column } from './Column'; + + +export class Row { + private columns: any[] = []; + private columnGap: number = 10; + + constructor(options?: any) { + if (options.children) { + this.columns = options.children; + } + } + addColumn(column: Column): this { + this.columns.push(column.toJSON()); + return this; + } + + setGap(gap: number): this { + + this.columnGap = gap + return this; + } + + toJSON(): Content { + return { columns: this.columns, columnGap: this.columnGap }; + } +} + + diff --git a/packages/cfdi/designs/src/pdf/Style.ts b/packages/cfdi/designs/src/pdf/Style.ts new file mode 100644 index 00000000..cc9dcb85 --- /dev/null +++ b/packages/cfdi/designs/src/pdf/Style.ts @@ -0,0 +1,69 @@ +import { Style as PdfStyle, ContentText } from 'pdfmake/interfaces'; + +export class Style { + private style: Partial = {}; + constructor(style: Partial = {}) { + this.style = style + } + + setFont(font: string): this { + this.style.font = font; + return this; + } + + setFontSize(size: number): this { + this.style.fontSize = size; + return this; + } + + setLineHeight(lineHeight: number): this { + this.style.lineHeight = lineHeight; + return this; + } + + setBold(isBold: boolean = true): this { + this.style.bold = isBold; + return this; + } + + setItalic(isItalic: boolean = true): this { + this.style.italics = isItalic; + return this; + } + + setAlignment(alignment: 'left' | 'right' | 'center' | 'justify'): this { + this.style.alignment = alignment; + return this; + } + + setColor(color: string): this { + this.style.color = color; + return this; + } + + setBackground(color: string): this { + this.style.background = color; + return this; + } + + setMargin(margin: number | [number, number, number, number]): this { + this.style.margin = margin; + return this; + } + + setOpacity(opacity: number): this { + this.style.opacity = opacity; + return this; + } + + setCharacterSpacing(spacing: number): this { + this.style.characterSpacing = spacing; + return this; + } + + toJSON(): Partial { + return this.style; + } +} + + diff --git a/packages/cfdi/designs/src/pdf/Table.ts b/packages/cfdi/designs/src/pdf/Table.ts new file mode 100644 index 00000000..f0219895 --- /dev/null +++ b/packages/cfdi/designs/src/pdf/Table.ts @@ -0,0 +1,76 @@ +import { ContentTable, Size, TableCell, TableLayout } from 'pdfmake/interfaces'; +import { Style } from './Style'; + +export class Table { + private content: ContentTable; + + constructor() { + this.content = { + table: { + body: [], + }, + }; + } + + setHeaderRow(headers: number): this { + this.content.table.headerRows = headers; + return this; + } + + setHeader(headers: (string | TableCell)[], style?: Style): this { + const headerRow = headers.map(cell => { + if (typeof cell === 'string') { + return { text: cell, ...(style ?? {}) }; + } else { + const cellStyle = style ? style.toJSON() : {}; + return { + ...(cell as unknown as Object), + // @ts-ignore + style: { ...cellStyle, ...(cell.style ?? {}) }, + }; + } + }); + this.content.table.body.unshift(headerRow); + return this; + } + + addRow(cells: (string | TableCell)[], style?: Style): this { + const rows = cells.map(cell => { + if (typeof cell === 'string') { + return { text: cell, ...(style ?? {}) }; + } else { + const cellStyle = style ? style.toJSON() : {}; + return { + ...(cell as unknown as Object), + // @ts-ignore + style: { ...cellStyle, ...(cell.style ?? {}) }, + }; + } + }); + this.content.table.body.push(rows); + return this; + } + + setLayout(layout: TableLayout): this { + this.content.layout = layout; + return this; + } + + setStyle(style: Style): this { + this.content = { ...this.content, style : style.toJSON()}; + return this; + } + + setMargin(margin: number | [number, number, number, number]): this { + this.content.margin = margin; + return this; + } + setWidths(widths: "*" | "auto" | Size[] | undefined ): this { + this.content.table.widths = widths; + return this; + } + + toJSON(): ContentTable { + return this.content; + } +} diff --git a/packages/cfdi/designs/src/pdf/Text.ts b/packages/cfdi/designs/src/pdf/Text.ts new file mode 100644 index 00000000..bcebe048 --- /dev/null +++ b/packages/cfdi/designs/src/pdf/Text.ts @@ -0,0 +1,48 @@ +import { ContentText } from 'pdfmake/interfaces'; +import { Style } from './Style'; + +export class Text { + private content: ContentText; + + constructor(text: string, style?: Style) { + this.content = { text }; + if (style) { + this.content.style = style.toJSON(); + } + } + + setBold(bold: boolean): this { + this.content.bold = bold; + return this; + } + + setMargin(margin: [number, number, number, number]): this { + this.content.margin = margin; + return this; + } + + + + setStyle(style: Style): this { + this.content.style = style.toJSON(); + return this; + } + + addText(text: string, style?: Style): this { + if (!Array.isArray(this.content.text)) { + let previousText = this.content.text; + let previousStyle = this.content.style ?? {}; + delete this.content.style; + this.content.text = [{ text: previousText, style: previousStyle }]; + } + + const fragment: ContentText = { text, ...(style ?? {}) }; + (this.content.text as ContentText[]).push(fragment); + + return this; + } + + toJSON(): ContentText { + return this.content; + } + } \ No newline at end of file diff --git a/packages/cfdi/designs/tsconfig.json b/packages/cfdi/designs/tsconfig.json new file mode 100644 index 00000000..1c6a17c1 --- /dev/null +++ b/packages/cfdi/designs/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "outDir": "dist", + "module": "ESNext", + "target": "ESNext", + "declaration": true, + "declarationDir": "dist", + "moduleResolution": "node", + "esModuleInterop": true, + "paths": { + "@cfdi/utils/*": [ + "./node_modules/@cfdi/utils/src", + "./node_modules/@cfdi/utils/src/*" + ], + "@cfdi/utils": [ + "./node_modules/@cfdi/utils/src" + ], + } + }, + "include": ["src"] + } + \ No newline at end of file diff --git a/packages/cfdi/designs/vite.config.ts b/packages/cfdi/designs/vite.config.ts new file mode 100644 index 00000000..ab07a917 --- /dev/null +++ b/packages/cfdi/designs/vite.config.ts @@ -0,0 +1,43 @@ +import { defineConfig } from "vite"; +import dts from "vite-plugin-dts"; +import terser from "@rollup/plugin-terser"; +import url from '@rollup/plugin-url'; + +export default defineConfig({ + build: { + //assetsInlineLimit: 0, + lib: { + entry: "src/index.ts", + formats: ["es", "cjs"], + fileName: (format) => `index.${format}.js`, + }, + rollupOptions: { + external: ['@cfdi/utils', 'pdfmake/build/pdfmake', 'pdfmake/interfaces', "pdfmake/build/vfs_fonts"], // Dependencias externas + plugins: [ + terser({ + compress: { + drop_console: true, // Elimina console.log + drop_debugger: true, // Elimina debugger + passes: 2, // Más agresivo + }, + mangle: { + properties: false, // Ofusca propiedades + keep_classnames: false, // No mantiene nombres de clases + keep_fnames: false, // No mantiene nombres de funciones + }, + format: { + comments: false, // Elimina comentarios + }, + }), + ], + }, + minify: "terser", + sourcemap: false, + target: "esnext", + }, + /* plugins: [ + dts({ + insertTypesEntry: true, + }) + ], */ +}); diff --git a/packages/cfdi/elements/README.md b/packages/cfdi/elements/README.md index 9f7b855e..9f4f20c7 100644 --- a/packages/cfdi/elements/README.md +++ b/packages/cfdi/elements/README.md @@ -1,205 +1,82 @@ -# CFDI +# @cfdi/elements -

- - Nest Logo -

-
    -
  • @cfdi/xml
  • +Elementos estructurales del comprobante CFDI. Define las constantes y clases base que representan los nodos XML de un CFDI 4.0. -
  • @cfdi/catalogos
  • @cfdi/csd
  • @cfdi/utils
  • @cfdi/pdf
  • @cfdi/curp +## Instalacion -
  • @cfdi/csf
  • -
  • @cfdi/rfc
-Documentacion -

- Este módulo genera un CFDI a partir de clases lo que facilita la creacion de XMl y sellarlo sin nigun problema de compatibilidad de las versiones 2.0 del xml de complementos. -

- -
- - - - -
- -Instala las dependencias and devDependencies y comienza a crear xml CFDI 4.0. -Para Windows Lea la Documentacion - -# Dependeces - -JDK - -```sh - sudo apt install default-jre - sudo apt install default-jdk -``` - -Openssl - -```sh - Debian/Ubuntu: sudo apt-get install openssl - CentOS, Red Hat: yum install openssl - Archlinux: sudo pacman -S openssl -``` - -Saxon-HE >=9.9.1.6J - -```sh - - official: http://saxon.sourceforge.net/ - Archlinux: https://aur.archlinux.org/packages/saxon-he - - Automatic Installation Alternative - - https://github.com/MisaelMa/saxon-he - sudo chmod 777 saxon.sh - sudo ./saxon.sh - - ███████╗ █████╗ ██╗ ██╗ ██████╗ ███╗ ██╗ ██╗ ██╗███████╗ - ██╔════╝██╔══██╗╚██╗██╔╝██╔═══██╗████╗ ██║ ██║ ██║██╔════╝ - ███████╗███████║ ╚███╔╝ ██║ ██║██╔██╗ ██║ ███████║█████╗ - ╚════██║██╔══██║ ██╔██╗ ██║ ██║██║╚██╗██║ ██╔══██║██╔══╝ - ███████║██║ ██║██╔╝ ██╗╚██████╔╝██║ ╚████║ ██║ ██║███████╗ - ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝ +```bash +npm install @cfdi/elements ``` -# Installation - -```sh -npm i --save @cfdi/xml +## Uso + +```typescript +import { Elemento } from '@cfdi/elements'; +import { + COMPROBANTE, + EMISOR, + RECEPTOR, + CONCEPTOS, + CONCEPTO, + IMPUESTOS, + TRASLADOS, + TRASLADO, + COMPLEMENTO, +} from '@cfdi/elements'; + +// Usar constantes de tags XML +console.log(COMPROBANTE); // 'cfdi:Comprobante' +console.log(EMISOR); // 'cfdi:Emisor' +console.log(RECEPTOR); // 'cfdi:Receptor' +console.log(CONCEPTOS); // 'cfdi:Conceptos' +console.log(CONCEPTO); // 'cfdi:Concepto' +console.log(IMPUESTOS); // 'cfdi:Impuestos' ``` -# Complementos - -## Información adicional para las Facturas - -- [x] :pushpin: Timbre fiscal digital (TFD). -- [ ] Estado de cuenta de combustibles de monederos electrónicos. -- [x] :pushpin: Donatarias. -- [x] :pushpin: Compra venta de divisas. -- [x] :pushpin: Otros derechos e impuestos. -- [x] :pushpin: Leyendas fiscales. -- [x] :pushpin: Persona física integrante de coordinado. -- [x] :pushpin: Turista pasajero extranjero. -- [x] :pushpin: Spei de tercero a tercero. -- [ ] Sector de ventas al detalle (Detallista). -- [x] :pushpin: CFDI Registro fiscal. -- [ ] Recibo de pago de nómina. -- [x] :pushpin: Pago en especie. -- [x] :pushpin: Vales de despensa. -- [x] :pushpin: Consumo de combustibles. versión 1.1 -- [x] :pushpin: Aerolíneas. -- [ ] Notarios Públicos. -- [x] :pushpin: Vehículo usado. -- [x] :pushpin: Servicios parciales de construcción. -- [x] :pushpin: Renovación y sustitución de vehículos. -- [x] :pushpin: Certificado de destrucción -- [x] :pushpin: Obras de arte plásticas y antigüedades -- [x] :pushpin: INE -- [x] :pushpin: Comercio Exterior versión 1.1 -- [x] :pushpin: Recepción de pagos -- [x] Hidrocarburos - - [x] :pushpin: IngresosHidrocarburos - - [x] :pushpin: GastosHidrocarburos10 - -## Complementos de Concepto - -- [x] :pushpin: Instituciones educativas privadas. -- [ ] Venta de vehículos. -- [ ] Terceros. -- [ ] Acreditamiento del IEPS - -# Informacion Oficial - -- Certificados de prueba - http://omawww.sat.gob.mx/tramitesyservicios/Paginas/certificado_sello_digital.htm -- Anexo 20 - http://omawww.sat.gob.mx/tramitesyservicios/Paginas/anexo_20_version3-3.htm -- Catálogo de productos y servicios - http://pys.sat.gob.mx/PyS/catPyS.aspx -- Catálogo de unidades de medida - http://pys.sat.gob.mx/PyS/catUnidades.aspx -- Consulta los complementos y complementos concepto de factura +### Clase Elemento -https://www.sat.gob.mx/consultas/49522/complementos-y-complementos-concepto-de-factura- +Clase generica base para representar nodos XML con prefijo de namespace. -https://www.sat.gob.mx/cs/Satellite?blobcol=urldata&blobkey=id&blobtable=MungoBlobs&blobwhere=1461173971924&ssbinary=true +```typescript +const concepto = new Elemento('cfdi:Concepto'); -# Generar archivos .pem - -Lo primero que se necesita es tener instalada la librería OpenSSL (programa dedicado a la generación y tratado de claves, certificados y keyStore) para poder utilizar los comandos que nos ayudarán a crear las llaves de nuestros sellos digitales. - -## Linux - -Instalar librería: - -Debian/Ubuntu: #sudo apt-get install openssl - -CentOS, Red Hat: #yum install openssl - -Ejecutar las instrucciones: - -Archivo key.pem - -```sh -openssl pkcs8 -inform DER -in nombrearchivo.key -out nombrearchivo.key.pem -passin pass:contraseña -``` - -archivo cer.pem - -```sh -openssl x509 -inform DER -outform PEM -in ruta/nombreArchivo.cer -pubkey -out ruta/nombreArchivo.cer.pem +concepto.tag(); // 'cfdi:Concepto' +concepto.prefix(); // 'cfdi' +concepto.name(); // 'Concepto' ``` -## Windows +### Complementos -Descargar libreria: http://slproweb.com/products/Win32OpenSSL.html +El paquete tambien exporta elementos de complementos como Carta Porte 3.1 y Vehiculo Usado. -Deberán descargar la versión según su sistema operativo, e instalar. - -Ejecutar desde terminal - -Archivo key.pem - -```sh -openssl.exe pkcs8 -inform DER -in ruta/nombreArchivo.key -passin pass:contraseña -out ruta/nombreArchivo.key.pem -``` - -archivo cer.pem - -```sh -openssl.exe x509 -inform DER -outform PEM -in ruta/nombreArchivo.cer -pubkey -out ruta/nombreArchivo.cer.pem +```typescript +import { CartaPorte31, VehiculoUsado } from '@cfdi/elements'; ``` -# Generar QR - -ESPECIFICACIÓN TÉCNICA DEL CÓDIGO DE BARRAS BIDIMENSIONAL A INCORPORAR EN LA REPRESENTACIÓN IMPRESA. - -Las representaciones impresas de los dos tipos de comprobantes fiscales digitales por Internet deben incluir un código de barras bidimensional conforme al formato de QR Code (Quick Response Code),usando la capacidad de corrección de error con nivel mínimo M, descrito en el estándar ISO/IEC18004, con base en los siguientes lineamientos. - -a) Debe contener los siguientes datos en la siguiente secuencia: - - *La URL del acceso al servicio que pueda mostrar los datos de la versión publica del comprobante. - *Numero de folio fiscal del comprobante (UUID). - *RFC del emisor. - *RFC del receptor. - *Ocho últimos caracteres del sello digital del emisor del comprobante. - -Donde se manejan / caracteres conformados de la siguiente manera: +## API -

- The house from the offer. -

+### Constantes -De esta manera se generan los datos validos para realizar una consulta de un CFDI por medio de su expresión impresa. +| Constante | Valor | +|-----------|-------| +| `COMPROBANTE` | `'cfdi:Comprobante'` | +| `EMISOR` | `'cfdi:Emisor'` | +| `RECEPTOR` | `'cfdi:Receptor'` | +| `CONCEPTOS` | `'cfdi:Conceptos'` | +| `CONCEPTO` | `'cfdi:Concepto'` | +| `IMPUESTOS` | `'cfdi:Impuestos'` | +| `TRASLADOS` | `'cfdi:Traslados'` | +| `TRASLADO` | `'cfdi:Traslado'` | +| `COMPLEMENTO` | `'cfdi:Complemento'` | -Ejemplo: +### Clase `Elemento` -https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=5803EB8D-81CD-4557-8719-26632D2FA434&re=XAXX010101000&rr=CARR861127SB0&tt=0000014300.000000&fe=rH8/bw== +| Metodo | Retorno | Descripcion | +|--------|---------|-------------| +| `tag()` | `string` | Nombre completo del tag (ej. `cfdi:Concepto`) | +| `prefix()` | `string` | Prefijo del namespace (ej. `cfdi`) | +| `name()` | `string` | Nombre del elemento sin prefijo (ej. `Concepto`) | -El código de barras bidimensional debe ser impreso en un cuadro con lados no menores a 2.75 centímetros. +## Licencia -

-The house from the offer. -

+[MIT](../../LICENSE) diff --git a/packages/cfdi/elements/config/index.js b/packages/cfdi/elements/config/index.js deleted file mode 100644 index 7dee80b9..00000000 --- a/packages/cfdi/elements/config/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict' -module.exports = require('./elements.cjs.production.min.js') diff --git a/packages/cfdi/elements/package.json b/packages/cfdi/elements/package.json index 18b34522..a1706112 100644 --- a/packages/cfdi/elements/package.json +++ b/packages/cfdi/elements/package.json @@ -4,9 +4,9 @@ "description": "Libreria para crear y sellar xml cfdi V4.0", "homepage": "https://cfdi.recreando.dev", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/elements.esm.production.min.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "release": { "branches": [ @@ -27,42 +27,15 @@ "url": "https://github.com/MisaelMa/recreando" }, "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build --env production --minify && rimraf ./dist/index.js ./dist/elements.cjs.development.* && npm run cp", - "cp": "cp ./config/index.js ./dist", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", "test:coverage": "vitest run --coverage", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" + "test:ui": "vitest --ui" }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/elements.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/elements.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "@cfdi/catalogos": "workspace:*", "@cfdi/csd": "workspace:*", @@ -72,18 +45,11 @@ "xml-js": "^1.6.11" }, "devDependencies": { - "rimraf": "^6.0.1", "@recreando/vite": "workspace:*", "@recreando/eslint-settings": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@types/node": "^18.11.3", + "@types/node": "^22", "eslint": "^8.57.0", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/elements/vite.config.mts b/packages/cfdi/elements/vite.config.mts new file mode 100644 index 00000000..78f30cf9 --- /dev/null +++ b/packages/cfdi/elements/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xml-js'], + }, + }, +})); diff --git a/packages/cfdi/estado/dist/consultarEstado.d.ts b/packages/cfdi/estado/dist/consultarEstado.d.ts new file mode 100644 index 00000000..44dde90e --- /dev/null +++ b/packages/cfdi/estado/dist/consultarEstado.d.ts @@ -0,0 +1,3 @@ +import { ConsultaParams, ConsultaResult } from './types'; +export declare function consultarEstado(params: ConsultaParams): Promise; +//# sourceMappingURL=consultarEstado.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/estado/dist/consultarEstado.d.ts.map b/packages/cfdi/estado/dist/consultarEstado.d.ts.map new file mode 100644 index 00000000..35df7424 --- /dev/null +++ b/packages/cfdi/estado/dist/consultarEstado.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"consultarEstado.d.ts","sourceRoot":"","sources":["../src/consultarEstado.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAY9D,wBAAsB,eAAe,CACnC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,cAAc,CAAC,CAsCzB"} \ No newline at end of file diff --git a/packages/cfdi/estado/dist/index.d.ts b/packages/cfdi/estado/dist/index.d.ts new file mode 100644 index 00000000..4b1eae3c --- /dev/null +++ b/packages/cfdi/estado/dist/index.d.ts @@ -0,0 +1,4 @@ +export * from './types'; +export * from './soap'; +export * from './consultarEstado'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/estado/dist/index.d.ts.map b/packages/cfdi/estado/dist/index.d.ts.map new file mode 100644 index 00000000..2a54e18a --- /dev/null +++ b/packages/cfdi/estado/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,mBAAmB,CAAC"} \ No newline at end of file diff --git a/packages/cfdi/estado/dist/index.mjs b/packages/cfdi/estado/dist/index.mjs new file mode 100644 index 00000000..835875d1 --- /dev/null +++ b/packages/cfdi/estado/dist/index.mjs @@ -0,0 +1,82 @@ +const l = "https://consultaqr.facturaelectronica.sat.gob.mx/ConsultaCFDIService.svc", d = "http://tempuri.org/IConsultaCFDIService/Consulta"; +function u(t) { + const e = parseFloat(t); + if (isNaN(e)) + throw new Error(`Total invalido: '${t}'`); + const r = e.toFixed(6), [o, n] = r.split("."); + return `${o.padStart(10, "0")}.${n}`; +} +function p(t) { + const { rfcEmisor: e, rfcReceptor: r, total: o, uuid: n } = t, a = u(o); + return ` + + + + + + + +`; +} +function c(t, e) { + const r = new RegExp( + `<(?:[a-zA-Z0-9_]+:)?${e}[^>]*>([\\s\\S]*?)<\\/(?:[a-zA-Z0-9_]+:)?${e}>`, + "i" + ), o = t.match(r); + return o ? o[1].trim() : ""; +} +function E(t) { + if (t.includes("") || t.includes("")) { + const s = c(t, "faultstring"); + throw new Error(`SOAP Fault: ${s || "Error desconocido del servicio"}`); + } + const e = c(t, "CodigoEstatus"), r = c(t, "EsCancelable"), o = c(t, "Estado"), n = c(t, "EstatusCancelacion"), a = c(t, "ValidacionEFOS"); + return { + codigoEstatus: e, + esCancelable: r, + estado: o, + estatusCancelacion: n, + validacionEFOS: a, + activo: o === "Vigente", + cancelado: o === "Cancelado", + noEncontrado: o === "No Encontrado" + }; +} +const i = 3e4; +async function m(t) { + const e = p(t), r = new AbortController(), o = setTimeout(() => r.abort(), i); + let n; + try { + n = await fetch(l, { + method: "POST", + headers: { + "Content-Type": "text/xml; charset=utf-8", + SOAPAction: d + }, + body: e, + signal: r.signal + }); + } catch (s) { + throw s instanceof Error && s.name === "AbortError" ? new Error( + `Timeout: el webservice del SAT no respondio en ${i / 1e3} segundos` + ) : new Error( + `Error de red al consultar el estado del CFDI: ${s instanceof Error ? s.message : String(s)}` + ); + } finally { + clearTimeout(o); + } + if (!n.ok) + throw new Error( + `El webservice del SAT retorno HTTP ${n.status}: ${n.statusText}` + ); + const a = await n.text(); + return E(a); +} +export { + d as SOAP_ACTION, + l as WEBSERVICE_URL, + p as buildSoapRequest, + m as consultarEstado, + u as formatTotal, + E as parseSoapResponse +}; diff --git a/packages/cfdi/estado/dist/soap.d.ts b/packages/cfdi/estado/dist/soap.d.ts new file mode 100644 index 00000000..e3036877 --- /dev/null +++ b/packages/cfdi/estado/dist/soap.d.ts @@ -0,0 +1,8 @@ +import { ConsultaParams, ConsultaResult } from './types'; +declare const WEBSERVICE_URL = "https://consultaqr.facturaelectronica.sat.gob.mx/ConsultaCFDIService.svc"; +declare const SOAP_ACTION = "http://tempuri.org/IConsultaCFDIService/Consulta"; +export declare function formatTotal(total: string): string; +export declare function buildSoapRequest(params: ConsultaParams): string; +export declare function parseSoapResponse(xml: string): ConsultaResult; +export { WEBSERVICE_URL, SOAP_ACTION }; +//# sourceMappingURL=soap.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/estado/dist/soap.d.ts.map b/packages/cfdi/estado/dist/soap.d.ts.map new file mode 100644 index 00000000..850a163b --- /dev/null +++ b/packages/cfdi/estado/dist/soap.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"soap.d.ts","sourceRoot":"","sources":["../src/soap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9D,QAAA,MAAM,cAAc,6EACwD,CAAC;AAC7E,QAAA,MAAM,WAAW,qDACmC,CAAC;AAOrD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD;AAKD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAc/D;AAmBD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAsB7D;AAED,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC"} \ No newline at end of file diff --git a/packages/cfdi/estado/dist/types.d.ts b/packages/cfdi/estado/dist/types.d.ts new file mode 100644 index 00000000..a0398b8a --- /dev/null +++ b/packages/cfdi/estado/dist/types.d.ts @@ -0,0 +1,17 @@ +export interface ConsultaParams { + rfcEmisor: string; + rfcReceptor: string; + total: string; + uuid: string; +} +export interface ConsultaResult { + codigoEstatus: string; + esCancelable: string; + estado: string; + estatusCancelacion: string; + validacionEFOS: string; + activo: boolean; + cancelado: boolean; + noEncontrado: boolean; +} +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/packages/cfdi/estado/dist/types.d.ts.map b/packages/cfdi/estado/dist/types.d.ts.map new file mode 100644 index 00000000..05aad1b9 --- /dev/null +++ b/packages/cfdi/estado/dist/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB"} \ No newline at end of file diff --git a/packages/cfdi/estado/package.json b/packages/cfdi/estado/package.json new file mode 100644 index 00000000..f2689a17 --- /dev/null +++ b/packages/cfdi/estado/package.json @@ -0,0 +1,35 @@ +{ + "name": "@cfdi/estado", + "version": "0.0.1", + "license": "MIT", + "main": "src/index.ts", + "module": "src/index.ts", + "types": "src/index.ts", + "source": "src/index.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build --config node_modules/@recreando/vite/vite.config.lib.mts", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/cfdi/estado/src/consultarEstado.ts b/packages/cfdi/estado/src/consultarEstado.ts new file mode 100644 index 00000000..6e318129 --- /dev/null +++ b/packages/cfdi/estado/src/consultarEstado.ts @@ -0,0 +1,53 @@ +import type { ConsultaParams, ConsultaResult } from './types'; +import { buildSoapRequest, parseSoapResponse, WEBSERVICE_URL, SOAP_ACTION } from './soap'; + +const TIMEOUT_MS = 30_000; + +/** + * Consulta el estado de un CFDI en el webservice del SAT. + * + * @param params - RFC emisor, RFC receptor, total y UUID del CFDI. + * @returns Resultado con el estado actual del comprobante y helpers booleanos. + * @throws Error si hay un problema de red, timeout o respuesta SOAP invalida. + */ +export async function consultarEstado( + params: ConsultaParams +): Promise { + const body = buildSoapRequest(params); + + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), TIMEOUT_MS); + + let response: Response; + try { + response = await fetch(WEBSERVICE_URL, { + method: 'POST', + headers: { + 'Content-Type': 'text/xml; charset=utf-8', + SOAPAction: SOAP_ACTION, + }, + body, + signal: controller.signal, + }); + } catch (err: unknown) { + if (err instanceof Error && err.name === 'AbortError') { + throw new Error( + `Timeout: el webservice del SAT no respondio en ${TIMEOUT_MS / 1000} segundos` + ); + } + throw new Error( + `Error de red al consultar el estado del CFDI: ${err instanceof Error ? err.message : String(err)}` + ); + } finally { + clearTimeout(timer); + } + + if (!response.ok) { + throw new Error( + `El webservice del SAT retorno HTTP ${response.status}: ${response.statusText}` + ); + } + + const xml = await response.text(); + return parseSoapResponse(xml); +} diff --git a/packages/cfdi/estado/src/index.ts b/packages/cfdi/estado/src/index.ts new file mode 100644 index 00000000..d7135fc5 --- /dev/null +++ b/packages/cfdi/estado/src/index.ts @@ -0,0 +1,3 @@ +export * from './types'; +export * from './soap'; +export * from './consultarEstado'; diff --git a/packages/cfdi/estado/src/soap.ts b/packages/cfdi/estado/src/soap.ts new file mode 100644 index 00000000..62b3e99e --- /dev/null +++ b/packages/cfdi/estado/src/soap.ts @@ -0,0 +1,86 @@ +import type { ConsultaParams, ConsultaResult } from './types'; + +const WEBSERVICE_URL = + 'https://consultaqr.facturaelectronica.sat.gob.mx/ConsultaCFDIService.svc'; +const SOAP_ACTION = + 'http://tempuri.org/IConsultaCFDIService/Consulta'; + +/** + * Formatea el total del CFDI al formato requerido por el SAT: + * 17 caracteres totales, 6 decimales, relleno con ceros a la izquierda. + * Ejemplo: '1000.00' → '0000001000.000000' + */ +export function formatTotal(total: string): string { + const num = parseFloat(total); + if (isNaN(num)) { + throw new Error(`Total invalido: '${total}'`); + } + // Separar la parte entera y decimal con 6 decimales fijos + const fixed = num.toFixed(6); + const [integer, decimal] = fixed.split('.'); + // La parte entera debe ocupar 10 caracteres (17 total - 1 punto - 6 decimales) + const paddedInteger = integer.padStart(10, '0'); + return `${paddedInteger}.${decimal}`; +} + +/** + * Construye el envelope SOAP para consultar el estado de un CFDI. + */ +export function buildSoapRequest(params: ConsultaParams): string { + const { rfcEmisor, rfcReceptor, total, uuid } = params; + const totalFormateado = formatTotal(total); + const expresion = `?re=${rfcEmisor}&rr=${rfcReceptor}&tt=${totalFormateado}&id=${uuid}`; + + return ` + + + + + + + +`; +} + +/** + * Extrae el contenido de texto de una etiqueta XML por su nombre local. + * Soporta namespaces (e.g., Vigente). + */ +function extractTag(xml: string, localName: string): string { + const pattern = new RegExp( + `<(?:[a-zA-Z0-9_]+:)?${localName}[^>]*>([\\s\\S]*?)<\\/(?:[a-zA-Z0-9_]+:)?${localName}>`, + 'i' + ); + const match = xml.match(pattern); + return match ? match[1].trim() : ''; +} + +/** + * Parsea la respuesta SOAP del SAT y retorna un ConsultaResult. + * Lanza un Error si la respuesta contiene un Fault SOAP. + */ +export function parseSoapResponse(xml: string): ConsultaResult { + if (xml.includes('') || xml.includes('')) { + const faultString = extractTag(xml, 'faultstring'); + throw new Error(`SOAP Fault: ${faultString || 'Error desconocido del servicio'}`); + } + + const codigoEstatus = extractTag(xml, 'CodigoEstatus'); + const esCancelable = extractTag(xml, 'EsCancelable'); + const estado = extractTag(xml, 'Estado'); + const estatusCancelacion = extractTag(xml, 'EstatusCancelacion'); + const validacionEFOS = extractTag(xml, 'ValidacionEFOS'); + + return { + codigoEstatus, + esCancelable, + estado, + estatusCancelacion, + validacionEFOS, + activo: estado === 'Vigente', + cancelado: estado === 'Cancelado', + noEncontrado: estado === 'No Encontrado', + }; +} + +export { WEBSERVICE_URL, SOAP_ACTION }; diff --git a/packages/cfdi/estado/src/types.ts b/packages/cfdi/estado/src/types.ts new file mode 100644 index 00000000..479f4f28 --- /dev/null +++ b/packages/cfdi/estado/src/types.ts @@ -0,0 +1,17 @@ +export interface ConsultaParams { + rfcEmisor: string; + rfcReceptor: string; + total: string; + uuid: string; +} + +export interface ConsultaResult { + codigoEstatus: string; + esCancelable: string; + estado: string; + estatusCancelacion: string; + validacionEFOS: string; + activo: boolean; + cancelado: boolean; + noEncontrado: boolean; +} diff --git a/packages/cfdi/estado/test/estado.test.ts b/packages/cfdi/estado/test/estado.test.ts new file mode 100644 index 00000000..3d334260 --- /dev/null +++ b/packages/cfdi/estado/test/estado.test.ts @@ -0,0 +1,171 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { consultarEstado } from '../src/consultarEstado'; + +const RESPONSE_VIGENTE = ` + + + + + S - Comprobante obtenido satisfactoriamente. + Cancelable con aceptación + Vigente + + 200 + + + +`; + +const RESPONSE_CANCELADO = ` + + + + + S - Comprobante obtenido satisfactoriamente. + No cancelable + Cancelado + Cancelado sin aceptación + 200 + + + +`; + +const PARAMS = { + rfcEmisor: 'AAA010101AAA', + rfcReceptor: 'BBB020202BBB', + total: '1000.00', + uuid: 'CEE4BE01-ADFA-4DEB-8421-ADD60F0BEDAC', +}; + +function mockFetchOk(body: string, status = 200) { + return vi.fn().mockResolvedValue({ + ok: status >= 200 && status < 300, + status, + statusText: status === 200 ? 'OK' : 'Error', + text: () => Promise.resolve(body), + }); +} + +describe('consultarEstado', () => { + beforeEach(() => { + vi.stubGlobal('fetch', undefined); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('retorna resultado vigente cuando el SAT responde correctamente', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_VIGENTE)); + + const result = await consultarEstado(PARAMS); + + expect(result.estado).toBe('Vigente'); + expect(result.activo).toBe(true); + expect(result.cancelado).toBe(false); + expect(result.noEncontrado).toBe(false); + expect(result.codigoEstatus).toBe( + 'S - Comprobante obtenido satisfactoriamente.' + ); + expect(result.validacionEFOS).toBe('200'); + }); + + it('retorna resultado cancelado cuando el CFDI esta cancelado', async () => { + vi.stubGlobal('fetch', mockFetchOk(RESPONSE_CANCELADO)); + + const result = await consultarEstado(PARAMS); + + expect(result.estado).toBe('Cancelado'); + expect(result.activo).toBe(false); + expect(result.cancelado).toBe(true); + expect(result.noEncontrado).toBe(false); + expect(result.estatusCancelacion).toBe('Cancelado sin aceptación'); + }); + + it('llama a fetch con el Content-Type correcto', async () => { + const fetchMock = mockFetchOk(RESPONSE_VIGENTE); + vi.stubGlobal('fetch', fetchMock); + + await consultarEstado(PARAMS); + + expect(fetchMock).toHaveBeenCalledOnce(); + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect((options.headers as Record)['Content-Type']).toBe( + 'text/xml; charset=utf-8' + ); + }); + + it('llama a fetch con el SOAPAction correcto', async () => { + const fetchMock = mockFetchOk(RESPONSE_VIGENTE); + vi.stubGlobal('fetch', fetchMock); + + await consultarEstado(PARAMS); + + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect((options.headers as Record)['SOAPAction']).toBe( + 'http://tempuri.org/IConsultaCFDIService/Consulta' + ); + }); + + it('llama a fetch con el metodo POST', async () => { + const fetchMock = mockFetchOk(RESPONSE_VIGENTE); + vi.stubGlobal('fetch', fetchMock); + + await consultarEstado(PARAMS); + + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect(options.method).toBe('POST'); + }); + + it('llama a la URL correcta del webservice del SAT', async () => { + const fetchMock = mockFetchOk(RESPONSE_VIGENTE); + vi.stubGlobal('fetch', fetchMock); + + await consultarEstado(PARAMS); + + const [url] = fetchMock.mock.calls[0] as [string, RequestInit]; + expect(url).toBe( + 'https://consultaqr.facturaelectronica.sat.gob.mx/ConsultaCFDIService.svc' + ); + }); + + it('lanza error cuando HTTP retorna un status de error', async () => { + vi.stubGlobal('fetch', mockFetchOk('Internal Server Error', 500)); + + await expect(consultarEstado(PARAMS)).rejects.toThrow('HTTP 500'); + }); + + it('lanza error cuando hay un error de red', async () => { + vi.stubGlobal( + 'fetch', + vi.fn().mockRejectedValue(new Error('ECONNREFUSED')) + ); + + await expect(consultarEstado(PARAMS)).rejects.toThrow( + 'Error de red al consultar el estado del CFDI' + ); + }); + + it('lanza error de timeout cuando fetch es abortado', async () => { + const abortError = new Error('The operation was aborted'); + abortError.name = 'AbortError'; + vi.stubGlobal('fetch', vi.fn().mockRejectedValue(abortError)); + + await expect(consultarEstado(PARAMS)).rejects.toThrow('Timeout'); + }); + + it('el body del SOAP contiene los RFC y UUID correctos', async () => { + const fetchMock = mockFetchOk(RESPONSE_VIGENTE); + vi.stubGlobal('fetch', fetchMock); + + await consultarEstado(PARAMS); + + const [, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + const body = options.body as string; + expect(body).toContain('re=AAA010101AAA'); + expect(body).toContain('rr=BBB020202BBB'); + expect(body).toContain('id=CEE4BE01-ADFA-4DEB-8421-ADD60F0BEDAC'); + expect(body).toContain('tt=0000001000.000000'); + }); +}); diff --git a/packages/cfdi/estado/test/soap.test.ts b/packages/cfdi/estado/test/soap.test.ts new file mode 100644 index 00000000..5874d634 --- /dev/null +++ b/packages/cfdi/estado/test/soap.test.ts @@ -0,0 +1,240 @@ +import { describe, it, expect } from 'vitest'; +import { buildSoapRequest, formatTotal, parseSoapResponse } from '../src/soap'; + +// --------------------------------------------------------------------------- +// formatTotal +// --------------------------------------------------------------------------- +describe('formatTotal', () => { + it('formatea un entero sin decimales', () => { + expect(formatTotal('1000')).toBe('0000001000.000000'); + }); + + it('formatea con dos decimales', () => { + expect(formatTotal('1000.00')).toBe('0000001000.000000'); + }); + + it('formatea con decimales parciales', () => { + expect(formatTotal('250.5')).toBe('0000000250.500000'); + }); + + it('formatea cero', () => { + expect(formatTotal('0')).toBe('0000000000.000000'); + }); + + it('formatea un monto grande', () => { + expect(formatTotal('9999999999.999999')).toBe('9999999999.999999'); + }); + + it('lanza error con un valor no numerico', () => { + expect(() => formatTotal('abc')).toThrow('Total invalido'); + }); +}); + +// --------------------------------------------------------------------------- +// buildSoapRequest +// --------------------------------------------------------------------------- +describe('buildSoapRequest', () => { + const params = { + rfcEmisor: 'AAA010101AAA', + rfcReceptor: 'BBB020202BBB', + total: '1000.00', + uuid: 'CEE4BE01-ADFA-4DEB-8421-ADD60F0BEDAC', + }; + + it('genera un envelope SOAP valido', () => { + const xml = buildSoapRequest(params); + expect(xml).toContain('soap:Envelope'); + expect(xml).toContain('soap:Body'); + expect(xml).toContain('tem:Consulta'); + expect(xml).toContain('tem:expresionImpresa'); + }); + + it('incluye el namespace de tempuri', () => { + const xml = buildSoapRequest(params); + expect(xml).toContain('xmlns:tem="http://tempuri.org/"'); + }); + + it('incluye todos los parametros en la expresion impresa', () => { + const xml = buildSoapRequest(params); + expect(xml).toContain('re=AAA010101AAA'); + expect(xml).toContain('rr=BBB020202BBB'); + expect(xml).toContain('tt=0000001000.000000'); + expect(xml).toContain('id=CEE4BE01-ADFA-4DEB-8421-ADD60F0BEDAC'); + }); + + it('envuelve la expresion en CDATA', () => { + const xml = buildSoapRequest(params); + expect(xml).toContain(''); + }); + + it('la expresion comienza con ?re=', () => { + const xml = buildSoapRequest(params); + expect(xml).toContain(' + + + + + S - Comprobante obtenido satisfactoriamente. + Cancelable con aceptación + Vigente + + 200 + + + +`; + +const RESPONSE_CANCELADO = ` + + + + + S - Comprobante obtenido satisfactoriamente. + No cancelable + Cancelado + Cancelado sin aceptación + 200 + + + +`; + +const RESPONSE_NO_ENCONTRADO = ` + + + + + N - 601: La expresión impresa proporcionada no es válida. + + No Encontrado + + + + + +`; + +const RESPONSE_SOAP_FAULT = ` + + + + s:Client + Error en la peticion + + +`; + +describe('parseSoapResponse', () => { + describe('CFDI Vigente', () => { + it('extrae el codigo de estatus', () => { + const result = parseSoapResponse(RESPONSE_VIGENTE); + expect(result.codigoEstatus).toBe( + 'S - Comprobante obtenido satisfactoriamente.' + ); + }); + + it('extrae esCancelable', () => { + const result = parseSoapResponse(RESPONSE_VIGENTE); + expect(result.esCancelable).toBe('Cancelable con aceptación'); + }); + + it('extrae el estado como Vigente', () => { + const result = parseSoapResponse(RESPONSE_VIGENTE); + expect(result.estado).toBe('Vigente'); + }); + + it('estatusCancelacion vacio', () => { + const result = parseSoapResponse(RESPONSE_VIGENTE); + expect(result.estatusCancelacion).toBe(''); + }); + + it('extrae validacionEFOS', () => { + const result = parseSoapResponse(RESPONSE_VIGENTE); + expect(result.validacionEFOS).toBe('200'); + }); + + it('helper activo es true', () => { + const result = parseSoapResponse(RESPONSE_VIGENTE); + expect(result.activo).toBe(true); + }); + + it('helper cancelado es false', () => { + const result = parseSoapResponse(RESPONSE_VIGENTE); + expect(result.cancelado).toBe(false); + }); + + it('helper noEncontrado es false', () => { + const result = parseSoapResponse(RESPONSE_VIGENTE); + expect(result.noEncontrado).toBe(false); + }); + }); + + describe('CFDI Cancelado', () => { + it('extrae el estado como Cancelado', () => { + const result = parseSoapResponse(RESPONSE_CANCELADO); + expect(result.estado).toBe('Cancelado'); + }); + + it('extrae estatusCancelacion', () => { + const result = parseSoapResponse(RESPONSE_CANCELADO); + expect(result.estatusCancelacion).toBe('Cancelado sin aceptación'); + }); + + it('helper activo es false', () => { + const result = parseSoapResponse(RESPONSE_CANCELADO); + expect(result.activo).toBe(false); + }); + + it('helper cancelado es true', () => { + const result = parseSoapResponse(RESPONSE_CANCELADO); + expect(result.cancelado).toBe(true); + }); + + it('helper noEncontrado es false', () => { + const result = parseSoapResponse(RESPONSE_CANCELADO); + expect(result.noEncontrado).toBe(false); + }); + }); + + describe('CFDI No Encontrado', () => { + it('extrae el estado como No Encontrado', () => { + const result = parseSoapResponse(RESPONSE_NO_ENCONTRADO); + expect(result.estado).toBe('No Encontrado'); + }); + + it('helper activo es false', () => { + const result = parseSoapResponse(RESPONSE_NO_ENCONTRADO); + expect(result.activo).toBe(false); + }); + + it('helper cancelado es false', () => { + const result = parseSoapResponse(RESPONSE_NO_ENCONTRADO); + expect(result.cancelado).toBe(false); + }); + + it('helper noEncontrado es true', () => { + const result = parseSoapResponse(RESPONSE_NO_ENCONTRADO); + expect(result.noEncontrado).toBe(true); + }); + }); + + describe('SOAP Fault', () => { + it('lanza error cuando hay un SOAP Fault', () => { + expect(() => parseSoapResponse(RESPONSE_SOAP_FAULT)).toThrow('SOAP Fault'); + }); + + it('incluye el mensaje de faultstring en el error', () => { + expect(() => parseSoapResponse(RESPONSE_SOAP_FAULT)).toThrow( + 'Error en la peticion' + ); + }); + }); +}); diff --git a/packages/cfdi/estado/tsconfig.json b/packages/cfdi/estado/tsconfig.json new file mode 100644 index 00000000..53e2475f --- /dev/null +++ b/packages/cfdi/estado/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "lib": ["dom", "esnext"], + "types": [ "node" ], + "importHelpers": true, + // output .d.ts declaration files for consumers + "declaration": true, + // output .js.map sourcemap files for consumers + "sourceMap": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + } +} diff --git a/packages/cfdi/curp/vitest.config.mts b/packages/cfdi/estado/vitest.config.mts similarity index 100% rename from packages/cfdi/curp/vitest.config.mts rename to packages/cfdi/estado/vitest.config.mts diff --git a/packages/cfdi/expresiones/README.md b/packages/cfdi/expresiones/README.md index 9487075c..478e20e5 100644 --- a/packages/cfdi/expresiones/README.md +++ b/packages/cfdi/expresiones/README.md @@ -1 +1,59 @@ -utils +# @cfdi/expresiones + +Generacion de expresiones impresas del CFDI para verificacion y codigos QR. Procesa un archivo XML de CFDI y extrae los valores necesarios para construir la cadena de verificacion. + +## Instalacion + +```bash +npm install @cfdi/expresiones +``` + +## Uso + +```typescript +import { Transform } from '@cfdi/expresiones'; + +// Cargar archivo XML del CFDI +const transform = new Transform(); +transform.s('/ruta/al/cfdi.xml'); + +// Generar la expresion impresa +const expresion = await transform.run(); +// Resultado: ||valor1|valor2|valor3|...|| +``` + +### Ejemplo completo + +```typescript +import { Transform } from '@cfdi/expresiones'; + +const transform = new Transform(); + +// Cargar el XML (usa @cfdi/2json internamente para parsear) +transform.s('/ruta/factura.xml'); + +// Configurar advertencias (opcional) +transform.warnings('silent'); + +// Obtener la expresion impresa +const cadena = await transform.run(); +console.log(cadena); +// ||4.0|2024-01-15T12:00:00|01|1000.00|...|| +``` + +## API + +### Clase `Transform` + +| Metodo | Retorno | Descripcion | +|--------|---------|-------------| +| `s(archivo)` | `Transform` | Carga y parsea un archivo XML de CFDI | +| `run()` | `Promise` | Genera la expresion impresa con formato `\|\|valor1\|valor2\|...\|\|` | +| `json(xslPath)` | `Transform` | Establece la ruta del archivo XSLT | +| `warnings(type)` | `Transform` | Configura el nivel de advertencias | + +La expresion generada contiene los valores del comprobante en orden: atributos, emisor, receptor, conceptos, impuestos y complemento. Se omiten automaticamente los namespaces, esquemas, certificado y sello. + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/expresiones/config/index.js b/packages/cfdi/expresiones/config/index.js deleted file mode 100644 index c3028c25..00000000 --- a/packages/cfdi/expresiones/config/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict' -module.exports = require('./expresiones.cjs.production.min.js') diff --git a/packages/cfdi/expresiones/package.json b/packages/cfdi/expresiones/package.json index f85aaae8..440abf9a 100644 --- a/packages/cfdi/expresiones/package.json +++ b/packages/cfdi/expresiones/package.json @@ -2,6 +2,9 @@ "name": "@cfdi/expresiones", "version": "4.0.13", "license": "MIT", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "release": { "branches": [ @@ -14,25 +17,7 @@ "dist" ], "engines": { - "node": ">=10" - }, - "scripts": { - "start": "tsdx watch", - "build": "tsdx build --env production --minify && rimraf ./dist/index.js ./dist/expresiones.cjs.development.* && npm run cp", - "cp": "cp ./config/index.js ./dist", - "test": "vitest", - "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "node": ">=22" }, "publishConfig": { "registry": "https://registry.npmjs.org/", @@ -42,57 +27,31 @@ "type": "git", "url": "https://github.com/MisaelMa/recreando" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "author": { - "name": "Amir Misael Marin Coh, Signati", - "email": "amisael.amir.misae@gmail.com, signatidev@gmail.com,", - "url": "" + "scripts": { + "build": "vite build", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, - "size-limit": [ - { - "path": "dist/expresiones.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/expresiones.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "xml-js": "^1.6.11" }, "devDependencies": { - "rimraf": "^6.0.1", "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", "@recreando/vite": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", + "@types/node": "^22", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", "@vitest/coverage-v8": "2.1.3", "@vitest/ui": "2.1.3" + }, + "author": { + "name": "Amir Misael Marin Coh, Signati", + "email": "amisael.amir.misae@gmail.com, signatidev@gmail.com,", + "url": "" } } diff --git a/packages/cfdi/expresiones/vite.config.mts b/packages/cfdi/expresiones/vite.config.mts new file mode 100644 index 00000000..78f30cf9 --- /dev/null +++ b/packages/cfdi/expresiones/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xml-js'], + }, + }, +})); diff --git a/packages/cfdi/pdf/README.md b/packages/cfdi/pdf/README.md new file mode 100644 index 00000000..9bfd84be --- /dev/null +++ b/packages/cfdi/pdf/README.md @@ -0,0 +1,63 @@ +# @cfdi/pdf + +Opciones de configuracion para la generacion de PDF a partir de comprobantes CFDI. Define las interfaces para personalizar el logo, lugar de expedicion y fuentes tipograficas del documento. + +## Instalacion + +```bash +npm install @cfdi/pdf +``` + +## Uso + +```typescript +import { OptionsPdf, Logo } from '@cfdi/pdf'; + +// Configuracion basica con logo como string base64 +const opciones: OptionsPdf = { + logo: 'data:image/png;base64,...', + lugarExpedicion: 'Ciudad de Mexico, CDMX', +}; + +// Configuracion con logo detallado +const logo: Logo = { + image: 'data:image/png;base64,...', + width: 150, + height: 80, +}; + +const opcionesCompletas: OptionsPdf = { + logo, + lugarExpedicion: 'Monterrey, Nuevo Leon', + fonts: { + Roboto: { + normal: '/ruta/fuentes/Roboto-Regular.ttf', + bold: '/ruta/fuentes/Roboto-Bold.ttf', + italics: '/ruta/fuentes/Roboto-Italic.ttf', + bolditalics: '/ruta/fuentes/Roboto-BoldItalic.ttf', + }, + }, +}; +``` + +## API + +### `OptionsPdf` + +| Propiedad | Tipo | Descripcion | +|-----------|------|-------------| +| `logo` | `string \| Logo` | Logo en formato base64 o como objeto `Logo` | +| `lugarExpedicion` | `string` | Direccion del lugar de expedicion | +| `fonts` | `TFontDictionary` | Diccionario de fuentes personalizadas (de pdfmake) | + +### `Logo` + +| Propiedad | Tipo | Descripcion | +|-----------|------|-------------| +| `image` | `string` | Imagen en formato base64 | +| `width` | `number \| string` | Ancho del logo | +| `height` | `number \| string` | Alto del logo | + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/pdf/package.json b/packages/cfdi/pdf/package.json index b9d35467..ef60f909 100644 --- a/packages/cfdi/pdf/package.json +++ b/packages/cfdi/pdf/package.json @@ -2,87 +2,40 @@ "name": "@cfdi/pdf", "version": "0.0.10-beta.4", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/pdf.esm.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "files": [ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "author": "MisaelMa", - "size-limit": [ - { - "path": "dist/pdf.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/pdf.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "@cfdi/utils": "workspace:*", "@cfdi/xml": "workspace:*", "@cfdi/2json": "workspace:*", "@cfdi/complementos": "workspace:*", "@cfdi/catalogos": "workspace:*", - "immutable": "^4.0.0-rc.12", - "moment": "^2.29.4", - "moment-timezone": "^0.5.27", - "pdfmake": "^0.1.65", - "qrcode": "^1.4.4", - "save-file": "^2.3.1", + "pdfmake": "^0.2.20", "xml-js": "^1.6.11" }, "devDependencies": { "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", "@recreando/vite": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", - "@types/pdfmake": "^0.1.13", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", + "@types/node": "^22", + "@types/pdfmake": "^0.2.11", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/pdf/src/abstract-cfdi-pdf.ts b/packages/cfdi/pdf/src/abstract-cfdi-pdf.ts deleted file mode 100644 index 2b437bed..00000000 --- a/packages/cfdi/pdf/src/abstract-cfdi-pdf.ts +++ /dev/null @@ -1,182 +0,0 @@ -import * as Pd from 'pdfmake/build/pdfmake'; - -import { BufferOptions, TDocumentDefinitions } from 'pdfmake/interfaces'; -import { - CFDIComprobante, - XmlCdfi, - XmlConcepto, - XmlEmisor, - XmlImpuestos, - XmlReceptor, -} from '@cfdi/xml' -import { TCreatedPdf, createPdf } from 'pdfmake/build/pdfmake'; - -import { OptionsPdf } from './types'; -import { XmlTfd } from '@cfdi/complementos/types/complements/tfd/tfd.com' -import { XmlToJson } from '@cfdi/2json'; -import path from 'path'; -// import PdfPrinter from 'pdfmake'; -// @ts-ignore -import pdfFonts from 'pdfmake/build/vfs_fonts'; -import pdfMake from 'pdfmake/build/pdfmake'; -import { writeFileSync } from 'fs'; - -pdfMake.vfs = pdfFonts.pdfMake.vfs; - -export abstract class RPDF { - public xml: XmlCdfi = {} as XmlCdfi; - public options: OptionsPdf; - public docDefinition: TDocumentDefinitions | any = {}; - public fonts = { - // Roboto: { - // normal: path.resolve(__dirname, '..', 'src', 'fonts', 'Roboto-Regular.ttf'), - // bold: path.resolve(__dirname, '..', 'src', 'fonts', 'Roboto-Regular.ttf'), - // italics: path.resolve(__dirname, '..', 'src', 'fonts', 'Roboto-Regular.ttf'), - // bolditalics: path.resolve(__dirname, '..', 'src', 'fonts', 'Roboto-Regular.ttf') - // }, - }; - constructor(xml: string, options: OptionsPdf = {} as OptionsPdf) { - // @ts-ignore - this.xml = XmlToJson(xml); - this.options = options; - } - setEskeleton(body: TDocumentDefinitions): void { - this.docDefinition = body; - } - protected abstract addLogo(): void; - protected abstract addFolio(c: CFDIComprobante): void; - protected abstract addEmisorData(emisor: XmlEmisor, expedido: string): void; - protected abstract addDate(date: string): void; - protected abstract addReceptor(receptor: XmlReceptor): void; - protected abstract fechaTimbrado(tfd: XmlTfd): void; - protected abstract addCatidad(comprobante: CFDIComprobante): void; - protected abstract addImpuesto(impuesto: XmlImpuestos): void; - protected abstract addNumberToLetter(total: number): void; - protected abstract addCSDEmisor(NoCertificado: string): void; - protected abstract addDetalles(detalles: XmlConcepto): void; - protected abstract addFormaDePago(forma: string): void; - protected abstract addMetodoDePago(metodo: string): void; - protected abstract addMoneda(moneda: string): void; - protected abstract addTipoComprobante(tipo: string): void; - protected abstract addCSDSat(tfd: XmlTfd): void; - protected abstract folioFiscal(tfd: XmlTfd): void; - protected abstract addSelloDgtEmisor(tfd: XmlTfd): void; - protected abstract addSelloDelSat(tfd: XmlTfd): void; - protected abstract addCadenaOriginal(tfd: XmlTfd): void; - protected abstract addQr( - tfd: XmlTfd, - emisor: XmlEmisor | undefined, - receptor: XmlReceptor | undefined, - total: string - ): void; - public async getDocument(): Promise { - if (this.xml['cfdi:Comprobante']['cfdi:Emisor']) { - this.addEmisorData( - this.xml['cfdi:Comprobante']['cfdi:Emisor'], - this.xml['cfdi:Comprobante']._attributes.LugarExpedicion - ); - } - await this.addLogo(); - this.addFolio(this.xml['cfdi:Comprobante']._attributes); - this.addDate(this.xml['cfdi:Comprobante']._attributes.Fecha); - // @ts-ignore - this.addReceptor(this.xml['cfdi:Comprobante']['cfdi:Receptor']); - this.addDetalles(this.xml['cfdi:Comprobante']['cfdi:Conceptos']); - this.addCatidad(this.xml['cfdi:Comprobante']._attributes); - // @ts-ignore - this.addImpuesto(this.xml['cfdi:Comprobante']['cfdi:Impuestos']); - this.addNumberToLetter(+this.xml['cfdi:Comprobante']._attributes.Total); - // @ts-ignore - this.addCSDEmisor(this.xml['cfdi:Comprobante']._attributes.NoCertificado); - // @ts-ignore - this.addFormaDePago(this.xml['cfdi:Comprobante']._attributes.FormaPago); - // @ts-ignore - this.addMetodoDePago(this.xml['cfdi:Comprobante']._attributes.MetodoPago); - // @ts-ignore - this.addMoneda(this.xml['cfdi:Comprobante']._attributes.Moneda); - // @ts-ignore - this.addTipoComprobante( - this.xml['cfdi:Comprobante']._attributes.TipoDeComprobante - ); - - if (this.xml['cfdi:Comprobante']!['cfdi:Complemento']) { - const complements = this.xml['cfdi:Comprobante']['cfdi:Complemento']; - if (complements['tfd:TimbreFiscalDigital']) { - const tfd = complements['tfd:TimbreFiscalDigital']; - this.fechaTimbrado(tfd); - this.addCSDSat(tfd); - this.folioFiscal(tfd); - this.addSelloDgtEmisor(tfd); - this.addSelloDelSat(tfd); - this.addCadenaOriginal(tfd); - await this.addQr( - tfd, - this.xml['cfdi:Comprobante']['cfdi:Emisor'], - this.xml['cfdi:Comprobante']['cfdi:Receptor'], - this.xml['cfdi:Comprobante']._attributes.Total as string - ); - } - } - const fo = { ...this.fonts, ...Pd.fonts, ...this.options.fonts }; - console.log(fo); - return createPdf(this.docDefinition); - } - - public async save(path: string, name: string) { - const dir = path + `${name.replace('.pdf', '')}.pdf`; - try { - const buffer = await this.getBuffer(); - writeFileSync(dir, buffer, { encoding: 'binary' }); - return { - save: true, - path: dir, - }; - } catch (e) { - return { - save: false, - error: e, - }; - } - } - - public async getBlob(options?: BufferOptions): Promise { - return new Promise(async (resolve) => { - const doc = await this.getDocument(); - doc!.getBlob((result) => { - resolve(result); - }, options); - }); - } - - public async getBase64(options?: BufferOptions): Promise { - return new Promise(async (resolve) => { - const doc = await this.getDocument(); - doc!.getBase64((result) => { - resolve(result); - }, options); - }); - } - - public async getBuffer(options?: BufferOptions): Promise { - return new Promise(async (resolve) => { - const doc = await this.getDocument(); - doc!.getBuffer((result) => { - resolve(result); - }, options); - }); - } - - public async getDataUrl(options?: BufferOptions): Promise { - return new Promise(async (resolve) => { - const doc = await this.getDocument(); - doc!.getDataUrl((result) => { - resolve(result); - }, options); - }); - } - - public async getStream(options?: BufferOptions) { - const doc = await this.getDocument(); - return doc!.getStream(options); - } -} diff --git a/packages/cfdi/pdf/src/index.ts b/packages/cfdi/pdf/src/index.ts index 4b054561..a3d3b4a0 100644 --- a/packages/cfdi/pdf/src/index.ts +++ b/packages/cfdi/pdf/src/index.ts @@ -1,2 +1 @@ export * from './types/index'; -export * from "./templates" diff --git a/packages/cfdi/pdf/src/templates/A111/A111.skelton.ts b/packages/cfdi/pdf/src/templates/A111/A111.skelton.ts deleted file mode 100644 index c35c2c8f..00000000 --- a/packages/cfdi/pdf/src/templates/A111/A111.skelton.ts +++ /dev/null @@ -1,249 +0,0 @@ -import { TDocumentDefinitions } from 'pdfmake/interfaces'; -export const A111SKELETON: TDocumentDefinitions | any = { - pageSize: 'A4', - pageMargins: [20, 25, 20, 25], - content: [ - { - text: [ - { - fontSize: 13, - text: '\nORDEN DE COMPRA ', - }, - ], - }, - - { - columns: [ - { - width: 200, - text: [ - { - text: [ - { - text: '\n\nSolicitante:', - style: { - bold: true, - fontSize: 10, - }, - }, - { text: ' Sistemas\n', fontSize: 10 }, - ], - }, - { - text: [ - { - text: 'Proveedor:', - style: { - bold: true, - fontSize: 10, - }, - }, - { text: ' Coppel\n', fontSize: 10 }, - ], - }, - { - text: [ - { - text: 'Empresa:', - style: { - bold: true, - fontSize: 10, - }, - }, - { text: ' Adriana Salvador Jeronimo\n', fontSize: 10 }, - ], - }, - ], - }, - { - width: 250, - text: [ - { - text: [], - }, - { - text: [ - { - text: '\n\nArticulos Solicitados:', - style: { - bold: true, - fontSize: 10, - }, - }, - { text: ' 1\n', fontSize: 10 }, - ], - }, - { - text: [ - { - text: 'Fecha de Pedido:', - style: { - bold: true, - fontSize: 10, - }, - }, - { text: '06/07/2020\n', fontSize: 10 }, - ], - }, - { - text: [ - { - text: 'Fecha de Llegada:', - style: { - bold: true, - fontSize: 10, - }, - }, - { text: ' 06/07/2020\n', fontSize: 10 }, - ], - }, - ], - }, - { - width: 150, - style: 'tableExample', - table: { - headerRows: 1, - body: [ - [ - { - text: 'Folio', - fillColor: '#dddddd', - border: [true, true, true, true], - }, - ], - ['109209437'], - ], - }, - }, - ], - }, - - { - style: 'tableExample', - table: { - widths: [40, 153, 50, 80, 60, 50, 50], - headerRows: 1, - body: [ - [ - { - text: 'N°', - fillColor: '#dddddd', - border: [true, true, true, true], - }, - { - text: 'Concepto/Descricion', - style: 'tableHeader', - fillColor: '#dddddd', - border: [true, true, true, true], - }, - { - text: 'C.pedida', - style: 'tableHeader', - fillColor: '#dddddd', - border: [true, true, true, true], - }, - { - text: 'Unidad', - style: 'tableHeader', - fillColor: '#dddddd', - border: [true, true, true, true], - }, - { - text: 'C.Recibida', - style: 'tableHeader', - fillColor: '#dddddd', - border: [true, true, true, true], - }, - { - text: 'Precio', - style: 'tableHeader', - fillColor: '#dddddd', - border: [true, true, true, true], - }, - { - text: 'Valor', - fillColor: '#dddddd', - border: [true, true, true, true], - }, - ], - ['1', 'cat', 'nomina', 'servicio', '19891', '090', '090'], - ], - }, - }, - { - style: 'tableExample', - table: { - widths: [548], - - body: [ - [ - { - border: [false, false, false, true], - alignment: 'center', - text: [ - { - border: [false, false, true, false], - linecolors: '#000080', - style: { fontSize: 10, bold: true, color: '#a76d09' }, - text: ' ', - }, - { - border: [false, false, false, false], - fontSize: 10, - text: '\n ', - }, - { - border: [false, false, false, false], - linecolors: '#000080', - style: { fontSize: 10, bold: true, color: '#a76d09' }, - text: '', - }, - { - border: [false, false, false, false], - fontSize: 10, - text: '\n\n\n\n ', - }, - ], - }, - ], - ], - }, - }, - - { - style: 'tableExample', - table: { - widths: [290, 250], - body: [ - [ - { - border: [false, false, false, false], - text: [ - { - alignment: 'left', - text: 'AUTORIZADO POR (Nombre y Firma) ', - style: { - bold: true, - }, - }, - ], - }, - { - border: [false, false, false, false], - text: [ - { - alignment: 'right', - text: 'SOLICITADO POR (Nombre y Firma) ', - style: { - bold: true, - }, - }, - ], - }, - ], - ], - }, - }, - ], -}; diff --git a/packages/cfdi/pdf/src/templates/A111/index.ts b/packages/cfdi/pdf/src/templates/A111/index.ts deleted file mode 100644 index 564473a6..00000000 --- a/packages/cfdi/pdf/src/templates/A111/index.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { TDocumentDefinitions } from 'pdfmake/interfaces'; -import { - CFDIComprobante, - XmlCdfi, - XmlConcepto, - XmlEmisor, - XmlImpuestos, - XmlReceptor, -} from '@cfdi/xml' -import { createPdf, TCreatedPdf } from 'pdfmake/build/pdfmake'; -import { RPDF } from '../../abstract-cfdi-pdf'; -import { A111SKELETON } from './A111.skelton'; -import { OptionsPdf } from '../../types'; -import { XmlTfd } from '@cfdi/complementos/types/complements/tfd/tfd.com' -export class A111 extends RPDF { - constructor(xml: string, options: OptionsPdf = {} as OptionsPdf) { - super(xml, options); - this.setEskeleton(A111SKELETON); - } - - protected addLogo(): void { - // throw new Error('Method not implemented.'); - } - protected addFolio(c: CFDIComprobante): void { - //throw new Error('Method not implemented.'); - } - protected addEmisorData(emisor: XmlEmisor, expedido: string): void { - //throw new Error('Method not implemented.'); - } - protected addDate(date: string): void { - //throw new Error('Method not implemented.'); - } - protected addReceptor(receptor: XmlReceptor): void { - //throw new Error('Method not implemented.'); - } - protected fechaTimbrado(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected addCatidad(comprobante: CFDIComprobante): void { - //throw new Error('Method not implemented.'); - } - protected addImpuesto(impuesto: XmlImpuestos): void { - //throw new Error('Method not implemented.'); - } - protected addNumberToLetter(total: number): void { - //throw new Error('Method not implemented.'); - } - protected addCSDEmisor(NoCertificado: string): void { - //throw new Error('Method not implemented.'); - } - protected addDetalles(detalles: XmlConcepto): void { - //throw new Error('Method not implemented.'); - } - protected addFormaDePago(forma: string): void { - //throw new Error('Method not implemented.'); - } - protected addMetodoDePago(metodo: string): void { - //throw new Error('Method not implemented.'); - } - protected addMoneda(moneda: string): void { - //throw new Error('Method not implemented.'); - } - protected addTipoComprobante(tipo: string): void { - //throw new Error('Method not implemented.'); - } - - protected addCSDSat(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected folioFiscal(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected addSelloDgtEmisor(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected addSelloDelSat(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected addCadenaOriginal(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected addQr( - tfd: XmlTfd, - emisor: XmlEmisor | undefined, - receptor: XmlReceptor | undefined, - total: string - ): void { - //throw new Error('Method not implemented.'); - } -} diff --git a/packages/cfdi/pdf/src/templates/A117/A117.skeleton.ts b/packages/cfdi/pdf/src/templates/A117/A117.skeleton.ts deleted file mode 100644 index 25ef5465..00000000 --- a/packages/cfdi/pdf/src/templates/A117/A117.skeleton.ts +++ /dev/null @@ -1,560 +0,0 @@ -import { TDocumentDefinitions } from 'pdfmake/interfaces'; -import { logo } from '@cfdi/utils'; -export const A117SKELETON: TDocumentDefinitions | any = { - pageSize: 'A4', - pageMargins: [20, 25, 20, 25], - content: [ - { - columns: [ - { - text: 'logo', - }, - { - width: 40, - text: '', - }, - { - margin: [0, 0, 0, 0], - width: 200, - text: [ - { - text: '\n', - style: { - bold: true, - color: '#a76d09', - }, - }, - { - text: [ - { - text: 'R.F.C: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: '\n' }, - ], - }, - { - text: [ - { - text: 'REGIMEN: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: '\n' }, - ], - }, - { - text: [ - { - text: 'LUGAR DE EXPEDICION: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: '\n' }, - ], - }, - ], - style: { - fontSize: 9, - }, - }, - [ - { - alignment: 'center', - margin: [55, 0, 0, 0], - text: 'FACTURA', - style: { - fontSize: 9, - bold: true, - }, - }, - { - margin: [80, 0, 0, 10], - alignment: 'center', - width: [10], - table: { - alignment: 'right', - body: [ - [ - { - text: 'FOLIO', - style: { - bold: true, - fontSize: 9, - alignment: 'center', - margin: [0, 0, 0, 0], - }, - }, - ], - ], - }, - layout: { - // @ts-ignore - paddingLeft: (i: any, node: any) => { - return 20; - }, - // @ts-ignore - paddingRight: (i: any, node: any) => { - return 20; - }, - // @ts-ignore - paddingTop: (i: any, node: any) => { - return 0; - }, - // @ts-ignore - paddingBottom: (i: any, node: any) => { - return 0; - }, - // @ts-ignore - fillColor: (rowIndex: number, node: any, columnIndex: any) => { - return rowIndex === 0 ? '#eeeeee' : null; - }, - }, - }, - { - alignment: 'center', - margin: [80, 0, 0, 0], - table: { - alignment: 'right', - heights: 10, - body: [ - [ - { - text: 'FECHA', - style: { - bold: true, - fontSize: 9, - alignment: 'center', - margin: [0, 0, 0, 0], - }, - }, - ], - ], - }, - layout: { - // @ts-ignore - paddingTop: (i: any, node: any) => { - return 0; - }, - // @ts-ignore - paddingBottom: (i: any, node: any) => { - return 0; - }, - // @ts-ignore - fillColor: (rowIndex: number, node: any, columnIndex: any) => { - return rowIndex === 0 ? '#eeeeee' : null; - }, - }, - }, - ], - ], - }, - { - bold: true, - margin: [0, 20, 0, 10], - text: [ - { - text: 'Datos del Cliente\n', - style: { - color: '#0941a7', - }, - }, - { - text: 'Razon Social: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: '' }, - { - text: 'R.F.C.: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: '' }, - { - text: 'Uso CFDI: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: '' }, - ], - style: { - fontSize: 10, - }, - }, - { - style: { - fontSize: 9, - }, - table: { - widths: [45, 50, 213, 40, 50, 53, 40], - body: [ - [ - { - text: 'CANTIDAD', - style: { - bold: true, - }, - }, - { - text: 'CLAVE SAT', - style: { - bold: true, - }, - }, - { - text: 'CONCEPTO/DESCRIPCIÓN', - alignment: 'center', - style: { - bold: true, - }, - }, - { - text: 'UNIDAD', - style: { - bold: true, - }, - }, - { - text: 'P.UNITARIO', - style: { - bold: true, - }, - }, - { - text: 'DESCUENTO', - style: { - bold: true, - }, - }, - { - text: 'IMPORTE', - style: { - bold: true, - }, - }, - ], - ], - }, - layout: { - // @ts-ignore - fillColor: (rowIndex: number, node: any, columnIndex: any) => { - return rowIndex === 0 ? '#eeeeee' : null; - }, - }, - }, - { - margin: [0, 7, 0, 7], - table: { - widths: ['*', 'auto'], - body: [ - [ - { - stack: [ - { - text: 'CANTIDAD CON LETRA', - style: { - bold: true, - fontSize: 9, - }, - }, - { - text: 'OCHOCIENTOS TREINTA Y NUEVE PESOS 99/100 M.N.', - style: { - fontSize: 9, - }, - }, - ], - }, - { - text: [ - { - text: 'SUBTOTAL: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: '\n' }, - { - text: 'DESCUENTO: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: '$\n' }, - { - text: 'IMPUESTOS: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: '$\n' }, - { - text: 'TOTAL: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: '$' }, - ], - style: { - fontSize: 9, - }, - }, - ], - ], - }, - }, - { - columns: [ - { - text: [ - { - text: 'Forma de pago: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: ' \n' }, - { - text: 'Método de pago: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: ' \n' }, - { - text: 'No. de cuenta: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: ' \n' }, - ], - style: { - fontSize: 9, - }, - }, - { - text: [ - { - text: 'Moneda: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: ' $ 1034.48\n' }, - { - text: 'Tipo de comprobante: ', - style: { - bold: true, - color: '#a76d09', - }, - }, - { text: ' $ 310.35\n' }, - ], - style: { - fontSize: 9, - }, - }, - ], - }, - { - style: { - fontSize: 9, - }, - table: { - widths: [250, 280], - body: [ - [ - { - border: [false, false, false, false], - text: 'No. CSD del Emisor', - alignment: 'center', - style: { - bold: true, - }, - }, - { - border: [false, false, false, false], - text: 'Fecha y hora de certificacion', - alignment: 'center', - style: { - bold: true, - }, - }, - ], - [ - { - border: [false, true, false, false], - text: ' ', - alignment: 'center', - }, - { - border: [false, true, false, false], - text: '', - alignment: 'center', - }, - ], - [ - { - border: [false, false, false, false], - text: 'Folio Fiscal', - alignment: 'center', - style: { - bold: true, - }, - }, - { - border: [false, false, false, false], - text: 'No. CSD del SAT', - alignment: 'center', - style: { - bold: true, - }, - }, - ], - [ - { - border: [false, true, false, false], - text: '', - alignment: 'center', - }, - { - border: [false, true, false, false], - text: '', - alignment: 'center', - }, - ], - ], - }, - }, - { - margin: [0, 25, 0, 0], - style: { - fontSize: 9, - }, - columns: [ - { - text: '', - }, - { - margin: [-10, -15, 0, 0], - table: { - widths: [418], - body: [ - [ - { - border: [false, false, false, false], - text: 'SELLO DIGITAL DEL EMISOR', - style: { - alignment: 'left', - color: '#0941a7', - }, - }, - ], - [ - { - border: [false, false, false, false], - text: '', - style: { - fontSize: 7, - }, - }, - ], - [ - { - border: [false, false, false, false], - text: 'SELLO DEL SAT', - style: { - alignment: 'left', - color: '#0941a7', - }, - }, - ], - [ - { - border: [false, false, false, false], - text: '', - style: { - fontSize: 7, - }, - }, - ], - [ - { - border: [false, false, false, false], - text: 'CADENA ORIGINAL DEL COMPLEMENTO DE CERTIFICACION DIGITAL DEL SAT', - style: { - alignment: 'left', - color: '#0941a7', - }, - }, - ], - [ - { - border: [false, false, false, false], - text: '', - style: { - fontSize: 7, - }, - }, - ], - ], - }, - style: { - fontSize: 9, - }, - }, - ], - }, - ], - // @ts-ignore - footer: (currentPage: number, pageCount: number) => { - return { - table: { - body: [ - [ - { - image: logo, - margin: [10, 0, 0, 0], - alignment: 'center', - fit: [20, 20], - }, - { - margin: [-5, 5, 0, 0], - text: 'by Signati', - // stext: "Page " + currentPage.toString() + ' of ' + pageCount, - alignment: 'right', - style: { - fontSize: 10, - }, - }, - ], - ], - }, - layout: 'noBorders', - }; - }, -}; diff --git a/packages/cfdi/pdf/src/templates/A117/index.ts b/packages/cfdi/pdf/src/templates/A117/index.ts deleted file mode 100644 index 863e59e5..00000000 --- a/packages/cfdi/pdf/src/templates/A117/index.ts +++ /dev/null @@ -1,348 +0,0 @@ -import { CFDIComprobante, XmlConcepto, XmlEmisor, XmlReceptor, XmlImpuestos, XmlConceptoProperties } from '@cfdi/xml' -import { - FormaPagoList, - MetodoPagoList, - RegimenFiscalList, - TipoComprobanteList, -} from '@cfdi/catalogos' -import { XmlTfd } from '@cfdi/complementos/types/complements/tfd/tfd.com' -import { ContentText } from 'pdfmake/interfaces'; -import { logo, NumeroALetras } from '@cfdi/utils'; -// @ts-ignore -import * as QRCode from 'qrcode'; - -import { A117SKELETON } from './A117.skeleton'; -import { RPDF } from '../../abstract-cfdi-pdf'; -import { OptionsPdf } from '../../types'; -export class A117 extends RPDF { - constructor(xml: string, options: OptionsPdf = {} as OptionsPdf) { - super(xml, options); - this.setEskeleton(A117SKELETON); - } - protected addLogo(): void { - if (this.options.logo) { - if (typeof this.options.logo === 'object') { - this.docDefinition.content[0].columns[0] = { - width: this.options.logo.width, - image: this.options.logo.image, - height: this.options.logo.height, - alignment: 'left', - }; - } else { - this.docDefinition.content[0].columns[0] = { - width: 100, - image: this.options.logo, - height: 100, - alignment: 'left', - }; - } - } else { - this.docDefinition.content[0].columns[0] = { - width: 100, - image: logo, - height: 100, - alignment: 'left', - }; - } - } - - protected addFolio(c: CFDIComprobante) { - const data = [ - { - text: c.Serie + ' - ' + c.Folio, - style: { - fontSize: 10, - alignment: 'center', - color: 'red', - margin: [0, 0, 0, 0], - }, - }, - ]; - this.docDefinition.content[0].columns[3][1].table.body.push(data); - } - - protected addEmisorData(emisor: XmlEmisor, expedido: string) { - this.docDefinition.content[0].columns[2].text[0].text = - emisor._attributes!.Nombre + '\n'; - this.docDefinition.content[0].columns[2].text[1].text[1].text = - emisor._attributes!.Rfc + '\n'; - const regimen = RegimenFiscalList.find( - (f) => f.value.toString() === emisor._attributes!.RegimenFiscal - ); - this.docDefinition.content[0].columns[2].text[2].text[1].text = - emisor._attributes!.RegimenFiscal + - ' - ' + - regimen!.descripcion.toUpperCase() + - '\n'; - this.docDefinition.content[0].columns[2].text[3].text[1].text = this.options - .lugarExpedicion - ? this.options.lugarExpedicion - : expedido; - } - - protected addDate(date: string) { - const data = [ - { - text: date, - style: { - fontSize: 10, - alignment: 'center', - color: 'red', - margin: [0, 0, 0, 0], - }, - }, - ]; - this.docDefinition.content[0].columns[3][2].table.body.push(data); - } - - protected addDetalles(detalles: XmlConcepto) { - let deatails: XmlConceptoProperties[] = []; - /* al momento de la conversion no respeta el array - lo convierte en objeto cuando es solo un item, - por eso la validacion si es typo array o no*/ - if (Array.isArray(detalles['cfdi:Concepto'])) { - deatails = detalles['cfdi:Concepto']; - } else { - // @ts-ignore - deatails.push(detalles['cfdi:Concepto']); - } - for (const detail of deatails) { - const con = detail._attributes; - const descripcion: ContentText[] = [ - { - text: con.Descripcion + '\n', - }, - ]; - if (detail['cfdi:ComplementoConcepto']) { - if (detail['cfdi:ComplementoConcepto']['iedu:instEducativas']) { - if ( - detail['cfdi:ComplementoConcepto']['iedu:instEducativas'] - ._attributes - ) { - const iedu = - detail['cfdi:ComplementoConcepto']['iedu:instEducativas'] - ._attributes; - descripcion.push({ text: 'ALUMNO: ', bold: true }); - descripcion.push({ - text: iedu!.nombreAlumno.toLocaleUpperCase() + '\n', - }); - descripcion.push({ text: 'CURP: ', bold: true }); - descripcion.push({ text: iedu!.CURP.toLocaleUpperCase() + '\n' }); - descripcion.push({ text: 'NIVEL EDUCATIVO: ', bold: true }); - descripcion.push({ - text: iedu!.nivelEducativo.toLocaleUpperCase() + '\n', - }); - descripcion.push({ text: 'CLAVE: ', bold: true }); - descripcion.push({ - text: iedu!.autRVOE.toLocaleUpperCase() + '\n', - }); - descripcion.push({ text: 'RFC: ', bold: true }); - descripcion.push({ - text: iedu!.rfcPago.toLocaleUpperCase() + '\n', - }); - } - } - if ( - detail['cfdi:ComplementoConcepto']['terceros:PorCuentadeTerceros'] - ) { - // @ts-ignore - const terceros = - detail['cfdi:ComplementoConcepto']['terceros:PorCuentadeTerceros']; - } - if ( - detail['cfdi:ComplementoConcepto']['ventavehiculos:VentaVehiculos'] - ) { - // @ts-ignore - const ventavehiculos = - detail['cfdi:ComplementoConcepto']['ventavehiculos:VentaVehiculos']; - } - } - this.docDefinition.content[2].table.body.push([ - { - text: con.Cantidad, - }, - { - text: con.ClaveProdServ, - }, - { - text: descripcion, - }, - { - text: con.ClaveUnidad, - }, - { - text: '$' + con.ValorUnitario, - }, - { - text: '$' + con.Descuento, - }, - { - text: '$' + con.Importe, - }, - ]); - } - // this.docDefinition.content[2].table.body.push(table) - } - - protected addReceptor(receptor: XmlReceptor | undefined) { - this.docDefinition.content[1].text[2] = { - text: receptor - ? receptor._attributes - ? receptor._attributes.Nombre + '\n' - : '' - : '', - }; - this.docDefinition.content[1].text[4] = { - text: receptor - ? receptor._attributes - ? receptor._attributes.Rfc + '\n' - : '' - : '', - }; - this.docDefinition.content[1].text[6] = { - text: receptor - ? receptor._attributes - ? receptor._attributes.UsoCFDI + '\n' - : '' - : '', - }; - } - - protected addCatidad(comprobante: CFDIComprobante) { - this.docDefinition.content[3].table.body[0][1].text[1] = { - text: '$' + comprobante.SubTotal + '\n', - }; - this.docDefinition.content[3].table.body[0][1].text[3] = { - text: '$' + comprobante.Descuento + '\n', - }; - this.docDefinition.content[3].table.body[0][1].text[7] = { - text: '$' + comprobante.Total + '\n', - }; - } - - protected addImpuesto(impuesto: XmlImpuestos | undefined) { - if (impuesto) { - // tslint:disable-next-line:no-unused-expression - let impues = '0.00'; - if (impuesto._attributes.TotalImpuestosTrasladados) { - impues = impuesto._attributes.TotalImpuestosTrasladados as string - } - this.docDefinition.content[3].table.body[0][1].text[5] = { - text: '$' + impues + '\n', - }; - } - } - - protected addNumberToLetter(total: number) { - // tslint:disable-next-line:no-unused-expression - const nue = new NumeroALetras(); - this.docDefinition.content[3].table.body[0][0].stack[1].text = - nue.NumeroALetras(total, { - plural: 'PESOS', - singular: 'PESO', - centPlural: 'CENTAVOS', - centSingular: 'CENTAVO', - }); - } - - protected addCSDEmisor(NoCertificado: string) { - this.docDefinition.content[5].table.body[1][0].text = NoCertificado; - } - - protected fechaTimbrado(tfd: XmlTfd) { - this.docDefinition.content[5].table.body[1][1].text = - tfd._attributes.FechaTimbrado; - } - - protected addCSDSat(tfd: XmlTfd) { - this.docDefinition.content[5].table.body[3][1].text = - tfd._attributes.NoCertificadoSAT; - } - - protected folioFiscal(tfd: XmlTfd) { - this.docDefinition.content[5].table.body[3][0].text = - tfd._attributes.UUID.toUpperCase(); - } - - protected addSelloDgtEmisor(tfd: XmlTfd) { - this.docDefinition.content[6].columns[1].table.body[1][0].text = - tfd._attributes.SelloCFD; - } - - protected addSelloDelSat(tfd: XmlTfd) { - // @ts-ignore - this.docDefinition.content[6].columns[1].table.body[3][0].text = - tfd._attributes.SelloSAT; - } - - protected addCadenaOriginal(tfd: XmlTfd) { - const cadena = `||${tfd._attributes.Version}|${tfd._attributes.UUID}|${tfd._attributes.FechaTimbrado}|${tfd._attributes.RfcProvCertif}|${tfd._attributes.SelloCFD}|${tfd._attributes.NoCertificadoSAT}||`; - this.docDefinition.content[6].columns[1].table.body[5][0].text = cadena; - } - - protected addFormaDePago(forma: string) { - const description = FormaPagoList.find((f) => f.value === forma); - // console.log(this.docDefinition.content[4].columns[0].text, description) - this.docDefinition.content[4].columns[0].text[1] = { - text: forma + ' - ' + description!.label + '\n', - }; - } - - protected addMetodoDePago(metodo: string) { - const description = MetodoPagoList.find((f) => f.value === metodo); - this.docDefinition.content[4].columns[0].text[3] = { - text: metodo + ' - ' + description!.label + '\n', - }; - // console.log(this.docDefinition.content[4]) - } - - protected addCuenta(cuenta: string) { - this.docDefinition.content[4].columns[0].text[5] = { - text: cuenta + '\n', - }; - // console.log(this.docDefinition.content[5]) - } - - protected addMoneda(moneda: string) { - // console.log(this.docDefinition.content[4].columns[1].text) - this.docDefinition.content[4].columns[1].text[1] = { - text: moneda + '\n', - }; - } - - protected addTipoComprobante(tipo: string) { - const description = TipoComprobanteList.find((f) => f.value === tipo); - this.docDefinition.content[4].columns[1].text[3] = { - text: tipo + ' - ' + description!.label + '\n', - }; - // console.log(this.docDefinition.content[6].columns[1].text) - } - - protected async addQr( - tfd: XmlTfd, - emisor: XmlEmisor | undefined, - receptor: XmlReceptor | undefined, - total: string - ) { - const url = `https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx`; - const uuid = tfd._attributes.UUID; - const rfcEmisor = emisor!._attributes!.Rfc; - const rfcReceptor = receptor!._attributes!.Rfc; - const sello = tfd._attributes.SelloCFD.substr(-8); - const totalSplit = total.split('.') as any; - const totalStart = totalSplit[0].padStart(18, '0'); - const totalEnd = totalSplit[1] - ? totalSplit[1].padEnd(6, '0') - : '0'.padEnd(6, '0'); - const cantidad = totalStart + '.' + totalEnd; - const urlQr = `${url}?id=${uuid}&re=${rfcEmisor}&rr=${rfcReceptor}&tt=${cantidad}&fe=${sello}`; - const text = await QRCode.toDataURL(urlQr); - this.docDefinition.content[6].columns[0] = { - margin: [-10, -19, 0, 0], - width: 130, - image: text, - height: 130, - alignment: 'left', - }; - } -} diff --git a/packages/cfdi/pdf/src/templates/B111/index.ts b/packages/cfdi/pdf/src/templates/B111/index.ts deleted file mode 100644 index 46da6217..00000000 --- a/packages/cfdi/pdf/src/templates/B111/index.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { - CFDIComprobante, - XmlComprobanteAttributes, - XmlConcepto, - XmlEmisor, - XmlImpuestos, - XmlReceptor, - XmlConceptoProperties -} from '@cfdi/xml' - -import { B111ESKELETON } from './B111.skeleton'; -import { OptionsPdf } from '../../types'; -import { RPDF } from '../../abstract-cfdi-pdf'; -import { XmlTfd } from '@cfdi/complementos/types/complements/tfd/tfd.com' - -import { ContentText } from 'pdfmake/interfaces'; - -export class B111 extends RPDF { - protected addLogo(): void { - // throw new Error('Method not implemented.'); - } - protected addFolio(c: XmlComprobanteAttributes ): void { - console.log(c); - const data = { text: c.Folio, alignment: 'center',color:"red" }; - - const arr = this.docDefinition.content[0].table.body[0][2].table.body[3]; - this.docDefinition.content[0].table.body[0][2].table.body[5].text=c.NoCertificado as string - - arr.push(data); - // this.docDefinition.content[0].table.body[0][2].table.body[3].push(data); - } - protected addEmisorData(emisor: XmlEmisor, expedido: string): void { - //throw new Error('Method not implemented.'); - this.docDefinition.content[1].table.body[0][0].text[2].text =" "+ emisor._attributes?.Nombre + "\n" ; - this.docDefinition.content[1].table.body[0][0].text[4].text =" "+ emisor._attributes?.Rfc + "\n" ; - this.docDefinition.content[1].table.body[0][0].text[6].text =" "+ this.options.lugarExpedicion + "\n" ; - this.docDefinition.content[1].table.body[0][0].text[8].text =" "+ emisor._attributes?.RegimenFiscal + "\n" ; - - } - protected addDate(date: string): void { - //throw new Error('Method not implemented.'); - } - protected addReceptor(receptor: XmlReceptor): void { - this.docDefinition.content[1].table.body[0][1].text[2].text =" "+ receptor._attributes?.Nombre + "\n" ; - this.docDefinition.content[1].table.body[0][1].text[4].text =" "+ receptor._attributes?.Rfc + "\n" ; - this.docDefinition.content[1].table.body[0][1].text[6].text =" "+ this.options.lugarExpedicion + "\n" ; - this.docDefinition.content[1].table.body[0][1].text[8].text =" "+ receptor._attributes?.UsoCFDI + "\n" ; - - // throw new Error('Method not implemented.'); - } - protected fechaTimbrado(tfd: XmlTfd): void { - // throw new Error('Method not implemented.'); - } - protected addCatidad(comprobante: CFDIComprobante): void { - //throw new Error('Method not implemented.'); - } - protected addImpuesto(impuesto: XmlImpuestos): void { - // throw new Error('Method not implemented.'); - } - protected addNumberToLetter(total: number): void { - // throw new Error('Method not implemented.'); - } - protected addCSDEmisor(NoCertificado: string): void { - //throw new Error('Method not implemented.'); - } - protected addDetalles(detalles: XmlConcepto): void { - let deatails: XmlConceptoProperties[] = []; - if (Array.isArray(detalles['cfdi:Concepto'])) { - deatails = detalles['cfdi:Concepto']; - } else { - // @ts-ignore - deatails.push(detalles['cfdi:Concepto']); - } - - for (const detail of deatails) { - const con = detail._attributes; - const descripcion: ContentText[] = [ - { - text: con.Descripcion + '\n', - }, - ]; - // this.docDefinition.content[2].table.body[1][1].push([con.Cantidad]) ; - } - //throw new Error('Method not implemented.'); - } - protected addFormaDePago(forma: string): void { - //throw new Error('Method not implemented.'); - } - protected addMetodoDePago(metodo: string): void { - //throw new Error('Method not implemented.'); - } - protected addMoneda(moneda: string): void { - //throw new Error('Method not implemented.'); - } - protected addTipoComprobante(tipo: string): void { - // throw new Error('Method not implemented.'); - } - protected addCSDSat(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected folioFiscal(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected addSelloDgtEmisor(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected addSelloDelSat(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected addCadenaOriginal(tfd: XmlTfd): void { - //throw new Error('Method not implemented.'); - } - protected addQr( - tfd: XmlTfd, - emisor: XmlEmisor | undefined, - receptor: XmlReceptor | undefined, - total: string - ): void { - //throw new Error('Method not implemented.'); - } - constructor(xml: string, options: OptionsPdf = {} as OptionsPdf) { - super(xml, options); - this.setEskeleton(B111ESKELETON); - } -} diff --git a/packages/cfdi/pdf/src/templates/B112/index.ts b/packages/cfdi/pdf/src/templates/B112/index.ts deleted file mode 100644 index 8c38d457..00000000 --- a/packages/cfdi/pdf/src/templates/B112/index.ts +++ /dev/null @@ -1,473 +0,0 @@ -import { XmlCdfi } from "@cfdi/xml" -import { XmlToJson } from "@cfdi/2json"; -import { logo } from '@cfdi/utils'; -import { createPdf, TCreatedPdf } from "pdfmake/build/pdfmake"; -import { TDocumentDefinitions } from "pdfmake/interfaces"; - - - - - -export class B112 { - // @ts-ignore - private xml: XmlCdfi; - private docDefinition: TDocumentDefinitions = { - pageSize: 'A4', - pageMargins: [20, 25, 20, 25], - content: [ - - { - - - style: 'tableExample', - table: { - - widths: [545], - body: [ - [ - { - border: [false, false, false, false], - fillColor: '#000080', - text: [ - - { - alignment: 'center', - text: 'FACTURA ELECTRÓNICA (CFDI)', - style: { - bold: true, - color: '#00FFFF', - fontSize: 13, - } - }, - - ] - } - ] - ] - } - }, - - - { - - style: 'tableExample', - table: { - - widths: [545], - body: [ - [ - { - border: [false, false, false, false], - text: [ - - { - alignment: 'left', - text: '\nNOMBRE O RAZON SOCIAL DE LA EMPRESA', - style: { - bold: true, - fontSize: 12, - } - }, - - ] - } - ] - ] - } - }, - { - columns: [ - { - width: 100, - image: logo, - height: 100, - alignment: 'left' - }, - { - width: 20, - text: '' - }, - { - margin: [0, 0, 0, 0], - width: 243, - text: [ - - { - text: [ - { - text: 'R.F.C:\n ', - style: { - bold: true, - color: '#a76d09', - } - }, - { text: ' GUCE910701NHA\n' } - ] - }, - { - text: [ - { - text: 'Dirrecion:\n', - style: { - bold: true, - color: '#a76d09', - } - }, - { text: ' av oquideas entre ruta5\n' } - ] - }, - { - text: [ - { - text: 'Telefono:\n', - style: { - bold: true, - color: '#a76d09', - } - }, - { text: ' 98765436899\n' } - ] - }, - ] - }, - { - width: 500, - - style: 'tableExample', - table: { - body: [ - [{ text: 'FACTURA', alignment: 'right', style: { bold: true, color: '#a76d09' } }], - [{ text: 'F3EE54R', alignment: 'right' }], - [{ text: 'FOLIO FISCAL', alignment: 'right', style: { bold: true, color: '#a76d09' } }], - [{ text: 'XXXXXXXXXX', alignment: 'right' }], - [{ text: 'N° DE SERIE DE CERTIFICACION', alignment: 'right', style: { bold: true, color: '#a76d09' } }], - [{ text: 'XXXXXXXXX', alignment: 'right' }], - [{ text: 'FECHA Y HORA DE CERTIFICACION', alignment: 'right', style: { bold: true, color: '#a76d09' } }], - [{ text: '18:12:12 02/07/2020', alignment: 'right' }], - ] - }, - layout: 'noBorders' - }, - - - ] - }, - { - style: 'tableExample', - table: { - - body: [ - [ - { - border: [false, false, false, false], - style: { bold: true, color: '#a76d09' }, - text: 'Lugar de Expedicion: ' - }, - { - border: [false, false, false, false], - - text: 'solidaridad,playa del carmen ' - }, - ] - ] - } - }, - - { - - style: 'tableExample', - table: { - - widths: [545], - body: [ - [ - { - border: [false, true, false, false], - text: [ - { - border: [false, true, false, false], - linecolors: '#000080', - style: { bold: true, color: '#a76d09' }, - text: 'Receptor: ' - }, - { - border: [false, false, false, false], - text: 'PEMEX GAS Y PETROQUIMICA BASICA\n ' - }, - { - border: [false, false, false, false], - linecolors: '#000080', - style: { bold: true, color: '#a76d09' }, - text: 'RFC del Clinete: ' - }, - { - border: [false, false, false, false], - text: 'PGP920716MT6\n ' - }, - { - border: [false, false, false, false], - linecolors: '#000080', - style: { bold: true, color: '#a76d09' }, - text: 'Dirrecion: ' - }, - { - border: [false, false, false, false], - text: 'AVENIDA MARINA NACIONAL 329 PETROLEOS MEXICANOS,Distrito Federal C.P. 86125, México \n' - }, - { - border: [false, false, false, false], - linecolors: '#000080', - style: { bold: true, color: '#a76d09' }, - text: 'Telefono: ' - }, - { - border: [false, false, false, false], - text: '9890808090 \n' - }, - ] - } - ] - ] - } - }, - { - style: 'tableExample', - table: { - widths: [50, 40, 173, 120, 60, 60], - headerRows: 1, - body: [ - - [{ text: 'cantidad', fillColor: '#dddddd', border: [true, true, true, true] }, { text: 'Unidad', style: 'tableHeader', fillColor: '#dddddd', border: [true, true, true, true] }, { text: 'descricion', style: 'tableHeader', fillColor: '#dddddd', border: [true, true, true, true] }, { text: 'Clave servicio/producto', style: 'tableHeader', fillColor: '#dddddd', border: [true, true, true, true] }, { text: 'Precio Unitario', style: 'tableHeader', fillColor: '#dddddd', border: [true, true, true, true] }, { text: 'Importe', style: 'tableHeader', fillColor: '#dddddd', border: [true, true, true, true] }], - ['1', 'cat', 'nomina', 'servicio', '19891', '090'], - ['1', 'cat', 'nomina', 'servicio', '19891', '090'], - ['1', 'cat', 'nomina', 'servicio', '19891', '090'], - ['1', 'cat', 'nomina', 'servicio', '19891', '090'], - - ] - }, - - - }, - { - margin: [0, 7, 0, 7], - table: { - - widths: ['auto', '*', 'auto'], - body: [ - [ - { - border: [false, false, false, false], - alignment: 'center', - - table: { - body: [ - [ - - { - image: logo, - width: 100, - height: 100, - }, - - - ], - ] - }, - layout: 'noBorders' - }, - { - border: [false, false, false, false], - stack: [ - { - text: 'CANTIDAD CON LETRA', - style: { - bold: true, - fontSize: 9 - } - }, - { - text: 'OCHOCIENTOS TREINTA Y NUEVE PESOS 99/100 M.N.\n\n', - style: { - fontSize: 9 - } - }, - { - text: 'METODO DE PAGO', - style: { - bold: true, - fontSize: 9 - } - }, - { - text: 'NO INDENTIFICADO\n', - style: { - fontSize: 9 - } - }, - { - text: 'REGIMEN', - style: { - bold: true, - fontSize: 9 - } - }, - { - text: 'PERSONA MORAL', - style: { - fontSize: 9 - } - } - ] - }, - { - border: [false, false, false, false], - style: 'tableExample', - table: { - headerRows: 1, - alignment: 'center', - body: [ - [{ text: 'Subtotal', alignment: 'center', }, { text: 'FACTURA', alignment: 'center' }], - [{ text: 'Descuento', alignment: 'center' }, { text: 'F3EE54R', alignment: 'center' }], - [{ text: 'I.V.A 16%', alignment: 'center' }, { text: 'F3EE54R', alignment: 'center' }], - [{ text: 'Total', alignment: 'center' }, { text: 'F3EE54R', alignment: 'center' }], - - - ] - }, - layout: 'lightHorizontalLines' - - } - ], - ] - } - }, - - - { - style: 'tableExample', - table: { - widths: [548], - - body: [ - [{ - border: [false, false, false, false], - text: [ - - { - text: 'SELLO DIGITAL\n', - style: { - bold: true, - color: '#0941a7', - fontSize: 10, - } - }, - { fontSize: 10, text: 'aYjYNUhTvNVosLnPJsV5h/lAW/HSs45Qzhl2W5V2DPqrdoFfp9mH7wUcS5v3jP6Oql4Y7ncYOcLqakqfGeclJJP/6T1XmbcvPPdBq1DGWh6DaisHS2QCMOW3MGuv8Hc/0j7JwYbXFpTKKM3cudwTmzh76MUoqnssDUfuFIVJ8=`,\n\n' }, - { - text: 'SELLO SAT\n', - style: { - fontSize: 10, - bold: true, - color: '#0941a7', - } - - }, - { fontSize: 10, text: 'GlU7AYil3GqVeUD9oJvqVKc2Uq/K2R7lkc2m6WPuhddjYvWm0foFfMVwzn2KfS7o6KZIddDXdAglhknZsz3ub3X0/aPW4DSwvDYXOF2yCCqd64vbt5MfWqpPqN2zmjzJVFe5ntIPQ21jveXAjR44pJIHNG3rUUUdhVnag6NFTqviaAV75z6OywesoMQCFcsoEjvKozzKGpT7Imuoa94aGIhj0TP5m1hk4OnROOcEBPo11mPf4elDKBDzk+iuCw4wiV/GHaeL0D4zBcVOL/Igz12MKRmYtNdmBfSCv3TI7bJ7qQUV1RckO2Rj1CpFrpa7xr/Vw6lEwitpkCwQ00SKBg==\n\n' }, - { - text: [ - { - text: 'CADENA ORIGINAL DEL COMPLEMENTO DE CERTIFICACION DIGITAL DEL SAT\n', - style: { - bold: true, - color: '#0941a7', - fontSize: 10, - } - }, - ] - }, - { - fontSize: 10, text: '||1.1|5D178E7E-C81C-11E8-89A8-237CD11664D5|2018-10-04T16:27:58|FMO1007168C6|eaYjYNUhTvNVosLnPJsV5h/xlAW/HSs45Qzhl2W5V2DPqrdoFfp9mH7wUcS5v3jP6Oql4Y7ncYOcLqakqfGeclJJP/6T1XmbcvPPdBq1DGWh6DaisHS2QCMOW3MG\n' + - 'uv8Hc/0j7JwYbXFpTKKM3cudwTmzh76MUoqnssDUfuFIVJ8=|00001000000401477845||' - }, - - - ] - }, - ] - ] - } - }, - { - - style: 'tableExample', - table: { - - widths: [548], - - body: [ - [ - { - border: [false, false, false, true], - alignment: 'center', - text: [ - { - border: [false, false, true, false], - linecolors: '#000080', - style: { fontSize: 10, bold: true, color: '#a76d09' }, - text: ' N° DE SERIE DE CERTIFICACION:', - }, - { - border: [false, false, false, false], - fontSize: 10, - text: 'XXXXXXXXX\n ' - }, - { - border: [false, false, false, false], - linecolors: '#000080', - style: { fontSize: 10, bold: true, color: '#a76d09' }, - text: 'FECHA Y HORA DE CERTIFICACION:' - }, - { - border: [false, false, false, false], - fontSize: 10, - text: '03/07/2020\n ' - }, - ] - } - ] - ] - } - }, - { - style: 'tableExample', - table: { - widths: [180, 200, 150], - headerRows: 1, - body: [ - - [{ text: ' PAGO EN UNA SOLA EXHIBICION', fontSize: 7, alignment: 'left', border: [false, false, false, false] }, - { text: 'Esta es una representación impresa de un CFDI', fontSize: 7, alignment: 'center', border: [false, false, false, false] }, - { text: 'Efectos fscales al pago', fontSize: 7, alignment: 'right', border: [false, false, false, false] }] - - - ] - }, - - - }, - - - - ], - - } - - constructor(xml: string) { - // @ts-ignore - this.xml = XmlToJson(xml) - } - - public async getDocument(): Promise { - return createPdf(this.docDefinition); - } - -} diff --git a/packages/cfdi/pdf/src/templates/index.ts b/packages/cfdi/pdf/src/templates/index.ts deleted file mode 100644 index 17c18046..00000000 --- a/packages/cfdi/pdf/src/templates/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { A117 } from './A117'; -export { B123 } from './B123'; -export { B111 } from './B111' -export { B112 } from './B112'; -export { B222 } from './B222'; -export { A111 } from './A111'; -export { B333 } from './B333'; diff --git a/packages/cfdi/pdf/vite.config.mts b/packages/cfdi/pdf/vite.config.mts new file mode 100644 index 00000000..8c147a43 --- /dev/null +++ b/packages/cfdi/pdf/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['pdfmake', 'pdfmake/build/pdfmake', 'pdfmake/interfaces', 'pdfmake/build/vfs_fonts', 'xml-js'], + }, + }, +})); diff --git a/packages/cfdi/rfc/README.md b/packages/cfdi/rfc/README.md new file mode 100644 index 00000000..bb2eba11 --- /dev/null +++ b/packages/cfdi/rfc/README.md @@ -0,0 +1,45 @@ +# @cfdi/rfc + +Validacion de RFC (Registro Federal de Contribuyentes) mexicano. Verifica formato, fecha, digito verificador y palabras inconvenientes. + +## Instalacion + +```bash +npm install @cfdi/rfc +``` + +## Uso + +```typescript +import { rfc } from '@cfdi/rfc'; + +// Validar un RFC +const resultado = rfc.validate('GARC850101AB1'); +// { isValid: true, type: 'PF', rfc: 'GARC850101AB1' } + +const resultado2 = rfc.validate('ABC010101XY9'); +// { isValid: false, type: '', rfc: 'ABC010101XY9' } + +// Obtener tipo de RFC +const tipo = rfc.getType('GARC850101AB1'); // 'PF' (Persona Fisica) +const tipo2 = rfc.getType('ABC010101XY9'); // 'PM' (Persona Moral) + +// Verificar palabras inconvenientes del SAT +const prohibido = rfc.hasForbiddenWords('BUEI850101AB1'); // true +``` + +## API + +### Modulo `rfc` + +| Funcion | Retorna | Descripcion | +|---------|---------|-------------| +| `validate(input)` | `{ isValid, type, rfc }` | Valida formato, fecha, digito verificador y palabras inconvenientes | +| `getType(rfc)` | `string` | Retorna `'PF'` (persona fisica, 13 caracteres) o `'PM'` (persona moral, 12 caracteres) | +| `hasForbiddenWords(rfc)` | `boolean` | Verifica si los primeros 4 caracteres estan en la lista de palabras inconvenientes del SAT | + +Sin dependencias externas. + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/rfc/package.json b/packages/cfdi/rfc/package.json index 0c42e565..f746698c 100644 --- a/packages/cfdi/rfc/package.json +++ b/packages/cfdi/rfc/package.json @@ -2,77 +2,34 @@ "name": "@cfdi/rfc", "version": "0.0.10-beta.2", "license": "MIT", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "module": "dist/rfc.esm.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "files": [ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build", + "build": "vite build --config node_modules/@recreando/vite/vite.config.lib.mts", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "peerDependencies": {}, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "author": "MisaelMa", - "size-limit": [ - { - "path": "dist/utils.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/utils.esm.js", - "limit": "10 KB" - } - ], "devDependencies": { "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", "@recreando/vite": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", + "@types/node": "^22", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", "@vitest/coverage-v8": "2.1.3", "@vitest/ui": "2.1.3" } -} \ No newline at end of file +} diff --git a/packages/cfdi/rfc/src/RfcFaker.ts b/packages/cfdi/rfc/src/RfcFaker.ts new file mode 100644 index 00000000..969c521b --- /dev/null +++ b/packages/cfdi/rfc/src/RfcFaker.ts @@ -0,0 +1,90 @@ +import { FORBIDDEN_WORD } from './common/constants'; +import { checkDigit } from './utils/checkDigit'; + +const VOWELS = 'AEIOU'; +const LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; +const HOMOCLAVE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + +const pick = (chars: string): string => + chars[Math.floor(Math.random() * chars.length)]; + +const randomInt = (min: number, max: number): number => + Math.floor(Math.random() * (max - min + 1)) + min; + +const pad2 = (n: number): string => String(n).padStart(2, '0'); + +/** Genera una fecha valida en formato YYMMDD */ +const randomDateStr = (): string => { + const year = randomInt(30, 99); // 1930-1999 para evitar fechas futuras + const month = randomInt(1, 12); + const daysInMonth = new Date(1900 + year, month, 0).getDate(); + const day = randomInt(1, daysInMonth); + return `${pad2(year)}${pad2(month)}${pad2(day)}`; +}; + +/** Genera 2 caracteres de homoclave (sin el digito verificador) */ +const randomHomoclave2 = (): string => + pick(HOMOCLAVE_CHARS) + pick(HOMOCLAVE_CHARS); + +/** + * Verifica si el prefijo de 4 letras esta en la lista de palabras prohibidas. + * Para persona moral el prefijo es de 3 letras, la funcion revisa solo los + * primeros 4 caracteres del RFC completo. + */ +const hasForbiddenPrefix = (prefix: string): boolean => + FORBIDDEN_WORD.includes(prefix.toUpperCase().slice(0, 4)); + +/** Genera un prefijo de 4 letras valido para persona fisica (AANC pattern) */ +const personaFisicaPrefix = (): string => { + let prefix: string; + do { + // Patron SAT: primera letra apellido paterno, vocal interna, letra apellido + // materno, primera letra nombre — simplificado con letras aleatorias validas + prefix = + pick(LETTERS) + pick(VOWELS) + pick(LETTERS) + pick(LETTERS); + } while (hasForbiddenPrefix(prefix)); + return prefix; +}; + +/** Genera un prefijo de 3 letras valido para persona moral */ +const personaMoralPrefix = (): string => { + let prefix: string; + do { + prefix = pick(LETTERS) + pick(LETTERS) + pick(LETTERS); + } while (hasForbiddenPrefix(prefix + 'A')); // verifica con una cuarta letra hipotetica + return prefix; +}; + +export class RfcFaker { + /** + * Genera un RFC aleatorio valido para persona fisica (13 caracteres). + */ + static persona(): string { + let rfc: string; + do { + const prefix = personaFisicaPrefix(); + const date = randomDateStr(); + const homo2 = randomHomoclave2(); + const base = `${prefix}${date}${homo2}`; + const digit = checkDigit(base + '0'); // checkDigit necesita 13 chars + rfc = `${base}${digit}`; + } while (rfc.length !== 13); + return rfc; + } + + /** + * Genera un RFC aleatorio valido para persona moral (12 caracteres). + */ + static moral(): string { + let rfc: string; + do { + const prefix = personaMoralPrefix(); + const date = randomDateStr(); + const homo2 = randomHomoclave2(); + const base = `${prefix}${date}${homo2}`; + const digit = checkDigit(base + '0'); // checkDigit maneja 12 chars con padding + rfc = `${base}${digit}`; + } while (rfc.length !== 12); + return rfc; + } +} diff --git a/packages/cfdi/rfc/src/index.ts b/packages/cfdi/rfc/src/index.ts index 9b325eef..751773f2 100644 --- a/packages/cfdi/rfc/src/index.ts +++ b/packages/cfdi/rfc/src/index.ts @@ -1 +1,4 @@ -export * as rfc from "./rfc" +export * as rfc from './rfc'; +export * from './rfc'; +export * from './value/Rfc'; +export * from './RfcFaker'; diff --git a/packages/cfdi/rfc/src/value/Rfc.ts b/packages/cfdi/rfc/src/value/Rfc.ts new file mode 100644 index 00000000..61631060 --- /dev/null +++ b/packages/cfdi/rfc/src/value/Rfc.ts @@ -0,0 +1,107 @@ +import { SPECIAL_CASES } from '../common/constants'; +import { validate } from '../rfc'; + +export class InvalidRfcError extends Error { + constructor(rfc: string) { + super(`'${rfc}' is not a valid RFC`); + this.name = 'InvalidRfcError'; + } +} + +/** + * RFCs especiales del SAT que son validos por definicion reglamentaria, + * independientemente del digito verificador. + */ +const SPECIAL_RFC_VALUES = Object.keys(SPECIAL_CASES); + +export class Rfc { + private constructor(private readonly _value: string) {} + + /** + * Factory principal: valida y lanza InvalidRfcError si el RFC es invalido. + * Los RFCs especiales (generico y extranjero) son aceptados por definicion. + */ + static of(rfc: string): Rfc { + const normalized = String(rfc).trim().toUpperCase(); + if (SPECIAL_RFC_VALUES.includes(normalized)) { + return new Rfc(normalized); + } + const result = validate(rfc); + if (!result.isValid) { + throw new InvalidRfcError(rfc); + } + return new Rfc(result.rfc); + } + + /** + * Factory segura: retorna null si el RFC es invalido. + */ + static parse(rfc: string): Rfc | null { + try { + return Rfc.of(rfc); + } catch { + return null; + } + } + + static isValid(rfc: string): boolean { + const normalized = String(rfc).trim().toUpperCase(); + if (SPECIAL_RFC_VALUES.includes(normalized)) return true; + return validate(rfc).isValid; + } + + toString(): string { + return this._value; + } + + /** Persona fisica: 13 caracteres (excluye genericos/extranjeros) */ + isFisica(): boolean { + return this._value.length === 13 && !this.isGeneric() && !this.isForeign(); + } + + /** Persona moral: 12 caracteres */ + isMoral(): boolean { + return this._value.length === 12; + } + + /** RFC generico del SAT: XAXX010101000 */ + isGeneric(): boolean { + return this._value === 'XAXX010101000'; + } + + /** RFC para operaciones con extranjeros: XEXX010101000 */ + isForeign(): boolean { + return this._value === 'XEXX010101000'; + } + + /** + * Extrae la fecha de nacimiento/constitucion codificada en el RFC (YYMMDD). + * Retorna null para RFCs especiales (generico y extranjero). + */ + obtainDate(): Date | null { + if (this.isGeneric() || this.isForeign()) return null; + + // Persona moral (12 chars): AAA + YYMMDD + HHH -> slice(3, 9) + // Persona fisica (13 chars): AAAA + YYMMDD + HHH -> slice(4, 10) + const dateStr = + this._value.length === 12 + ? this._value.slice(3, 9) + : this._value.slice(4, 10); + + const year = parseInt(dateStr.slice(0, 2), 10); + const month = parseInt(dateStr.slice(2, 4), 10) - 1; + const day = parseInt(dateStr.slice(4, 6), 10); + + // Heuristica de siglo: si YY <= anio actual => 2000s, si no => 1900s + const currentYear = new Date().getFullYear() % 100; + const century = year <= currentYear ? 2000 : 1900; + + const date = new Date(century + year, month, day); + if (isNaN(date.getTime())) return null; + return date; + } + + equals(other: Rfc): boolean { + return this._value === other._value; + } +} diff --git a/packages/cfdi/rfc/test/RfcFaker.test.ts b/packages/cfdi/rfc/test/RfcFaker.test.ts new file mode 100644 index 00000000..0af3bd6b --- /dev/null +++ b/packages/cfdi/rfc/test/RfcFaker.test.ts @@ -0,0 +1,107 @@ +import { describe, expect, it } from 'vitest'; +import { validate } from '../src/rfc'; +import { Rfc } from '../src/value/Rfc'; +import { RfcFaker } from '../src/RfcFaker'; + +describe('RfcFaker.persona()', () => { + it('genera un RFC de 13 caracteres', () => { + const rfc = RfcFaker.persona(); + expect(rfc).toHaveLength(13); + }); + + it('genera un RFC que pasa la validacion de la funcion validate()', () => { + const rfc = RfcFaker.persona(); + const result = validate(rfc); + expect(result.isValid).toBe(true); + }); + + it('genera un RFC reconocido como persona fisica por Rfc', () => { + const rfcStr = RfcFaker.persona(); + const rfc = Rfc.of(rfcStr); + expect(rfc.isFisica()).toBe(true); + expect(rfc.isMoral()).toBe(false); + }); + + it('genera un RFC que no es generico ni extranjero', () => { + const rfc = Rfc.of(RfcFaker.persona()); + expect(rfc.isGeneric()).toBe(false); + expect(rfc.isForeign()).toBe(false); + }); + + it('genera RFCs distintos en multiples llamadas', () => { + // Con alta probabilidad, dos RFCs aleatorios no seran iguales + const rfcs = new Set(Array.from({ length: 10 }, () => RfcFaker.persona())); + expect(rfcs.size).toBeGreaterThan(1); + }); + + it('el tipo retornado por validate() es "person"', () => { + const rfc = RfcFaker.persona(); + expect(validate(rfc).type).toBe('person'); + }); + + it('genera multiples RFCs validos consecutivos', () => { + for (let i = 0; i < 20; i++) { + const rfc = RfcFaker.persona(); + const result = validate(rfc); + expect(result.isValid).toBe(true); + } + }); +}); + +describe('RfcFaker.moral()', () => { + it('genera un RFC de 12 caracteres', () => { + const rfc = RfcFaker.moral(); + expect(rfc).toHaveLength(12); + }); + + it('genera un RFC que pasa la validacion de la funcion validate()', () => { + const rfc = RfcFaker.moral(); + const result = validate(rfc); + expect(result.isValid).toBe(true); + }); + + it('genera un RFC reconocido como persona moral por Rfc', () => { + const rfcStr = RfcFaker.moral(); + const rfc = Rfc.of(rfcStr); + expect(rfc.isMoral()).toBe(true); + expect(rfc.isFisica()).toBe(false); + }); + + it('el tipo retornado por validate() es "company"', () => { + const rfc = RfcFaker.moral(); + expect(validate(rfc).type).toBe('company'); + }); + + it('genera multiples RFCs validos consecutivos', () => { + for (let i = 0; i < 20; i++) { + const rfc = RfcFaker.moral(); + const result = validate(rfc); + expect(result.isValid).toBe(true); + } + }); + + it('genera RFCs distintos en multiples llamadas', () => { + const rfcs = new Set(Array.from({ length: 10 }, () => RfcFaker.moral())); + expect(rfcs.size).toBeGreaterThan(1); + }); +}); + +describe('diferencias entre persona() y moral()', () => { + it('persona() y moral() generan longitudes distintas', () => { + expect(RfcFaker.persona()).toHaveLength(13); + expect(RfcFaker.moral()).toHaveLength(12); + }); + + it('los RFCs generados son strings mayusculas', () => { + const persona = RfcFaker.persona(); + const moral = RfcFaker.moral(); + expect(persona).toBe(persona.toUpperCase()); + expect(moral).toBe(moral.toUpperCase()); + }); + + it('los RFCs generados solo contienen caracteres validos del SAT', () => { + const rfcRegex = /^[A-ZÑ&]{3,4}[0-9]{6}[A-Z0-9]{3}$/; + expect(RfcFaker.persona()).toMatch(rfcRegex); + expect(RfcFaker.moral()).toMatch(rfcRegex); + }); +}); diff --git a/packages/cfdi/rfc/test/blah.test.ts b/packages/cfdi/rfc/test/blah.test.ts index 6ac59191..68a61c59 100644 --- a/packages/cfdi/rfc/test/blah.test.ts +++ b/packages/cfdi/rfc/test/blah.test.ts @@ -1,7 +1,9 @@ -import { describe, expect, it, test } from 'vitest'; +// Archivo legado reemplazado por rfc.test.ts, value/Rfc.test.ts y RfcFaker.test.ts +import { describe, it } from 'vitest'; -describe('blah', () => { - it('works', () => { - expect(2).toEqual(2); +describe('legado', () => { + it('migrado a archivos de test dedicados', () => { + // Tests movidos a test/rfc.test.ts, test/value/Rfc.test.ts y test/RfcFaker.test.ts }); }); + diff --git a/packages/cfdi/rfc/test/rfc.test.ts b/packages/cfdi/rfc/test/rfc.test.ts new file mode 100644 index 00000000..d465458b --- /dev/null +++ b/packages/cfdi/rfc/test/rfc.test.ts @@ -0,0 +1,111 @@ +import { describe, expect, it } from 'vitest'; +import { getType, hasForbiddenWords, validate } from '../src/rfc'; + +// RFC de prueba verificados con la funcion checkDigit del SAT +const RFC_PERSONA_FISICA = 'GODE561231GR8'; // persona fisica valida +const RFC_PERSONA_MORAL = 'BMC860829IF3'; // persona moral valida + +describe('validate()', () => { + describe('RFCs validos', () => { + it('acepta RFC valido de persona fisica (13 chars)', () => { + const result = validate(RFC_PERSONA_FISICA); + expect(result.isValid).toBe(true); + expect(result.type).toBe('person'); + expect(result.rfc).toBe(RFC_PERSONA_FISICA); + }); + + it('acepta RFC valido de persona moral (12 chars)', () => { + const result = validate(RFC_PERSONA_MORAL); + expect(result.isValid).toBe(true); + expect(result.type).toBe('company'); + expect(result.rfc).toBe(RFC_PERSONA_MORAL); + }); + + it('normaliza el input — minusculas y espacios extra', () => { + const result = validate(' gode561231gr8 '); + expect(result.isValid).toBe(true); + expect(result.rfc).toBe(RFC_PERSONA_FISICA); + }); + + it('siempre retorna el objeto con la propiedad rfc aunque sea invalido', () => { + const result = validate('invalido'); + expect(result).toHaveProperty('isValid'); + expect(result).toHaveProperty('type'); + expect(result).toHaveProperty('rfc'); + }); + }); + + describe('RFCs invalidos', () => { + it('rechaza cadena vacia', () => { + const result = validate(''); + expect(result.isValid).toBe(false); + }); + + it('rechaza RFC demasiado corto', () => { + expect(validate('GOD56').isValid).toBe(false); + }); + + it('rechaza RFC demasiado largo', () => { + expect(validate('GODE5612311234GR8X').isValid).toBe(false); + }); + + it('rechaza RFC con mes imposible (13)', () => { + // La fecha YYMMDD con MM=13 es invalida + expect(validate('GODE561301GR8').isValid).toBe(false); + }); + + it('rechaza RFC con dia imposible (00)', () => { + expect(validate('GODE561200GR8').isValid).toBe(false); + }); + + it('rechaza RFC con digito verificador incorrecto', () => { + // Ultimo digito cambiado a uno incorrecto + const rfcMalo = RFC_PERSONA_FISICA.slice(0, -1) + '9'; + expect(validate(rfcMalo).isValid).toBe(false); + }); + + it('rechaza RFC con palabra prohibida en prefijo', () => { + // Cualquier RFC cuyo prefijo de 4 letras sea palabra prohibida + // Nota: el formato puede ser valido pero la palabra lo invalida + const result = validate('BUEI010101XX0'); + expect(result.isValid).toBe(false); + }); + }); +}); + +describe('getType()', () => { + it('retorna "person" para RFC de 13 caracteres', () => { + expect(getType(RFC_PERSONA_FISICA)).toBe('person'); + }); + + it('retorna "company" para RFC de 12 caracteres', () => { + expect(getType(RFC_PERSONA_MORAL)).toBe('company'); + }); + + it('retorna "generic" para XAXX010101000', () => { + expect(getType('XAXX010101000')).toBe('generic'); + }); + + it('retorna "foreign" para XEXX010101000', () => { + expect(getType('XEXX010101000')).toBe('foreign'); + }); +}); + +describe('hasForbiddenWords()', () => { + it('detecta palabras prohibidas al inicio del RFC', () => { + expect(hasForbiddenWords('BUEI010101XX0')).toBe(true); + expect(hasForbiddenWords('CACA010101XX0')).toBe(true); + expect(hasForbiddenWords('MEAR010101XX0')).toBe(true); + expect(hasForbiddenWords('PUTA010101XX0')).toBe(true); + }); + + it('no detecta palabra prohibida en RFC normal', () => { + expect(hasForbiddenWords(RFC_PERSONA_FISICA)).toBe(false); + expect(hasForbiddenWords(RFC_PERSONA_MORAL)).toBe(false); + }); + + it('no detecta palabra prohibida si el prefijo no coincide exactamente', () => { + // MULE no esta en la lista, solo MULA + expect(hasForbiddenWords('MULE010101XX0')).toBe(false); + }); +}); diff --git a/packages/cfdi/rfc/test/value/Rfc.test.ts b/packages/cfdi/rfc/test/value/Rfc.test.ts new file mode 100644 index 00000000..a30bf69e --- /dev/null +++ b/packages/cfdi/rfc/test/value/Rfc.test.ts @@ -0,0 +1,222 @@ +import { describe, expect, it } from 'vitest'; +import { InvalidRfcError, Rfc } from '../../src/value/Rfc'; + +// RFCs de prueba verificados con la logica checkDigit del SAT +const RFC_FISICA = 'GODE561231GR8'; // persona fisica valida (13 chars) +const RFC_MORAL = 'BMC860829IF3'; // persona moral valida (12 chars) +const RFC_GENERICO = 'XAXX010101000'; +const RFC_EXTRANJERO = 'XEXX010101000'; + +describe('Rfc.of()', () => { + it('crea instancia con RFC valido de persona fisica', () => { + const rfc = Rfc.of(RFC_FISICA); + expect(rfc.toString()).toBe(RFC_FISICA); + }); + + it('crea instancia con RFC valido de persona moral', () => { + const rfc = Rfc.of(RFC_MORAL); + expect(rfc.toString()).toBe(RFC_MORAL); + }); + + it('acepta RFC generico XAXX010101000 por definicion reglamentaria', () => { + const rfc = Rfc.of(RFC_GENERICO); + expect(rfc.toString()).toBe(RFC_GENERICO); + }); + + it('acepta RFC para extranjeros XEXX010101000 por definicion reglamentaria', () => { + const rfc = Rfc.of(RFC_EXTRANJERO); + expect(rfc.toString()).toBe(RFC_EXTRANJERO); + }); + + it('normaliza el input a mayusculas y sin espacios', () => { + const rfc = Rfc.of(' gode561231gr8 '); + expect(rfc.toString()).toBe(RFC_FISICA); + }); + + it('lanza InvalidRfcError con RFC invalido', () => { + expect(() => Rfc.of('RFC_INVALIDO')).toThrow(InvalidRfcError); + }); + + it('el mensaje de error incluye el RFC proporcionado', () => { + expect(() => Rfc.of('MAL')).toThrow("'MAL' is not a valid RFC"); + }); + + it('lanza InvalidRfcError con cadena vacia', () => { + expect(() => Rfc.of('')).toThrow(InvalidRfcError); + }); +}); + +describe('Rfc.parse()', () => { + it('retorna instancia Rfc con RFC valido de persona fisica', () => { + const rfc = Rfc.parse(RFC_FISICA); + expect(rfc).not.toBeNull(); + expect(rfc!.toString()).toBe(RFC_FISICA); + }); + + it('retorna instancia Rfc con RFC valido de persona moral', () => { + const rfc = Rfc.parse(RFC_MORAL); + expect(rfc).not.toBeNull(); + expect(rfc!.toString()).toBe(RFC_MORAL); + }); + + it('retorna null con RFC invalido', () => { + expect(Rfc.parse('INVALIDO')).toBeNull(); + }); + + it('retorna null con cadena vacia', () => { + expect(Rfc.parse('')).toBeNull(); + }); + + it('acepta RFC generico', () => { + expect(Rfc.parse(RFC_GENERICO)).not.toBeNull(); + }); + + it('acepta RFC de extranjero', () => { + expect(Rfc.parse(RFC_EXTRANJERO)).not.toBeNull(); + }); +}); + +describe('Rfc.isValid()', () => { + it('retorna true para RFC de persona fisica valido', () => { + expect(Rfc.isValid(RFC_FISICA)).toBe(true); + }); + + it('retorna true para RFC de persona moral valido', () => { + expect(Rfc.isValid(RFC_MORAL)).toBe(true); + }); + + it('retorna true para RFC generico', () => { + expect(Rfc.isValid(RFC_GENERICO)).toBe(true); + }); + + it('retorna true para RFC de extranjero', () => { + expect(Rfc.isValid(RFC_EXTRANJERO)).toBe(true); + }); + + it('retorna false para RFC con formato invalido', () => { + expect(Rfc.isValid('INVALIDO')).toBe(false); + }); + + it('retorna false para RFC con digito verificador incorrecto', () => { + const rfcMalo = RFC_FISICA.slice(0, -1) + '9'; + expect(Rfc.isValid(rfcMalo)).toBe(false); + }); +}); + +describe('isFisica()', () => { + it('retorna true para persona fisica (13 chars)', () => { + expect(Rfc.of(RFC_FISICA).isFisica()).toBe(true); + }); + + it('retorna false para persona moral (12 chars)', () => { + expect(Rfc.of(RFC_MORAL).isFisica()).toBe(false); + }); + + it('retorna false para RFC generico aunque tenga 13 chars', () => { + expect(Rfc.of(RFC_GENERICO).isFisica()).toBe(false); + }); + + it('retorna false para RFC de extranjero aunque tenga 13 chars', () => { + expect(Rfc.of(RFC_EXTRANJERO).isFisica()).toBe(false); + }); +}); + +describe('isMoral()', () => { + it('retorna true para persona moral (12 chars)', () => { + expect(Rfc.of(RFC_MORAL).isMoral()).toBe(true); + }); + + it('retorna false para persona fisica (13 chars)', () => { + expect(Rfc.of(RFC_FISICA).isMoral()).toBe(false); + }); +}); + +describe('isGeneric()', () => { + it('retorna true solo para XAXX010101000', () => { + expect(Rfc.of(RFC_GENERICO).isGeneric()).toBe(true); + }); + + it('retorna false para RFC normal de persona fisica', () => { + expect(Rfc.of(RFC_FISICA).isGeneric()).toBe(false); + }); + + it('retorna false para RFC de extranjero', () => { + expect(Rfc.of(RFC_EXTRANJERO).isGeneric()).toBe(false); + }); +}); + +describe('isForeign()', () => { + it('retorna true solo para XEXX010101000', () => { + expect(Rfc.of(RFC_EXTRANJERO).isForeign()).toBe(true); + }); + + it('retorna false para RFC normal de persona fisica', () => { + expect(Rfc.of(RFC_FISICA).isForeign()).toBe(false); + }); + + it('retorna false para RFC generico', () => { + expect(Rfc.of(RFC_GENERICO).isForeign()).toBe(false); + }); +}); + +describe('obtainDate()', () => { + it('extrae la fecha de un RFC de persona fisica', () => { + // GODE561231GR8: date part = 561231 -> 31 diciembre 1956 + const rfc = Rfc.of(RFC_FISICA); + const date = rfc.obtainDate(); + expect(date).not.toBeNull(); + expect(date!.getFullYear()).toBe(1956); + expect(date!.getMonth()).toBe(11); // diciembre = indice 11 + expect(date!.getDate()).toBe(31); + }); + + it('extrae la fecha de un RFC de persona moral', () => { + // BMC860829IF3: date part = 860829 -> 29 agosto 1986 + const rfc = Rfc.of(RFC_MORAL); + const date = rfc.obtainDate(); + expect(date).not.toBeNull(); + expect(date!.getFullYear()).toBe(1986); + expect(date!.getMonth()).toBe(7); // agosto = indice 7 + expect(date!.getDate()).toBe(29); + }); + + it('retorna null para RFC generico', () => { + expect(Rfc.of(RFC_GENERICO).obtainDate()).toBeNull(); + }); + + it('retorna null para RFC de extranjero', () => { + expect(Rfc.of(RFC_EXTRANJERO).obtainDate()).toBeNull(); + }); +}); + +describe('equals()', () => { + it('dos instancias con el mismo RFC son iguales', () => { + const a = Rfc.of(RFC_FISICA); + const b = Rfc.of(RFC_FISICA); + expect(a.equals(b)).toBe(true); + }); + + it('dos instancias con diferentes RFCs no son iguales', () => { + const a = Rfc.of(RFC_FISICA); + const b = Rfc.of(RFC_MORAL); + expect(a.equals(b)).toBe(false); + }); + + it('es reflexivo: a.equals(a) es true', () => { + const a = Rfc.of(RFC_FISICA); + expect(a.equals(a)).toBe(true); + }); + + it('es simetrico: a.equals(b) == b.equals(a)', () => { + const a = Rfc.of(RFC_FISICA); + const b = Rfc.of(RFC_MORAL); + expect(a.equals(b)).toBe(b.equals(a)); + }); +}); + +describe('toString()', () => { + it('retorna el valor del RFC en mayusculas', () => { + const rfc = Rfc.of(RFC_FISICA); + expect(rfc.toString()).toBe(RFC_FISICA); + }); +}); diff --git a/packages/cfdi/curp/.eslintrc.js b/packages/cfdi/schema/.eslintrc.js similarity index 100% rename from packages/cfdi/curp/.eslintrc.js rename to packages/cfdi/schema/.eslintrc.js diff --git a/packages/cfdi/curp/.gitignore b/packages/cfdi/schema/.gitignore similarity index 100% rename from packages/cfdi/curp/.gitignore rename to packages/cfdi/schema/.gitignore diff --git a/packages/cfdi/curp/.npmignore b/packages/cfdi/schema/.npmignore similarity index 100% rename from packages/cfdi/curp/.npmignore rename to packages/cfdi/schema/.npmignore diff --git a/packages/cfdi/curp/LICENSE b/packages/cfdi/schema/LICENSE similarity index 100% rename from packages/cfdi/curp/LICENSE rename to packages/cfdi/schema/LICENSE diff --git a/packages/cfdi/schema/README.md b/packages/cfdi/schema/README.md new file mode 100644 index 00000000..2a9ad366 --- /dev/null +++ b/packages/cfdi/schema/README.md @@ -0,0 +1,295 @@ +# @cfdi/schema - Clean Code Refactored Version + +Sistema refactorizado para procesamiento de archivos XSD con arquitectura limpia, reutilización de código y eliminación de duplicaciones. + +## 🎯 Características Principales + +- ✅ **Carga Universal**: Soporte para URLs y archivos locales +- ✅ **Clean Code**: Eliminación de duplicaciones y centralización de lógica +- ✅ **Arquitectura Modular**: Clases base reutilizables y utilidades comunes +- ✅ **Factory Pattern**: Creación simplificada de procesadores +- ✅ **Constantes Centralizadas**: Sin valores hardcodeados +- ✅ **Interfaces Estandarizadas**: APIs consistentes +- ✅ **Compatibilidad hacia atrás**: Migración gradual sin romper código existente + +## 📦 Instalación + +```bash +npm install @cfdi/schema +``` + +## 🚀 Uso Rápido + +### Método 1: Factory Pattern (Recomendado) + +```typescript +import { processXSD, createCfdiProcessor } from '@cfdi/schema'; + +// Procesamiento directo desde URL +const cfdiResult = await processXSD( + 'cfdi', + 'https://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd' +); + +// Procesamiento directo desde archivo local +const catalogResult = await processXSD('catalog', './path/to/catalog.xsd'); + +// Con configuración personalizada +const processor = createCfdiProcessor({ + source: 'https://example.com/schema.xsd', + timeout: 20000, + encoding: 'utf-8', +}); +const result = await processor.process(); +``` + +### Método 2: Uso Tradicional (Compatible) + +```typescript +import { CfdiProcess, CatalogProcess } from '@cfdi/schema'; + +// CFDI desde URL +const cfdiProcessor = CfdiProcess.of(); +cfdiProcessor.setConfig({ + source: 'https://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd', +}); +const cfdiResult = await cfdiProcessor.process(); + +// Catálogo desde archivo local +const catalogProcessor = CatalogProcess.of(); +catalogProcessor.setConfig({ source: './catalog.xsd' }); +const catalogResult = await catalogProcessor.process(); +``` + +### Método 3: XSDLoader Directo + +```typescript +import { XSDLoader } from '@cfdi/schema'; + +const loader = XSDLoader.getInstance(); + +// Cargar múltiples archivos +const results = await loader.loadMultipleXSD([ + { source: 'https://example.com/schema1.xsd' }, + { source: './local-schema.xsd', timeout: 5000 }, +]); +``` + +## 🏗️ Arquitectura + +### Estructura Modular + +``` +src/ +├── common/ # Código común y reutilizable +│ ├── constants.ts # Constantes centralizadas +│ ├── interfaces.ts # Interfaces estandarizadas +│ ├── xml-utils.ts # Utilidades XML reutilizables +│ ├── base-processor.ts # Clase base abstracta +│ └── processor-factory.ts # Factory pattern +├── cfdi.xsd.ts # Procesador CFDI refactorizado +├── catalogos.xsd.ts # Procesador catálogos refactorizado +├── loader.xsd.ts # Cargador XSD universal +└── index.ts # Exportaciones principales +``` + +### Principios Aplicados + +1. **DRY (Don't Repeat Yourself)**: Eliminación de código duplicado +2. **Single Responsibility**: Cada clase tiene una responsabilidad específica +3. **Open/Closed**: Extensible sin modificar código existente +4. **Dependency Inversion**: Dependencias inyectadas, no hardcodeadas +5. **Factory Pattern**: Creación centralizada de objetos + +## 🔧 APIs Principales + +### ProcessorFactory + +```typescript +import { ProcessorFactory } from '@cfdi/schema'; + +// Crear procesador CFDI +const cfdiProcessor = ProcessorFactory.createCfdiProcessor({ + source: 'https://example.com/cfdi.xsd', +}); + +// Crear procesador de catálogos +const catalogProcessor = ProcessorFactory.createCatalogProcessor({ + source: './catalog.xsd', +}); + +// Procesamiento directo +const result = await ProcessorFactory.processXSD( + 'cfdi', + 'https://example.com/schema.xsd' +); +``` + +### XMLUtils (Utilidades Reutilizables) + +```typescript +import { XMLUtils } from '@cfdi/schema'; + +// Convertir a XSD con formato estándar +const xsdString = XMLUtils.toXsd(elementCompact); + +// Crear esquema base con namespaces +const schemaBase = XMLUtils.createSchemaBase({ + targetNamespace: 'custom-namespace', +}); + +// Limpiar anotaciones +XMLUtils.removeAnnotations(element); + +// Verificar elementos de solo atributos +const isOnlyAttr = XMLUtils.isOnlyAttribute(element); +``` + +### Constantes Centralizadas + +```typescript +import { XSD_CONSTANTS } from '@cfdi/schema'; + +// Usar configuraciones predefinidas +const timeout = XSD_CONSTANTS.DEFAULT_TIMEOUT; +const encoding = XSD_CONSTANTS.DEFAULT_ENCODING; +const namespaces = XSD_CONSTANTS.NAMESPACES; +const outputOptions = XSD_CONSTANTS.OUTPUT_OPTIONS; +``` + +## 🔄 Migración desde Versión Anterior + +### Código Anterior + +```typescript +// ❌ Versión anterior con duplicaciones +const cfdiProcessor = CfdiProcess.of(); +cfdiProcessor.setConfig({ path: './schema.xsd' }); +const result = await cfdiProcessor.process(); +``` + +### Código Refactorizado + +```typescript +// ✅ Versión refactorizada (compatible) +const cfdiProcessor = CfdiProcess.of(); +cfdiProcessor.setConfig({ source: './schema.xsd' }); // 'path' también funciona +const result = await cfdiProcessor.process(); + +// ✅ O mejor aún, usar factory +const result = await processXSD('cfdi', './schema.xsd'); +``` + +## 🎨 Personalización Avanzada + +### Extender BaseXSDProcessor + +```typescript +import { BaseXSDProcessor, ProcessorConfig } from '@cfdi/schema'; + +class CustomProcessor extends BaseXSDProcessor { + private static instance: CustomProcessor; + + static of(): CustomProcessor { + if (!CustomProcessor.instance) { + CustomProcessor.instance = new CustomProcessor(); + } + return CustomProcessor.instance; + } + + async process(): Promise { + this.validateConfig(); + const xsd = await this.readXsd(); + // Lógica personalizada + return this.customProcessing(xsd); + } + + private customProcessing(xsd: any): any { + // Implementación específica + } +} +``` + +### Configuración de XMLUtils + +```typescript +import { XMLUtils, XSD_CONSTANTS } from '@cfdi/schema'; + +// Crear esquema con configuración personalizada +const customSchema = XMLUtils.createSchemaBase({ + namespaces: { + 'xmlns:custom': 'http://custom.namespace.com', + }, + targetNamespace: 'http://custom.namespace.com', + imports: [ + { + namespace: 'http://custom.namespace.com', + schemaLocation: 'http://custom.namespace.com/schema.xsd', + }, + ], +}); +``` + +## 🛠️ Configuración Avanzada + +### Opciones de LoaderOptions + +```typescript +interface LoaderOptions { + source: string; // URL o ruta local + encoding?: BufferEncoding; // Codificación (default: 'utf-8') + timeout?: number; // Timeout para URLs (default: 15000ms) +} +``` + +### Opciones de ProcessorConfig + +```typescript +interface ProcessorConfig { + source?: string; // URL o ruta (recomendado) + path?: string; // Compatibilidad hacia atrás + encoding?: BufferEncoding; + timeout?: number; +} +``` + +## 📊 Ventajas del Refactoring + +| Aspecto | Antes | Después | +| ----------------- | ------------------------------------- | ---------------------------------- | +| **Duplicación** | Métodos repetidos en múltiples clases | Lógica centralizada en clases base | +| **Configuración** | Hardcoded en cada clase | Constantes centralizadas | +| **Creación** | Singleton manual por clase | Factory pattern unificado | +| **Reutilización** | Código copiado | Utilidades compartidas | +| **Mantenimiento** | Cambios en múltiples lugares | Single point of change | +| **Testing** | Tests duplicados | Tests centralizados | + +## 🔍 Debugging y Logging + +El sistema incluye logging automático para facilitar el debugging: + +```typescript +// Logs automáticos incluidos: +// - "Descargando XSD desde URL: [url]" +// - "Cargando XSD desde archivo local: [path]" +// - "XSD cargado exitosamente desde: [source]" +``` + +## 📋 Ejemplos Completos + +Ver `/examples/` para ejemplos detallados de uso y migración. + +## 🤝 Contribución + +Al contribuir, asegúrate de seguir los principios de clean code implementados: + +1. No duplicar lógica existente +2. Usar constantes centralizadas +3. Extender clases base cuando sea apropiado +4. Mantener compatibilidad hacia atrás +5. Añadir tests para nueva funcionalidad + +## 📝 Changelog + +- **v2.0.0**: Refactoring completo con clean code +- **v1.x.x**: Versión legacy (compatibilidad mantenida) diff --git a/packages/cfdi/schema/UPGRADE_NOTES.md b/packages/cfdi/schema/UPGRADE_NOTES.md new file mode 100644 index 00000000..f644de16 --- /dev/null +++ b/packages/cfdi/schema/UPGRADE_NOTES.md @@ -0,0 +1,122 @@ +# Notas de Actualización - XSDLoader + +## Resumen de Cambios + +Se ha implementado una nueva clase `XSDLoader` que unifica la carga de archivos XSD tanto desde rutas locales como desde URLs. Esta implementación mejora la flexibilidad y mantiene compatibilidad hacia atrás. + +## Nuevas Funcionalidades + +### 1. Clase XSDLoader + +- **Carga desde URLs**: Descarga automática de archivos XSD con timeout configurable +- **Carga desde rutas locales**: Lectura de archivos del sistema de archivos +- **Validación automática**: Verifica extensión .xsd y contenido válido +- **Manejo de errores**: Mensajes de error descriptivos +- **Singleton Pattern**: Instancia única reutilizable + +### 2. Actualizaciones en CfdiProcess + +- Migrado para usar `XSDLoader` en lugar de `readFileSync` directo +- Nuevo método `setConfig()` acepta `source` además de `path` +- Método `readXsd()` ahora es asíncrono + +### 3. Actualizaciones en CatalogProcess + +- Renombrada de `Catalogs` a `CatalogProcess` para consistencia +- Implementación similar a `CfdiProcess` usando `XSDLoader` +- Ya no extiende de la clase `Process` + +## Uso + +### Básico + +```typescript +import { CfdiProcess, CatalogProcess, XSDLoader } from '@cfdi/schema'; + +// Cargar desde URL +const cfdiProcessor = CfdiProcess.of(); +cfdiProcessor.setConfig({ + source: 'https://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd', +}); +const result = await cfdiProcessor.process(); + +// Cargar desde archivo local +const catalogProcessor = CatalogProcess.of(); +catalogProcessor.setConfig({ + source: './path/to/catalog.xsd', +}); +const catalogResult = await catalogProcessor.process(); +``` + +### Uso directo de XSDLoader + +```typescript +const xsdLoader = XSDLoader.getInstance(); + +// Cargar un solo archivo +const xsdData = await xsdLoader.loadXSD({ + source: 'https://example.com/schema.xsd', + timeout: 15000, +}); + +// Cargar múltiples archivos +const multipleXsd = await xsdLoader.loadMultipleXSD([ + { source: 'https://example.com/schema1.xsd' }, + { source: './local-schema.xsd' }, +]); +``` + +## Compatibilidad hacia atrás + +El código existente seguirá funcionando sin cambios: + +```typescript +// ✅ Esto sigue funcionando +const processor = CfdiProcess.of(); +processor.setConfig({ path: './mi-archivo.xsd' }); +``` + +## Validaciones incluidas + +- ✅ Verificación de extensión `.xsd` +- ✅ Validación de contenido XML válido +- ✅ Verificación de esquema XSD (presencia de `xs:schema`) +- ✅ Manejo de timeouts en descargas +- ✅ Verificación de existencia de archivos locales + +## Manejo de Errores + +La clase proporciona mensajes de error descriptivos: + +- `"El archivo debe tener extensión .xsd"` +- `"El archivo no existe: /path/to/file"` +- `"Timeout al descargar el archivo desde URL"` +- `"El archivo no es un esquema XSD válido"` + +## Archivos modificados + +- ✅ `src/XSDLoader.ts` - Nueva clase principal +- ✅ `src/CfdiProcess.ts` - Actualizado para usar XSDLoader +- ✅ `src/CatalogProcess.ts` - Actualizado y renombrado +- ✅ `src/index.ts` - Exportaciones actualizadas +- ✅ `src/examples/usage-example.ts` - Ejemplos de uso + +## Dependencias + +No se requieren nuevas dependencias. Utiliza las librerías existentes: + +- `xml-js` para parsing XML +- `fs` para archivos locales +- `fetch` (nativo) para URLs + +## Migración recomendada + +Para aprovechar al máximo las nuevas funcionalidades, considera migrar gradualmente: + +1. Reemplaza `path` por `source` en las configuraciones +2. Actualiza `Catalogs` por `CatalogProcess` si lo usas directamente +3. Añade manejo de errores async/await donde sea necesario + +## Ejemplos completos + +Ver `src/examples/usage-example.ts` para ejemplos detallados de uso y migración. diff --git a/packages/cfdi/curp/jest.config.js b/packages/cfdi/schema/jest.config.js similarity index 100% rename from packages/cfdi/curp/jest.config.js rename to packages/cfdi/schema/jest.config.js diff --git a/packages/cfdi/schema/package.json b/packages/cfdi/schema/package.json new file mode 100644 index 00000000..387bb7c9 --- /dev/null +++ b/packages/cfdi/schema/package.json @@ -0,0 +1,53 @@ +{ + "name": "@cfdi/schema", + "version": "0.0.13", + "license": "MIT", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "source": "./src/index.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org/", + "tag": "latest", + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/MisaelMa/recreando" + }, + "author": { + "name": "Amir Misael Marin Coh, Signati", + "email": "amisael.amir.misae@gmail.com, signatidev@gmail.com,", + "url": "" + }, + "dependencies": { + "xsd2jsonschema": "^0.3.7", + "xml-js": "^1.6.11", + "ajv": "^8.12.0" + }, + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/cfdi/schema/src/catalogos.xsd.ts b/packages/cfdi/schema/src/catalogos.xsd.ts new file mode 100644 index 00000000..356591c2 --- /dev/null +++ b/packages/cfdi/schema/src/catalogos.xsd.ts @@ -0,0 +1,40 @@ +import { ElementCompact } from 'xml-js'; +import { BaseXSDProcessor } from './common/base-processor'; +import { XMLUtils } from './common/xml-utils'; +import { XSD_CONSTANTS } from './common/constants'; + +export class CatalogProcess extends BaseXSDProcessor { + private static instance: CatalogProcess; + + public static of(): CatalogProcess { + if (!CatalogProcess.instance) { + CatalogProcess.instance = new CatalogProcess(); + } + return CatalogProcess.instance; + } + + async process() { + this.validateConfig(); + const xsd = await this.readXsd(); + const processedXsd = this.processXsdData(xsd); + const result = XMLUtils.toXsd(processedXsd); + return { catalogos: result }; + } + + private processXsdData(target: ElementCompact): ElementCompact { + const catalogos = target['xs:schema']['xs:simpleType'] as any[]; + this.removePropertiesCatalog(catalogos, XSD_CONSTANTS.CATALOG_REMOVE_PROPERTIES); + return target; + } + + private removePropertiesCatalog(catalogos: any[], properties: readonly string[]): void { + properties.forEach((property) => { + const index = catalogos.findIndex( + (catalog) => catalog._attributes?.name === property + ); + if (index !== -1) { + catalogos[index]['xs:restriction']['xs:enumeration'] = []; + } + }); + } +} diff --git a/packages/cfdi/schema/src/cfdi.xsd.ts b/packages/cfdi/schema/src/cfdi.xsd.ts new file mode 100644 index 00000000..667a05a7 --- /dev/null +++ b/packages/cfdi/schema/src/cfdi.xsd.ts @@ -0,0 +1,143 @@ +import { ElementCompact } from 'xml-js'; +import { BaseXSDProcessor } from './common/base-processor'; +import { XMLUtils } from './common/xml-utils'; +import { XSD_CONSTANTS } from './common/constants'; + +export interface XsdElement { + xsd: ElementCompact; + name: string; +} + +export class CfdiXsd extends BaseXSDProcessor { + private static instance: CfdiXsd; + + public static of(): CfdiXsd { + if (!CfdiXsd.instance) { + CfdiXsd.instance = new CfdiXsd(); + } + return CfdiXsd.instance; + } + + async process() { + this.validateConfig(); + const xsd = await this.getXsd(); + return XMLUtils.transformSchemasToXsd(xsd); + } + + public async getXsd(): Promise { + const targetXsd = await this.readXsd(); + + const xsd: ElementCompact[] = []; + this.schemaWrap(targetXsd, xsd, null, 'comprobante', 'comprobante'); + + const comprobante = this.createComprobanteElement(targetXsd); + xsd.unshift({ + name: 'comprobante', + path: 'comprobante', + key: 'comprobante', + folder: 'comprobante', + xsd: comprobante, + }); + + return xsd as XsdElement[]; + } + + public async getXsdByElement(element: string, key: string = 'name'): Promise { + const xsd = await this.getXsd(); + //console.log(xsd); + const elementXsd = xsd.find((x: Record) => x[key] === element); + return elementXsd || undefined; + } + + private schemaWrap( + xsd: ElementCompact, + base: ElementCompact[] = [], + folder: string | null = null, + path = '', + key = '' + ): void { + const schema = xsd['xs:schema']['xs:element']['xs:complexType'][ + 'xs:sequence' + ]['xs:element'] as Array; + const items = Array.isArray(schema) ? schema : [schema]; + + items.forEach((element) => { + const name = XMLUtils.getElementName(element); + const newXsd = this.generateXsd( + element, + 'json', + folder || name, + path, + `${key}_${name}` + ); + + const isOnlyAttribute = !!newXsd.xsd['xs:schema']?.['xs:element']?.['xs:complexType']?.['xs:sequence']; + + if (!isOnlyAttribute) { + base.push(newXsd); + } else { + const newXsdElement = { ...newXsd }; + + this.schemaWrap( + newXsdElement.xsd, + base, + folder || name, + `${path}_${name}` || name, + `${path}_${name}` + ); + + delete newXsd.xsd['xs:schema']?.['xs:element']['xs:complexType']['xs:sequence']; + base.push(newXsd); + } + }); + } + + private createComprobanteElement(xsd: ElementCompact): ElementCompact { + const comprobante = { ...xsd }; + delete comprobante['xs:schema']['xs:element']['xs:complexType']['xs:sequence']; + //console.log(JSON.stringify(comprobante, null, 2)); + return comprobante; + } + + /** + * Genera esquemas indexados por nombre (utilidad legacy) + */ + generateSchemas(schemas: any[]): Record { + return XMLUtils.generateSchemasMap(schemas); + } + + /** + * Verifica si elemento tiene solo atributos (utilidad legacy) + */ + isOnlyAttribute(element: any): boolean { + return XMLUtils.isOnlyAttribute(element); + } + + private generateXsd( + element: any, + type: 'xsd' | 'json' = 'xsd', + folder: string, + path = '', + key = '' + ): any { + XMLUtils.removeAnnotations(element); + + const name = XMLUtils.getElementName(element); + const schemaBase = XMLUtils.createSchemaBase(); + + const newElement = { + 'xs:schema': { + ...schemaBase, + 'xs:element': element, + }, + }; + + return { + name, + folder, + path: path || name, + key, + xsd: type === 'xsd' ? XMLUtils.toXsd(newElement) : newElement, + }; + } +} diff --git a/packages/cfdi/schema/src/common/base-processor.ts b/packages/cfdi/schema/src/common/base-processor.ts new file mode 100644 index 00000000..58d96ab6 --- /dev/null +++ b/packages/cfdi/schema/src/common/base-processor.ts @@ -0,0 +1,66 @@ +import { ElementCompact } from 'xml-js'; +import { XSDLoader, LoaderOptions } from '../loader.xsd'; +import { XSD_CONSTANTS } from './constants'; +import { ProcessorConfig, IXSDProcessor } from './interfaces'; + +/** + * Clase base abstracta que centraliza la lógica común de procesadores XSD + * Elimina duplicación entre CfdiProcess y CatalogProcess + */ +export abstract class BaseXSDProcessor implements IXSDProcessor { + protected xsdLoader: XSDLoader; + protected source: string = ''; + + constructor() { + this.xsdLoader = XSDLoader.getInstance(); + } + + /** + * Configuración estandarizada con compatibilidad hacia atrás + */ + setConfig(options: ProcessorConfig): void { + // Mantener compatibilidad hacia atrás con 'path' + const source = options.source || options.path; + if (source) { + this.source = source; + } + } + + /** + * Lectura estandarizada de XSD con validación + */ + async readXsd(): Promise { + if (!this.source) { + throw new Error('No se ha configurado una fuente XSD. Use setConfig() primero.'); + } + + const loaderOptions: LoaderOptions = { + source: this.source, + encoding: XSD_CONSTANTS.DEFAULT_ENCODING, + timeout: XSD_CONSTANTS.DEFAULT_TIMEOUT, + }; + + return await this.xsdLoader.loadXSD(loaderOptions); + } + + /** + * Validación de configuración + */ + protected validateConfig(): void { + if (!this.source) { + throw new Error('Configuración inválida: se requiere source o path'); + } + } + + /** + * Método abstracto que cada procesador debe implementar + */ + abstract process(): Promise; + + /** + * Método opcional para limpieza de recursos + */ + dispose(): void { + // Implementación base - los procesadores pueden sobrescribir + } +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/common/const/structure.ts b/packages/cfdi/schema/src/common/const/structure.ts new file mode 100644 index 00000000..05a53029 --- /dev/null +++ b/packages/cfdi/schema/src/common/const/structure.ts @@ -0,0 +1,14 @@ +export const STRUCTURE: Record = { + tipoDatos: 'catalogos', + catalogos: 'catalogos', + InformacionGlobal: 'comprobante', + CfdiRelacionados: 'comprobante', + Emisor: 'comprobante', + Receptor: 'comprobante', + Impuestos: 'comprobante', + Complemento: 'comprobante', + Addenda: 'comprobante', + Comprobante: 'comprobante', + Conceptos: 'comprobante', + ine: 'complementos', +}; diff --git a/packages/cfdi/schema/src/common/constants.ts b/packages/cfdi/schema/src/common/constants.ts new file mode 100644 index 00000000..90039fdb --- /dev/null +++ b/packages/cfdi/schema/src/common/constants.ts @@ -0,0 +1,48 @@ +/** + * Constantes centralizadas para el procesamiento de XSD + */ + +export const XSD_CONSTANTS = { + // Configuración de timeout y encoding por defecto + DEFAULT_TIMEOUT: 15000, + DEFAULT_ENCODING: 'utf-8' as BufferEncoding, + + // Espacios de nombres XML comunes + NAMESPACES: { + CFDI: 'http://www.sat.gob.mx/cfd/4', + XS: 'http://www.w3.org/2001/XMLSchema', + CAT_CFDI: 'http://www.sat.gob.mx/sitio_internet/cfd/catalogos', + TD_CFDI: 'http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI', + }, + + // Ubicaciones de esquemas externos + SCHEMA_LOCATIONS: { + CAT_CFDI: 'http://www.sat.gob.mx/sitio_internet/cfd/catalogos/catCFDI.xsd', + TD_CFDI: 'http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI/tdCFDI.xsd', + }, + + // Opciones de procesamiento XML estándar + XML_OPTIONS: { + compact: true, + ignoreComment: true, + alwaysChildren: true, + }, + + // Configuración de salida XML + OUTPUT_OPTIONS: { + compact: true, + ignoreComment: true, + spaces: 4, + }, + + // Propiedades de catálogo a eliminar por defecto + CATALOG_REMOVE_PROPERTIES: [ + 'c_CodigoPostal', + 'c_ClaveProdServ', + 'c_ClaveUnidad', + 'c_Colonia', + ], +} as const; + +export type XSDNamespaces = typeof XSD_CONSTANTS.NAMESPACES; +export type SchemaLocations = typeof XSD_CONSTANTS.SCHEMA_LOCATIONS; \ No newline at end of file diff --git a/packages/cfdi/schema/src/common/interfaces.ts b/packages/cfdi/schema/src/common/interfaces.ts new file mode 100644 index 00000000..a25c1c75 --- /dev/null +++ b/packages/cfdi/schema/src/common/interfaces.ts @@ -0,0 +1,64 @@ +import { ElementCompact } from 'xml-js'; +import { LoaderOptions } from '../loader.xsd'; + +/** + * Configuración base para procesadores XSD + */ +export interface ProcessorConfig { + source?: string; + path?: string; // Mantener compatibilidad hacia atrás + encoding?: BufferEncoding; + timeout?: number; +} + +/** + * Opciones de procesamiento extendidas + */ +export interface ProcessingOptions extends LoaderOptions { + validateSchema?: boolean; + removeAnnotations?: boolean; +} + +/** + * Resultado estándar de procesamiento + */ +export interface ProcessingResult { + name: string; + path?: string; + key?: string; + folder?: string; + xsd: string | ElementCompact; +} + +/** + * Configuración de generación XSD + */ +export interface XSDGenerationConfig { + type: 'xsd' | 'json'; + folder?: string; + path?: string; + key?: string; +} + +/** + * Interface base para procesadores + */ +export interface IXSDProcessor { + setConfig(options: ProcessorConfig): void; + process(): Promise; + readXsd(): Promise; +} + +/** + * Opciones para creación de elementos XML + */ +export interface XMLElementOptions { + namespaces?: Record; + imports?: Array<{ + namespace: string; + schemaLocation: string; + }>; + targetNamespace?: string; + elementFormDefault?: string; + attributeFormDefault?: string; +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/common/processor-factory.ts b/packages/cfdi/schema/src/common/processor-factory.ts new file mode 100644 index 00000000..a002267f --- /dev/null +++ b/packages/cfdi/schema/src/common/processor-factory.ts @@ -0,0 +1,68 @@ +import { CfdiXsd } from '../cfdi.xsd'; +import { CatalogProcess } from '../catalogos.xsd'; +import { ProcessorConfig } from './interfaces'; + +/** + * Factory para crear procesadores XSD de manera centralizada + * Simplifica el uso y centraliza la lógica de creación + */ +export class ProcessorFactory { + /** + * Crea un procesador CFDI configurado + */ + static createCfdiProcessor(config?: ProcessorConfig): CfdiXsd { + const processor = CfdiXsd.of(); + if (config) { + processor.setConfig(config); + } + return processor; + } + + /** + * Crea un procesador de catálogos configurado + */ + static createCatalogProcessor(config?: ProcessorConfig): CatalogProcess { + const processor = CatalogProcess.of(); + if (config) { + processor.setConfig(config); + } + return processor; + } + + /** + * Crea un procesador basado en el tipo especificado + */ + static createProcessor( + type: 'cfdi' | 'catalog', + config?: ProcessorConfig + ): CfdiXsd | CatalogProcess { + switch (type) { + case 'cfdi': + return this.createCfdiProcessor(config); + case 'catalog': + return this.createCatalogProcessor(config); + default: + throw new Error(`Tipo de procesador no soportado: ${type}`); + } + } + + /** + * Procesa un XSD desde una fuente específica + */ + static async processXSD( + type: 'cfdi' | 'catalog', + source: string, + options?: Omit + ): Promise { + const config: ProcessorConfig = { source, ...options }; + const processor = this.createProcessor(type, config); + return await processor.process(); + } +} + +/** + * Funciones de conveniencia para uso directo + */ +export const createCfdiProcessor = ProcessorFactory.createCfdiProcessor; +export const createCatalogProcessor = ProcessorFactory.createCatalogProcessor; +export const processXSD = ProcessorFactory.processXSD; \ No newline at end of file diff --git a/packages/cfdi/schema/src/common/xml-utils.ts b/packages/cfdi/schema/src/common/xml-utils.ts new file mode 100644 index 00000000..206e95c6 --- /dev/null +++ b/packages/cfdi/schema/src/common/xml-utils.ts @@ -0,0 +1,98 @@ +import { ElementCompact, js2xml } from 'xml-js'; +import { XSD_CONSTANTS } from './constants'; +import { XMLElementOptions } from './interfaces'; + +/** + * Utilidades XML centralizadas para evitar duplicación + */ +export class XMLUtils { + /** + * Convierte elemento a XSD con configuración estándar + */ + static toXsd(element: ElementCompact): string { + return js2xml(element, XSD_CONSTANTS.OUTPUT_OPTIONS); + } + + /** + * Genera estructura base de esquema XSD con namespaces estándar + */ + static createSchemaBase(options: XMLElementOptions = {}): any { + const defaultNamespaces = { + 'xmlns:cfdi': XSD_CONSTANTS.NAMESPACES.CFDI, + 'xmlns:xs': XSD_CONSTANTS.NAMESPACES.XS, + 'xmlns:catCFDI': XSD_CONSTANTS.NAMESPACES.CAT_CFDI, + 'xmlns:tdCFDI': XSD_CONSTANTS.NAMESPACES.TD_CFDI, + }; + + const defaultImports = [ + { + _attributes: { + namespace: XSD_CONSTANTS.NAMESPACES.CAT_CFDI, + schemaLocation: XSD_CONSTANTS.SCHEMA_LOCATIONS.CAT_CFDI, + }, + }, + { + _attributes: { + namespace: XSD_CONSTANTS.NAMESPACES.TD_CFDI, + schemaLocation: XSD_CONSTANTS.SCHEMA_LOCATIONS.TD_CFDI, + }, + }, + ]; + + return { + _attributes: { + ...defaultNamespaces, + ...options.namespaces, + targetNamespace: options.targetNamespace || XSD_CONSTANTS.NAMESPACES.CFDI, + elementFormDefault: options.elementFormDefault || 'qualified', + attributeFormDefault: options.attributeFormDefault || 'unqualified', + }, + 'xs:import': options.imports || defaultImports, + }; + } + + /** + * Limpia anotaciones de un elemento + */ + static removeAnnotations(element: any): void { + delete element?.['xs:annotation']; + } + + /** + * Obtiene el nombre de un elemento con fallback + */ + static getElementName(element: any, fallback: string = 'unknown'): string { + return element?._attributes?.name || fallback; + } + + /** + * Verifica si un elemento tiene solo atributos (sin secuencia) + */ + static isOnlyAttribute(element: any): boolean { + return ( + !!element?.['xs:complexType']['xs:attribute'] && + !element['xs:complexType']['xs:sequence'] + ); + } + + /** + * Convierte array de esquemas a objeto indexado por nombre + */ + static generateSchemasMap(schemas: any[]): Record { + const schemasMap: Record = {}; + schemas.forEach((schema) => { + schemasMap[schema.name] = schema.xsd; + }); + return schemasMap; + } + + /** + * Aplica transformación estándar de salida a lista de esquemas + */ + static transformSchemasToXsd(schemas: any[]): any[] { + return schemas.map((x: any) => ({ + ...x, + xsd: XMLUtils.toXsd(x.xsd) + })); + } +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/complementos/complementos.process.ts b/packages/cfdi/schema/src/complementos/complementos.process.ts new file mode 100644 index 00000000..f83ecfbc --- /dev/null +++ b/packages/cfdi/schema/src/complementos/complementos.process.ts @@ -0,0 +1,53 @@ +import { readFileSync } from 'fs'; +import { js2xml } from 'xml-js'; +import { Iedu } from './iedu.process'; +interface ComplementoData { + name: string; + path: string; +} +export class Complementos { + complementos: ComplementoData[] = []; + private static instance: Complementos; + + public static of(): Complementos { + if (!Complementos.instance) { + Complementos.instance = new Complementos(); + } + return Complementos.instance; + } + + setConfig(options: any) { + const { path } = options; + path && (this.complementos = path); + } + + async process() { + return this.getComplementos(); + } + + getComplementos() { + const xsd = this.complementos.map(async (c) => { + return { + name: c.name, + key: c.name, + folder: 'complementos', + type: 'complementos', + xsd: await this.createComplemento(c), + }; + }); + + return Promise.all(xsd); + } + + createComplemento(data: ComplementoData) { + switch (data.name) { + case 'iedu': + return Iedu.of().setConfig(data.path).process(); + case 'pago': + //return new PagoComplemento(data); + // Agrega más casos según sea necesario para otros tipos de complementos + default: + throw new Error(`Tipo de complemento desconocido: ${data.name}`); + } + } +} diff --git a/packages/cfdi/schema/src/complementos/iedu.process.ts b/packages/cfdi/schema/src/complementos/iedu.process.ts new file mode 100644 index 00000000..6d347ef8 --- /dev/null +++ b/packages/cfdi/schema/src/complementos/iedu.process.ts @@ -0,0 +1,28 @@ +import { readFileSync } from 'fs'; +import { Process } from './process'; +import { ElementCompact } from 'xml-js'; + +export class Iedu extends Process { + private static instance: Iedu; + + constructor() { + super(); + } + public static of(): Iedu { + if (!Iedu.instance) { + // ¡Usa la clase concreta aquí! + Iedu.instance = new Iedu(); + } + return Iedu.instance; + } + process() { + const xsd = this.read(); + return xsd; + } + + xsd(content: ElementCompact) { + console.log(content); + + return content; + } +} diff --git a/packages/cfdi/schema/src/complementos/process.ts b/packages/cfdi/schema/src/complementos/process.ts new file mode 100644 index 00000000..5e5ef700 --- /dev/null +++ b/packages/cfdi/schema/src/complementos/process.ts @@ -0,0 +1,28 @@ +import { readFileSync } from 'fs'; +import { ElementCompact, js2xml, xml2js } from 'xml-js'; + +export abstract class Process { + xsdPath: string = ''; + async read() { + const xsdContent = readFileSync(this.xsdPath, 'utf-8'); + const options = { + compact: true, + ignoreComment: true, + alwaysChildren: true, + }; + const xsd = xml2js(xsdContent, options) as ElementCompact; + const xsdCompact = await this.xsd(xsd); + return js2xml(xsdCompact, { + compact: true, + ignoreComment: true, + spaces: 4, + }); + } + + setConfig(path: string): this { + this.xsdPath = path; + return this; + } + + protected abstract xsd(xsd: ElementCompact): any; +} diff --git a/packages/cfdi/schema/src/files/catCFDI.xsd b/packages/cfdi/schema/src/files/catCFDI.xsd new file mode 100644 index 00000000..a5314545 --- /dev/null +++ b/packages/cfdi/schema/src/files/catCFDI.xsd @@ -0,0 +1,162337 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/cfdi/schema/src/files/cfdv40.xsd b/packages/cfdi/schema/src/files/cfdv40.xsd new file mode 100644 index 00000000..9d513084 --- /dev/null +++ b/packages/cfdi/schema/src/files/cfdv40.xsd @@ -0,0 +1,850 @@ + + + + + + + Estándar de Comprobante Fiscal Digital por Internet. + + + + + + Nodo condicional para precisar la información relacionada con el comprobante global. + + + + + Atributo requerido para expresar el período al que corresponde la información del comprobante global. + + + + + Atributo requerido para expresar el mes o los meses al que corresponde la información del comprobante global. + + + + + Atributo requerido para expresar el año al que corresponde la información del comprobante global. + + + + + + + + + + + + + Nodo opcional para precisar la información de los comprobantes relacionados. + + + + + + Nodo requerido para precisar la información de los comprobantes relacionados. + + + + + Atributo requerido para registrar el folio fiscal (UUID) de un CFDI relacionado con el presente comprobante, por ejemplo: Si el CFDI relacionado es un comprobante de traslado que sirve para registrar el movimiento de la mercancía. Si este comprobante se usa como nota de crédito o nota de débito del comprobante relacionado. Si este comprobante es una devolución sobre el comprobante relacionado. Si éste sustituye a una factura cancelada. + + + + + + + + + + + + + + + Atributo requerido para indicar la clave de la relación que existe entre éste que se está generando y el o los CFDI previos. + + + + + + + Nodo requerido para expresar la información del contribuyente emisor del comprobante. + + + + + Atributo requerido para registrar la Clave del Registro Federal de Contribuyentes correspondiente al contribuyente emisor del comprobante. + + + + + Atributo requerido para registrar el nombre, denominación o razón social del contribuyente inscrito en el RFC, del emisor del comprobante. + + + + + + + + + + + + + Atributo requerido para incorporar la clave del régimen del contribuyente emisor al que aplicará el efecto fiscal de este comprobante. + + + + + Atributo condicional para expresar el número de operación proporcionado por el SAT cuando se trate de un comprobante a través de un PCECFDI o un PCGCFDISP. + + + + + + + + + + + + + + Nodo requerido para precisar la información del contribuyente receptor del comprobante. + + + + + Atributo requerido para registrar la Clave del Registro Federal de Contribuyentes correspondiente al contribuyente receptor del comprobante. + + + + + Atributo requerido para registrar el nombre(s), primer apellido, segundo apellido, según corresponda, denominación o razón social del contribuyente, inscrito en el RFC, del receptor del comprobante. + + + + + + + + + + + + + Atributo requerido para registrar el código postal del domicilio fiscal del receptor del comprobante. + + + + + + + + + + + + Atributo condicional para registrar la clave del país de residencia para efectos fiscales del receptor del comprobante, cuando se trate de un extranjero, y que es conforme con la especificación ISO 3166-1 alpha-3. Es requerido cuando se incluya el complemento de comercio exterior o se registre el atributo NumRegIdTrib. + + + + + Atributo condicional para expresar el número de registro de identidad fiscal del receptor cuando sea residente en el extranjero. Es requerido cuando se incluya el complemento de comercio exterior. + + + + + + + + + + + + Atributo requerido para incorporar la clave del régimen fiscal del contribuyente receptor al que aplicará el efecto fiscal de este comprobante. + + + + + Atributo requerido para expresar la clave del uso que dará a esta factura el receptor del CFDI. + + + + + + + Nodo requerido para listar los conceptos cubiertos por el comprobante. + + + + + + Nodo requerido para registrar la información detallada de un bien o servicio amparado en el comprobante. + + + + + + Nodo condicional para capturar los impuestos aplicables al presente concepto. + + + + + + Nodo opcional para asentar los impuestos trasladados aplicables al presente concepto. + + + + + + Nodo requerido para asentar la información detallada de un traslado de impuestos aplicable al presente concepto. + + + + + Atributo requerido para señalar la base para el cálculo del impuesto, la determinación de la base se realiza de acuerdo con las disposiciones fiscales vigentes. No se permiten valores negativos. + + + + + + + + + + + + Atributo requerido para señalar la clave del tipo de impuesto trasladado aplicable al concepto. + + + + + Atributo requerido para señalar la clave del tipo de factor que se aplica a la base del impuesto. + + + + + Atributo condicional para señalar el valor de la tasa o cuota del impuesto que se traslada para el presente concepto. Es requerido cuando el atributo TipoFactor tenga una clave que corresponda a Tasa o Cuota. + + + + + + + + + + + + Atributo condicional para señalar el importe del impuesto trasladado que aplica al concepto. No se permiten valores negativos. Es requerido cuando TipoFactor sea Tasa o Cuota. + + + + + + + + + + Nodo opcional para asentar los impuestos retenidos aplicables al presente concepto. + + + + + + Nodo requerido para asentar la información detallada de una retención de impuestos aplicable al presente concepto. + + + + + Atributo requerido para señalar la base para el cálculo de la retención, la determinación de la base se realiza de acuerdo con las disposiciones fiscales vigentes. No se permiten valores negativos. + + + + + + + + + + + + Atributo requerido para señalar la clave del tipo de impuesto retenido aplicable al concepto. + + + + + Atributo requerido para señalar la clave del tipo de factor que se aplica a la base del impuesto. + + + + + Atributo requerido para señalar la tasa o cuota del impuesto que se retiene para el presente concepto. + + + + + + + + + + + + Atributo requerido para señalar el importe del impuesto retenido que aplica al concepto. No se permiten valores negativos. + + + + + + + + + + + + + Nodo opcional para registrar información del contribuyente Tercero, a cuenta del que se realiza la operación. + + + + + Atributo requerido para registrar la Clave del Registro Federal de Contribuyentes del contribuyente Tercero, a cuenta del que se realiza la operación. + + + + + Atributo requerido para registrar el nombre, denominación o razón social del contribuyente Tercero correspondiente con el Rfc, a cuenta del que se realiza la operación. + + + + + + + + + + + + + Atributo requerido para incorporar la clave del régimen del contribuyente Tercero, a cuenta del que se realiza la operación. + + + + + Atributo requerido para incorporar el código postal del domicilio fiscal del Tercero, a cuenta del que se realiza la operación. + + + + + + + + + + + + + + Nodo opcional para introducir la información aduanera aplicable cuando se trate de ventas de primera mano de mercancías importadas o se trate de operaciones de comercio exterior con bienes o servicios. + + + + + Atributo requerido para expresar el número del pedimento que ampara la importación del bien que se expresa en el siguiente formato: últimos 2 dígitos del año de validación seguidos por dos espacios, 2 dígitos de la aduana de despacho seguidos por dos espacios, 4 dígitos del número de la patente seguidos por dos espacios, 1 dígito que corresponde al último dígito del año en curso, salvo que se trate de un pedimento consolidado iniciado en el año inmediato anterior o del pedimento original de una rectificación, seguido de 6 dígitos de la numeración progresiva por aduana. + + + + + + + + + + + + + Nodo opcional para asentar el número de cuenta predial con el que fue registrado el inmueble, en el sistema catastral de la entidad federativa de que trate, o bien para incorporar los datos de identificación del certificado de participación inmobiliaria no amortizable. + + + + + Atributo requerido para precisar el número de la cuenta predial del inmueble cubierto por el presente concepto, o bien para incorporar los datos de identificación del certificado de participación inmobiliaria no amortizable, tratándose de arrendamiento. + + + + + + + + + + + + + + + Nodo opcional donde se incluyen los nodos complementarios de extensión al concepto definidos por el SAT, de acuerdo con las disposiciones particulares para un sector o actividad específica. + + + + + + + + + + Nodo opcional para expresar las partes o componentes que integran la totalidad del concepto expresado en el comprobante fiscal digital por Internet. + + + + + + Nodo opcional para introducir la información aduanera aplicable cuando se trate de ventas de primera mano de mercancías importadas o se trate de operaciones de comercio exterior con bienes o servicios. + + + + + Atributo requerido para expresar el número del pedimento que ampara la importación del bien que se expresa en el siguiente formato: últimos 2 dígitos del año de validación seguidos por dos espacios, 2 dígitos de la aduana de despacho seguidos por dos espacios, 4 dígitos del número de la patente seguidos por dos espacios, 1 dígito que corresponde al último dígito del año en curso, salvo que se trate de un pedimento consolidado iniciado en el año inmediato anterior o del pedimento original de una rectificación, seguido de 6 dígitos de la numeración progresiva por aduana. + + + + + + + + + + + + + + Atributo requerido para expresar la clave del producto o del servicio amparado por la presente parte. Es requerido y deben utilizar las claves del catálogo de productos y servicios, cuando los conceptos que registren por sus actividades correspondan con dichos conceptos. + + + + + Atributo opcional para expresar el número de serie, número de parte del bien o identificador del producto o del servicio amparado por la presente parte. Opcionalmente se puede utilizar claves del estándar GTIN. + + + + + + + + + + + + + Atributo requerido para precisar la cantidad de bienes o servicios del tipo particular definido por la presente parte. + + + + + + + + + + + + Atributo opcional para precisar la unidad de medida propia de la operación del emisor, aplicable para la cantidad expresada en la parte. La unidad debe corresponder con la descripción de la parte. + + + + + + + + + + + + + Atributo requerido para precisar la descripción del bien o servicio cubierto por la presente parte. + + + + + + + + + + + + + Atributo opcional para precisar el valor o precio unitario del bien o servicio cubierto por la presente parte. No se permiten valores negativos. + + + + + Atributo opcional para precisar el importe total de los bienes o servicios de la presente parte. Debe ser equivalente al resultado de multiplicar la cantidad por el valor unitario expresado en la parte. No se permiten valores negativos. + + + + + + + + Atributo requerido para expresar la clave del producto o del servicio amparado por el presente concepto. Es requerido y deben utilizar las claves del catálogo de productos y servicios, cuando los conceptos que registren por sus actividades correspondan con dichos conceptos. + + + + + Atributo opcional para expresar el número de parte, identificador del producto o del servicio, la clave de producto o servicio, SKU o equivalente, propia de la operación del emisor, amparado por el presente concepto. Opcionalmente se puede utilizar claves del estándar GTIN. + + + + + + + + + + + + + Atributo requerido para precisar la cantidad de bienes o servicios del tipo particular definido por el presente concepto. + + + + + + + + + + + + Atributo requerido para precisar la clave de unidad de medida estandarizada aplicable para la cantidad expresada en el concepto. La unidad debe corresponder con la descripción del concepto. + + + + + Atributo opcional para precisar la unidad de medida propia de la operación del emisor, aplicable para la cantidad expresada en el concepto. La unidad debe corresponder con la descripción del concepto. + + + + + + + + + + + + + Atributo requerido para precisar la descripción del bien o servicio cubierto por el presente concepto. + + + + + + + + + + + + + Atributo requerido para precisar el valor o precio unitario del bien o servicio cubierto por el presente concepto. + + + + + Atributo requerido para precisar el importe total de los bienes o servicios del presente concepto. Debe ser equivalente al resultado de multiplicar la cantidad por el valor unitario expresado en el concepto. No se permiten valores negativos. + + + + + Atributo opcional para representar el importe de los descuentos aplicables al concepto. No se permiten valores negativos. + + + + + Atributo requerido para expresar si la operación comercial es objeto o no de impuesto. + + + + + + + + + + Nodo condicional para expresar el resumen de los impuestos aplicables. + + + + + + Nodo condicional para capturar los impuestos retenidos aplicables. Es requerido cuando en los conceptos se registre algún impuesto retenido. + + + + + + Nodo requerido para la información detallada de una retención de impuesto específico. + + + + + Atributo requerido para señalar la clave del tipo de impuesto retenido. + + + + + Atributo requerido para señalar el monto del impuesto retenido. No se permiten valores negativos. + + + + + + + + + + Nodo condicional para capturar los impuestos trasladados aplicables. Es requerido cuando en los conceptos se registre un impuesto trasladado. + + + + + + Nodo requerido para la información detallada de un traslado de impuesto específico. + + + + + Atributo requerido para señalar la suma de los atributos Base de los conceptos del impuesto trasladado. No se permiten valores negativos. + + + + + Atributo requerido para señalar la clave del tipo de impuesto trasladado. + + + + + Atributo requerido para señalar la clave del tipo de factor que se aplica a la base del impuesto. + + + + + Atributo condicional para señalar el valor de la tasa o cuota del impuesto que se traslada por los conceptos amparados en el comprobante. + + + + + + + + + + + + Atributo condicional para señalar la suma del importe del impuesto trasladado, agrupado por impuesto, TipoFactor y TasaOCuota. No se permiten valores negativos. + + + + + + + + + + + Atributo condicional para expresar el total de los impuestos retenidos que se desprenden de los conceptos expresados en el comprobante fiscal digital por Internet. No se permiten valores negativos. Es requerido cuando en los conceptos se registren impuestos retenidos. + + + + + Atributo condicional para expresar el total de los impuestos trasladados que se desprenden de los conceptos expresados en el comprobante fiscal digital por Internet. No se permiten valores negativos. Es requerido cuando en los conceptos se registren impuestos trasladados. + + + + + + + Nodo opcional donde se incluye el complemento Timbre Fiscal Digital de manera obligatoria y los nodos complementarios determinados por el SAT, de acuerdo con las disposiciones particulares para un sector o actividad específica. + + + + + + + + + + Nodo opcional para recibir las extensiones al presente formato que sean de utilidad al contribuyente. Para las reglas de uso del mismo, referirse al formato origen. + + + + + + + + + + + Atributo requerido con valor prefijado a 4.0 que indica la versión del estándar bajo el que se encuentra expresado el comprobante. + + + + + + + + + + Atributo opcional para precisar la serie para control interno del contribuyente. Este atributo acepta una cadena de caracteres. + + + + + + + + + + + + + Atributo opcional para control interno del contribuyente que expresa el folio del comprobante, acepta una cadena de caracteres. + + + + + + + + + + + + + Atributo requerido para la expresión de la fecha y hora de expedición del Comprobante Fiscal Digital por Internet. Se expresa en la forma AAAA-MM-DDThh:mm:ss y debe corresponder con la hora local donde se expide el comprobante. + + + + + Atributo requerido para contener el sello digital del comprobante fiscal, al que hacen referencia las reglas de resolución miscelánea vigente. El sello debe ser expresado como una cadena de texto en formato Base 64. + + + + + + + + + + Atributo condicional para expresar la clave de la forma de pago de los bienes o servicios amparados por el comprobante. + + + + + Atributo requerido para expresar el número de serie del certificado de sello digital que ampara al comprobante, de acuerdo con el acuse correspondiente a 20 posiciones otorgado por el sistema del SAT. + + + + + + + + + + + + Atributo requerido que sirve para incorporar el certificado de sello digital que ampara al comprobante, como texto en formato base 64. + + + + + + + + + + Atributo condicional para expresar las condiciones comerciales aplicables para el pago del comprobante fiscal digital por Internet. Este atributo puede ser condicionado mediante atributos o complementos. + + + + + + + + + + + + + Atributo requerido para representar la suma de los importes de los conceptos antes de descuentos e impuesto. No se permiten valores negativos. + + + + + Atributo condicional para representar el importe total de los descuentos aplicables antes de impuestos. No se permiten valores negativos. Se debe registrar cuando existan conceptos con descuento. + + + + + Atributo requerido para identificar la clave de la moneda utilizada para expresar los montos, cuando se usa moneda nacional se registra MXN. Conforme con la especificación ISO 4217. + + + + + Atributo condicional para representar el tipo de cambio FIX conforme con la moneda usada. Es requerido cuando la clave de moneda es distinta de MXN y de XXX. El valor debe reflejar el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo moneda. Si el valor está fuera del porcentaje aplicable a la moneda tomado del catálogo c_Moneda, el emisor debe obtener del PAC que vaya a timbrar el CFDI, de manera no automática, una clave de confirmación para ratificar que el valor es correcto e integrar dicha clave en el atributo Confirmacion. + + + + + + + + + + + + Atributo requerido para representar la suma del subtotal, menos los descuentos aplicables, más las contribuciones recibidas (impuestos trasladados - federales y/o locales, derechos, productos, aprovechamientos, aportaciones de seguridad social, contribuciones de mejoras) menos los impuestos retenidos federales y/o locales. Si el valor es superior al límite que establezca el SAT en la Resolución Miscelánea Fiscal vigente, el emisor debe obtener del PAC que vaya a timbrar el CFDI, de manera no automática, una clave de confirmación para ratificar que el valor es correcto e integrar dicha clave en el atributo Confirmacion. No se permiten valores negativos. + + + + + Atributo requerido para expresar la clave del efecto del comprobante fiscal para el contribuyente emisor. + + + + + Atributo requerido para expresar si el comprobante ampara una operación de exportación. + + + + + Atributo condicional para precisar la clave del método de pago que aplica para este comprobante fiscal digital por Internet, conforme al Artículo 29-A fracción VII incisos a y b del CFF. + + + + + Atributo requerido para incorporar el código postal del lugar de expedición del comprobante (domicilio de la matriz o de la sucursal). + + + + + Atributo condicional para registrar la clave de confirmación que entregue el PAC para expedir el comprobante con importes grandes, con un tipo de cambio fuera del rango establecido o con ambos casos. Es requerido cuando se registra un tipo de cambio o un total fuera del rango establecido. + + + + + + + + + + + + diff --git a/packages/cfdi/schema/src/files/complementos/iedu.xsd b/packages/cfdi/schema/src/files/complementos/iedu.xsd new file mode 100644 index 00000000..32bdf249 --- /dev/null +++ b/packages/cfdi/schema/src/files/complementos/iedu.xsd @@ -0,0 +1,69 @@ + + + + + + Atributo requerido con valor prefijado a 1.0 que indica la versión del estándar bajo el que se encuentra expresado el complemento concepto al comprobante. + + + + + + + + + + Atributo requerido para indicar el nombre del Alumno + + + + + + + + + + + + + + + + + Atributo requerido para indicar el nivel educativo que cursa el alumno + + + + + + + + + + + + + + Atributo requerido para especificar la clave del centro de trabajo o el reconocimiento de validez oficial de estudios en los términos de la Ley General de Educación que tenga la institución educativa privada donde se realiza el pago. + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/cfdi/schema/src/files/complementos/iedu.xslt b/packages/cfdi/schema/src/files/complementos/iedu.xslt new file mode 100644 index 00000000..63ee02f9 --- /dev/null +++ b/packages/cfdi/schema/src/files/complementos/iedu.xslt @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/cfdi/schema/src/files/complementos/iedu2.xsd b/packages/cfdi/schema/src/files/complementos/iedu2.xsd new file mode 100644 index 00000000..16f867de --- /dev/null +++ b/packages/cfdi/schema/src/files/complementos/iedu2.xsd @@ -0,0 +1,84 @@ + + + + + Complemento concepto para la expedición de comprobantes fiscales por parte de Instituciones Educativas Privadas, para los efectos del artículo primero y cuarto del decreto por el que se otorga un estímulo fiscal a las personas físicas en relación con los pagos por servicios educativos + + + + + Atributo requerido con valor prefijado a 1.0 que indica la versión del estándar bajo el que se encuentra expresado el complemento concepto al comprobante. + + + + + + + + + + Atributo requerido para indicar el nombre del Alumno + + + + + + + + Atributo requerido para indicar la CURP del alumno de la institución educativa + + + + + Atributo requerido para indicar el nivel educativo que cursa el alumno + + + + + + + + + + + + + + Atributo requerido para especificar la clave del centro de trabajo o el reconocimiento de validez oficial de estudios en los términos de la Ley General de Educación que tenga la institución educativa privada donde se realiza el pago. + + + + + + + + + + + Atributo opcional para indicar el RFC de quien realiza el pago cuando sea diferente a quien recibe el servicio + + + + + + + Tipo definido para la expresión de RFC's de contribuyentes. Cabe hacer la mención que debido a las reglas definidas por el estándar XML en el caso de que un RFC dado incluya un caracter ampersand, dicho caracter deberá ser expresado mediante la secuencia de escape especificado como parte del estándar. En la definición del tipo se expresa una longitud mínima y máxima, sin embargo la longitud puede ser redefinida como una extensión según se determina el uso particular + + + + + + + + + + + Tipo definido para la expresión de una CURP. + + + + + + + + diff --git a/packages/cfdi/schema/src/files/schema/catalogos/catalogos.json b/packages/cfdi/schema/src/files/schema/catalogos/catalogos.json new file mode 100644 index 00000000..9af11b8d --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/catalogos/catalogos.json @@ -0,0 +1,1566 @@ +{ + "$id": "catalogos.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from catalogos on Tue Dec 26 2023 19:00:38 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Schema tag attributes: xmlns:catCFDI='http://www.sat.gob.mx/sitio_internet/cfd/catalogos' xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='http://www.sat.gob.mx/sitio_internet/cfd/catalogos' elementFormDefault='unqualified' attributeFormDefault='unqualified'", + "properties": { + "c_FormaPago": { + "$ref": "#/definitions/c_FormaPago" + }, + "c_Moneda": { + "$ref": "#/definitions/c_Moneda" + }, + "c_TipoDeComprobante": { + "$ref": "#/definitions/c_TipoDeComprobante" + }, + "c_Exportacion": { + "$ref": "#/definitions/c_Exportacion" + }, + "c_MetodoPago": { + "$ref": "#/definitions/c_MetodoPago" + }, + "c_CodigoPostal": { + "$ref": "#/definitions/c_CodigoPostal" + }, + "c_Periodicidad": { + "$ref": "#/definitions/c_Periodicidad" + }, + "c_Meses": { + "$ref": "#/definitions/c_Meses" + }, + "c_TipoRelacion": { + "$ref": "#/definitions/c_TipoRelacion" + }, + "c_RegimenFiscal": { + "$ref": "#/definitions/c_RegimenFiscal" + }, + "c_Pais": { + "$ref": "#/definitions/c_Pais" + }, + "c_UsoCFDI": { + "$ref": "#/definitions/c_UsoCFDI" + }, + "c_ClaveProdServ": { + "$ref": "#/definitions/c_ClaveProdServ" + }, + "c_ClaveUnidad": { + "$ref": "#/definitions/c_ClaveUnidad" + }, + "c_ObjetoImp": { + "$ref": "#/definitions/c_ObjetoImp" + }, + "c_Impuesto": { + "$ref": "#/definitions/c_Impuesto" + }, + "c_TipoFactor": { + "$ref": "#/definitions/c_TipoFactor" + }, + "c_Estado": { + "$ref": "#/definitions/c_Estado" + }, + "c_Colonia": { + "$ref": "#/definitions/c_Colonia" + }, + "c_Localidad": { + "$ref": "#/definitions/c_Localidad" + }, + "c_Municipio": { + "$ref": "#/definitions/c_Municipio" + } + }, + "type": "object", + "anyOf": [ + { + "required": [ + "c_FormaPago" + ] + }, + { + "required": [ + "c_Moneda" + ] + }, + { + "required": [ + "c_TipoDeComprobante" + ] + }, + { + "required": [ + "c_Exportacion" + ] + }, + { + "required": [ + "c_MetodoPago" + ] + }, + { + "required": [ + "c_CodigoPostal" + ] + }, + { + "required": [ + "c_Periodicidad" + ] + }, + { + "required": [ + "c_Meses" + ] + }, + { + "required": [ + "c_TipoRelacion" + ] + }, + { + "required": [ + "c_RegimenFiscal" + ] + }, + { + "required": [ + "c_Pais" + ] + }, + { + "required": [ + "c_UsoCFDI" + ] + }, + { + "required": [ + "c_ClaveProdServ" + ] + }, + { + "required": [ + "c_ClaveUnidad" + ] + }, + { + "required": [ + "c_ObjetoImp" + ] + }, + { + "required": [ + "c_Impuesto" + ] + }, + { + "required": [ + "c_TipoFactor" + ] + }, + { + "required": [ + "c_Estado" + ] + }, + { + "required": [ + "c_Colonia" + ] + }, + { + "required": [ + "c_Localidad" + ] + }, + { + "required": [ + "c_Municipio" + ] + } + ], + "definitions": { + "c_FormaPago": { + "enum": [ + "01", + "02", + "03", + "04", + "05", + "06", + "08", + "12", + "13", + "14", + "15", + "17", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", + "99" + ], + "type": "string" + }, + "c_Moneda": { + "enum": [ + "AED", + "AFN", + "ALL", + "AMD", + "ANG", + "AOA", + "ARS", + "AUD", + "AWG", + "AZN", + "BAM", + "BBD", + "BDT", + "BGN", + "BHD", + "BIF", + "BMD", + "BND", + "BOB", + "BOV", + "BRL", + "BSD", + "BTN", + "BWP", + "BYR", + "BZD", + "CAD", + "CDF", + "CHE", + "CHF", + "CHW", + "CLF", + "CLP", + "CNH", + "CNY", + "COP", + "COU", + "CRC", + "CUC", + "CUP", + "CVE", + "CZK", + "DJF", + "DKK", + "DOP", + "DZD", + "EGP", + "ERN", + "ESD", + "ETB", + "EUR", + "FJD", + "FKP", + "GBP", + "GEL", + "GHS", + "GIP", + "GMD", + "GNF", + "GTQ", + "GYD", + "HKD", + "HNL", + "HRK", + "HTG", + "HUF", + "IDR", + "ILS", + "INR", + "IQD", + "IRR", + "ISK", + "JMD", + "JOD", + "JPY", + "KES", + "KGS", + "KHR", + "KMF", + "KPW", + "KRW", + "KWD", + "KYD", + "KZT", + "LAK", + "LBP", + "LKR", + "LRD", + "LSL", + "LYD", + "MAD", + "MDL", + "MGA", + "MKD", + "MMK", + "MNT", + "MOP", + "MRO", + "MUR", + "MVR", + "MWK", + "MXN", + "MXV", + "MYR", + "MZN", + "NAD", + "NGN", + "NIC", + "NIO", + "NOK", + "NPR", + "NZD", + "OMR", + "PAB", + "PEN", + "PGK", + "PHP", + "PKR", + "PLN", + "PYG", + "QAR", + "RON", + "RSD", + "RUB", + "RWF", + "SAR", + "SBD", + "SCR", + "SDG", + "SEK", + "SGD", + "SHP", + "SLL", + "SOS", + "SRD", + "SSP", + "STD", + "SVC", + "SYP", + "SZL", + "THB", + "TJS", + "TMT", + "TND", + "TOP", + "TRY", + "TTD", + "TWD", + "TZS", + "UAH", + "UGX", + "USD", + "USN", + "UYI", + "UYP", + "UYU", + "UZS", + "VEF", + "VES", + "VND", + "VUV", + "WST", + "XAF", + "XAG", + "XAU", + "XBA", + "XBB", + "XBC", + "XBD", + "XCD", + "XDR", + "XOF", + "XPD", + "XPF", + "XPT", + "XSU", + "XTS", + "XUA", + "XXX", + "YER", + "ZAR", + "ZMW", + "ZWL" + ], + "type": "string" + }, + "c_TipoDeComprobante": { + "enum": [ + "I", + "E", + "T", + "N", + "P" + ], + "type": "string" + }, + "c_Exportacion": { + "enum": [ + "01", + "02", + "03", + "04" + ], + "type": "string" + }, + "c_MetodoPago": { + "enum": [ + "PUE", + "PPD" + ], + "type": "string" + }, + "c_CodigoPostal": { + "type": "string" + }, + "c_Periodicidad": { + "enum": [ + "01", + "02", + "03", + "04", + "05" + ], + "type": "string" + }, + "c_Meses": { + "enum": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18" + ], + "type": "string" + }, + "c_TipoRelacion": { + "enum": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09" + ], + "type": "string" + }, + "c_RegimenFiscal": { + "enum": [ + "601", + "603", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "614", + "615", + "616", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "628", + "629", + "630" + ], + "type": "string" + }, + "c_Pais": { + "enum": [ + "AFG", + "ALA", + "ALB", + "DEU", + "AND", + "AGO", + "AIA", + "ATA", + "ATG", + "SAU", + "DZA", + "ARG", + "ARM", + "ABW", + "AUS", + "AUT", + "AZE", + "BHS", + "BGD", + "BRB", + "BHR", + "BEL", + "BLZ", + "BEN", + "BMU", + "BLR", + "MMR", + "BOL", + "BIH", + "BWA", + "BRA", + "BRN", + "BGR", + "BFA", + "BDI", + "BTN", + "CPV", + "KHM", + "CMR", + "CAN", + "QAT", + "BES", + "TCD", + "CHL", + "CHN", + "CYP", + "COL", + "COM", + "PRK", + "KOR", + "CIV", + "CRI", + "HRV", + "CUB", + "CUW", + "DNK", + "DMA", + "ECU", + "EGY", + "SLV", + "ARE", + "ERI", + "SVK", + "SVN", + "ESP", + "USA", + "EST", + "ETH", + "PHL", + "FIN", + "FJI", + "FRA", + "GAB", + "GMB", + "GEO", + "GHA", + "GIB", + "GRD", + "GRC", + "GRL", + "GLP", + "GUM", + "GTM", + "GUF", + "GGY", + "GIN", + "GNB", + "GNQ", + "GUY", + "HTI", + "HND", + "HKG", + "HUN", + "IND", + "IDN", + "IRQ", + "IRN", + "IRL", + "BVT", + "IMN", + "CXR", + "NFK", + "ISL", + "CYM", + "CCK", + "COK", + "FRO", + "SGS", + "HMD", + "FLK", + "MNP", + "MHL", + "PCN", + "SLB", + "TCA", + "UMI", + "VGB", + "VIR", + "ISR", + "ITA", + "JAM", + "JPN", + "JEY", + "JOR", + "KAZ", + "KEN", + "KGZ", + "KIR", + "KWT", + "LAO", + "LSO", + "LVA", + "LBN", + "LBR", + "LBY", + "LIE", + "LTU", + "LUX", + "MAC", + "MDG", + "MYS", + "MWI", + "MDV", + "MLI", + "MLT", + "MAR", + "MTQ", + "MUS", + "MRT", + "MYT", + "MEX", + "FSM", + "MDA", + "MCO", + "MNG", + "MNE", + "MSR", + "MOZ", + "NAM", + "NRU", + "NPL", + "NIC", + "NER", + "NGA", + "NIU", + "NOR", + "NCL", + "NZL", + "OMN", + "NLD", + "PAK", + "PLW", + "PSE", + "PAN", + "PNG", + "PRY", + "PER", + "PYF", + "POL", + "PRT", + "PRI", + "GBR", + "CAF", + "CZE", + "MKD", + "COG", + "COD", + "DOM", + "REU", + "RWA", + "ROU", + "RUS", + "ESH", + "WSM", + "ASM", + "BLM", + "KNA", + "SMR", + "MAF", + "SPM", + "VCT", + "SHN", + "LCA", + "STP", + "SEN", + "SRB", + "SYC", + "SLE", + "SGP", + "SXM", + "SYR", + "SOM", + "LKA", + "SWZ", + "ZAF", + "SDN", + "SSD", + "SWE", + "CHE", + "SUR", + "SJM", + "THA", + "TWN", + "TZA", + "TJK", + "IOT", + "ATF", + "TLS", + "TGO", + "TKL", + "TON", + "TTO", + "TUN", + "TKM", + "TUR", + "TUV", + "UKR", + "UGA", + "URY", + "UZB", + "VUT", + "VAT", + "VEN", + "VNM", + "WLF", + "YEM", + "DJI", + "ZMB", + "ZWE", + "ZZZ" + ], + "type": "string" + }, + "c_UsoCFDI": { + "enum": [ + "G01", + "G02", + "G03", + "I01", + "I02", + "I03", + "I04", + "I05", + "I06", + "I07", + "I08", + "D01", + "D02", + "D03", + "D04", + "D05", + "D06", + "D07", + "D08", + "D09", + "D10", + "P01", + "S01", + "CP01", + "CN01" + ], + "type": "string" + }, + "c_ClaveProdServ": { + "type": "string" + }, + "c_ClaveUnidad": { + "type": "string" + }, + "c_ObjetoImp": { + "enum": [ + "01", + "02", + "03", + "04" + ], + "type": "string" + }, + "c_Impuesto": { + "enum": [ + "001", + "002", + "003" + ], + "type": "string" + }, + "c_TipoFactor": { + "enum": [ + "Tasa", + "Cuota", + "Exento" + ], + "type": "string" + }, + "c_Estado": { + "enum": [ + "AGU", + "BCN", + "BCS", + "CAM", + "CHP", + "CHH", + "COA", + "COL", + "DIF", + "CMX", + "DUR", + "GUA", + "GRO", + "HID", + "JAL", + "MEX", + "MIC", + "MOR", + "NAY", + "NLE", + "OAX", + "PUE", + "QUE", + "ROO", + "SLP", + "SIN", + "SON", + "TAB", + "TAM", + "TLA", + "VER", + "YUC", + "ZAC", + "AL", + "AK", + "AZ", + "AR", + "CA", + "NC", + "SC", + "CO", + "CT", + "ND", + "SD", + "DE", + "FL", + "GA", + "HI", + "ID", + "IL", + "IN", + "IA", + "KS", + "KY", + "LA", + "ME", + "MD", + "MA", + "MI", + "MN", + "MS", + "MO", + "MT", + "NE", + "NV", + "NJ", + "NY", + "NH", + "NM", + "OH", + "OK", + "OR", + "PA", + "RI", + "TN", + "TX", + "UT", + "VT", + "VA", + "WV", + "WA", + "WI", + "WY", + "ON", + "QC", + "NS", + "NB", + "MB", + "BC", + "PE", + "SK", + "AB", + "NL", + "NT", + "YT", + "UN" + ], + "type": "string" + }, + "c_Colonia": { + "type": "string" + }, + "c_Localidad": { + "enum": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", + "32", + "33", + "34", + "35", + "36", + "37", + "38", + "39", + "40", + "41", + "42", + "43", + "44", + "45", + "46", + "47", + "48", + "49", + "50", + "51", + "52", + "53", + "54", + "55", + "56", + "57", + "58", + "59", + "60", + "61", + "62", + "66", + "67", + "68", + "69" + ], + "type": "string" + }, + "c_Municipio": { + "enum": [ + "001", + "002", + "003", + "004", + "005", + "006", + "007", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "024", + "025", + "026", + "027", + "028", + "029", + "030", + "031", + "032", + "033", + "034", + "035", + "036", + "037", + "038", + "039", + "040", + "041", + "042", + "043", + "044", + "045", + "046", + "047", + "048", + "049", + "050", + "051", + "052", + "053", + "054", + "055", + "056", + "057", + "058", + "059", + "060", + "061", + "062", + "063", + "064", + "065", + "066", + "067", + "068", + "069", + "070", + "071", + "072", + "073", + "074", + "075", + "076", + "077", + "078", + "079", + "080", + "081", + "082", + "083", + "084", + "085", + "086", + "087", + "088", + "089", + "090", + "091", + "092", + "093", + "094", + "095", + "096", + "097", + "098", + "099", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "123", + "124", + "125", + "126", + "127", + "128", + "129", + "130", + "131", + "132", + "133", + "134", + "135", + "136", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + "160", + "161", + "162", + "163", + "164", + "165", + "166", + "167", + "168", + "169", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "256", + "257", + "258", + "259", + "260", + "261", + "262", + "263", + "264", + "265", + "266", + "267", + "268", + "269", + "270", + "271", + "272", + "273", + "274", + "275", + "276", + "277", + "278", + "279", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "287", + "288", + "289", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "306", + "307", + "308", + "309", + "310", + "311", + "312", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + "512", + "513", + "514", + "515", + "516", + "517", + "518", + "519", + "520", + "521", + "522", + "523", + "524", + "525", + "526", + "527", + "528", + "529", + "530", + "531", + "532", + "533", + "534", + "535", + "536", + "537", + "538", + "539", + "540", + "541", + "542", + "543", + "544", + "545", + "546", + "547", + "548", + "549", + "550", + "551", + "552", + "553", + "554", + "555", + "556", + "557", + "558", + "559", + "560", + "561", + "562", + "563", + "564", + "565", + "566", + "567", + "568", + "569", + "570" + ], + "type": "string" + } + } +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/catalogos/tipodatos.json b/packages/cfdi/schema/src/files/schema/catalogos/tipodatos.json new file mode 100644 index 00000000..f1adef17 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/catalogos/tipodatos.json @@ -0,0 +1,135 @@ +{ + "$id": "tipoDatos.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from tipoDatos on Tue Dec 26 2023 19:00:38 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Schema tag attributes: xmlns:tdCFDI='http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI' xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI' elementFormDefault='unqualified' attributeFormDefault='unqualified'", + "properties": { + "t_CURP": { "$ref": "#/definitions/t_CURP" }, + "t_Importe": { "$ref": "#/definitions/t_Importe" }, + "t_Fecha": { "$ref": "#/definitions/t_Fecha" }, + "t_ImporteMXN": { "$ref": "#/definitions/t_ImporteMXN" }, + "t_CuentaBancaria": { "$ref": "#/definitions/t_CuentaBancaria" }, + "t_RFC": { "$ref": "#/definitions/t_RFC" }, + "t_RFC_PM": { "$ref": "#/definitions/t_RFC_PM" }, + "t_RFC_PF": { "$ref": "#/definitions/t_RFC_PF" }, + "t_FechaHora": { "$ref": "#/definitions/t_FechaHora" }, + "t_FechaH": { "$ref": "#/definitions/t_FechaH" }, + "t_Descrip100": { "$ref": "#/definitions/t_Descrip100" }, + "t_NumeroDomicilio": { "$ref": "#/definitions/t_NumeroDomicilio" }, + "t_Referencia": { "$ref": "#/definitions/t_Referencia" }, + "t_Descrip120": { "$ref": "#/definitions/t_Descrip120" }, + "t_TipoCambio": { "$ref": "#/definitions/t_TipoCambio" } + }, + "type": "object", + "anyOf": [ + { "required": ["t_CURP"] }, + { "required": ["t_Importe"] }, + { "required": ["t_Fecha"] }, + { "required": ["t_ImporteMXN"] }, + { "required": ["t_CuentaBancaria"] }, + { "required": ["t_RFC"] }, + { "required": ["t_RFC_PM"] }, + { "required": ["t_RFC_PF"] }, + { "required": ["t_FechaHora"] }, + { "required": ["t_FechaH"] }, + { "required": ["t_Descrip100"] }, + { "required": ["t_NumeroDomicilio"] }, + { "required": ["t_Referencia"] }, + { "required": ["t_Descrip120"] }, + { "required": ["t_TipoCambio"] } + ], + "definitions": { + "t_CURP": { + "description": "Tipo definido para expresar la Clave Única de Registro de Población (CURP)", + "maxLength": 18, + "minLength": 18, + "pattern": "[A-Z][AEIOUX][A-Z]{2}[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])[MH]([ABCMTZ]S|[BCJMOT]C|[CNPST]L|[GNQ]T|[GQS]R|C[MH]|[MY]N|[DH]G|NE|VZ|DF|SP)[BCDFGHJ-NP-TV-Z]{3}[0-9A-Z][0-9]", + "type": "string" + }, + "t_Importe": { + "description": "Tipo definido para expresar importes numéricos con fracción hasta seis decimales. No se permiten valores negativos.", + "minimum": 0, + "pattern": "[0-9]{1,18}(.[0-9]{1,6})?", + "type": "number" + }, + "t_Fecha": { + "description": "Tipo definido para la expresión de la fecha. Se expresa en la forma AAAA-MM-DD.", + "pattern": "((19|20)[0-9][0-9])-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])", + "type": "string" + }, + "t_ImporteMXN": { + "description": "Tipo definido para expresar importes monetarios en moneda nacional MXN con fracción hasta dos decimales. No se permiten valores negativos.", + "minimum": 0, + "pattern": "[0-9]{1,18}(.[0-9]{1,2})?", + "type": "number" + }, + "t_CuentaBancaria": { + "description": "Tipo definido para expresar la cuenta bancarizada.", + "pattern": "[0-9]{10,18}", + "type": "integer" + }, + "t_RFC": { + "description": "Tipo definido para expresar claves del Registro Federal de Contribuyentes", + "maxLength": 13, + "minLength": 12, + "pattern": "[A-Z&Ñ]{3,4}[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])[A-Z0-9]{2}[0-9A]", + "type": "string" + }, + "t_RFC_PM": { + "description": "Tipo definido para la expresión de un Registro Federal de Contribuyentes de persona moral.", + "minLength": 12, + "pattern": "[A-Z&Ñ]{3}[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])[A-Z0-9]{2}[0-9A]", + "type": "string" + }, + "t_RFC_PF": { + "description": "Tipo definido para la expresión de un Registro Federal de Contribuyentes de persona física.", + "minLength": 13, + "pattern": "[A-Z&Ñ]{4}[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])[A-Z0-9]{2}[0-9A]", + "type": "string" + }, + "t_FechaHora": { + "description": "Tipo definido para la expresión de la fecha y hora. Se expresa en la forma AAAA-MM-DDThh:mm:ss", + "pattern": "((19|20)[0-9][0-9])-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])", + "type": "string" + }, + "t_FechaH": { + "description": "Tipo definido para la expresión de la fecha y hora. Se expresa en la forma AAAA-MM-DDThh:mm:ss", + "pattern": "(20[1-9][0-9])-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9])", + "type": "string" + }, + "t_Descrip100": { + "description": "Tipo definido para expresar la calle en que está ubicado el domicilio del emisor del comprobante o del destinatario de la mercancía.", + "maxLength": 100, + "minLength": 1, + "pattern": "[^|]{1,100}", + "type": "string" + }, + "t_NumeroDomicilio": { + "description": "Tipo definido para expresar el número interior o el número exterior en donde se ubica el domicilio del emisor del comprobante o del destinatario de la mercancía.", + "maxLength": 55, + "minLength": 1, + "pattern": "[^|]{1,55}", + "type": "string" + }, + "t_Referencia": { + "description": "Tipo definido para expresar la referencia geográfica adicional que permita una fácil o precisa ubicación del domicilio del emisor del comprobante o del destinatario de la mercancía, por ejemplo las coordenadas GPS.", + "maxLength": 250, + "minLength": 1, + "pattern": "[^|]{1,250}", + "type": "string" + }, + "t_Descrip120": { + "description": "Tipo definido para expresar la colonia, localidad o municipio en que está ubicado el domicilio del emisor del comprobante o del destinatario de la mercancía.", + "maxLength": 120, + "minLength": 1, + "pattern": "[^|]{1,120}", + "type": "string" + }, + "t_TipoCambio": { + "description": "Tipo definido para expresar el tipo de cambio. No se permiten valores negativos.", + "minimum": 0, + "pattern": "[0-9]{1,18}(.[0-9]{1,6})?", + "type": "number" + } + } +} diff --git a/packages/cfdi/schema/src/files/schema/cfdi.json b/packages/cfdi/schema/src/files/schema/cfdi.json new file mode 100644 index 00000000..ba62c299 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/cfdi.json @@ -0,0 +1,129 @@ +{ + "catalogos": [ + { + "name": "tipodatos", + "type": "catalogos", + "key": "CATALOGOS_TIPODATOS", + "path": "catalogos" + }, + { + "name": "catalogos", + "type": "catalogos", + "key": "CATALOGOS_CATALOGOS", + "path": "catalogos" + } + ], + "comprobante": [ + { + "name": "comprobante", + "type": "comprobante", + "key": "COMPROBANTE", + "path": "comprobante" + }, + { + "name": "informacionglobal", + "type": "comprobante", + "key": "COMPROBANTE_INFORMACIONGLOBAL", + "path": "informacionglobal" + }, + { + "name": "cfdirelacionado", + "type": "comprobante", + "key": "COMPROBANTE_CFDIRELACIONADOS_CFDIRELACIONADO", + "path": "cfdirelacionados" + }, + { + "name": "cfdirelacionados", + "type": "comprobante", + "key": "COMPROBANTE_CFDIRELACIONADOS", + "path": "cfdirelacionados" + }, + { + "name": "emisor", + "type": "comprobante", + "key": "COMPROBANTE_EMISOR", + "path": "emisor" + }, + { + "name": "receptor", + "type": "comprobante", + "key": "COMPROBANTE_RECEPTOR", + "path": "receptor" + }, + { + "name": "traslado", + "type": "comprobante", + "key": "COMPROBANTE_CONCEPTOS_CONCEPTO_IMPUESTOS_TRASLADOS_TRASLADO", + "path": "conceptos" + }, + { + "name": "retencion", + "type": "comprobante", + "key": "COMPROBANTE_CONCEPTOS_CONCEPTO_IMPUESTOS_RETENCIONES_RETENCION", + "path": "conceptos" + }, + { + "name": "acuentaterceros", + "type": "comprobante", + "key": "COMPROBANTE_CONCEPTOS_CONCEPTO_ACUENTATERCEROS", + "path": "conceptos" + }, + { + "name": "informacionaduanera", + "type": "comprobante", + "key": "COMPROBANTE_CONCEPTOS_CONCEPTO_INFORMACIONADUANERA", + "path": "conceptos" + }, + { + "name": "cuentapredial", + "type": "comprobante", + "key": "COMPROBANTE_CONCEPTOS_CONCEPTO_CUENTAPREDIAL", + "path": "conceptos" + }, + { + "name": "informacionaduanera", + "type": "comprobante", + "key": "COMPROBANTE_CONCEPTOS_CONCEPTO_PARTE_INFORMACIONADUANERA", + "path": "conceptos" + }, + { + "name": "parte", + "type": "comprobante", + "key": "COMPROBANTE_CONCEPTOS_CONCEPTO_PARTE", + "path": "conceptos" + }, + { + "name": "concepto", + "type": "comprobante", + "key": "COMPROBANTE_CONCEPTOS_CONCEPTO", + "path": "conceptos" + }, + { + "name": "retencion", + "type": "comprobante", + "key": "COMPROBANTE_IMPUESTOS_RETENCIONES_RETENCION", + "path": "impuestos" + }, + { + "name": "traslado", + "type": "comprobante", + "key": "COMPROBANTE_IMPUESTOS_TRASLADOS_TRASLADO", + "path": "impuestos" + }, + { + "name": "impuestos", + "type": "comprobante", + "key": "COMPROBANTE_IMPUESTOS", + "path": "impuestos" + } + ], + "complementos": [ + { + "name": "iedu", + "type": "complementos", + "key": "IEDU", + "path": "complementos" + } + ], + "unknow": [] +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/cfdirelacionados/cfdirelacionado.json b/packages/cfdi/schema/src/files/schema/cfdirelacionados/cfdirelacionado.json new file mode 100644 index 00000000..a53c174e --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/cfdirelacionados/cfdirelacionado.json @@ -0,0 +1,18 @@ +{ + "$id": "comprobante_CfdiRelacionados_CfdiRelacionado.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_CfdiRelacionados_CfdiRelacionado on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Schema tag attributes: xmlns:cfdi='http://www.sat.gob.mx/cfd/4' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:catCFDI='http://www.sat.gob.mx/sitio_internet/cfd/catalogos' xmlns:tdCFDI='http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI' targetNamespace='http://www.sat.gob.mx/cfd/4' elementFormDefault='qualified' attributeFormDefault='unqualified'", + "required": ["UUID"], + "properties": { + "UUID": { + "description": "Atributo requerido para registrar el folio fiscal (UUID) de un CFDI relacionado con el presente comprobante, por ejemplo: Si el CFDI relacionado es un comprobante de traslado que sirve para registrar el movimiento de la mercancía. Si este comprobante se usa como nota de crédito o nota de débito del comprobante relacionado. Si este comprobante es una devolución sobre el comprobante relacionado. Si éste sustituye a una factura cancelada.", + "maxLength": 36, + "minLength": 36, + "pattern": "[a-f0-9A-F]{8}-[a-f0-9A-F]{4}-[a-f0-9A-F]{4}-[a-f0-9A-F]{4}-[a-f0-9A-F]{12}", + "type": "string" + } + }, + "type": "object", + "definitions": {} +} diff --git a/packages/cfdi/schema/src/files/schema/cfdirelacionados/cfdirelacionados.json b/packages/cfdi/schema/src/files/schema/cfdirelacionados/cfdirelacionados.json new file mode 100644 index 00000000..c393237e --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/cfdirelacionados/cfdirelacionados.json @@ -0,0 +1,14 @@ +{ + "$id": "comprobante_CfdiRelacionados.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_CfdiRelacionados on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo requerido para indicar la clave de la relación que existe entre éste que se está generando y el o los CFDI previos.", + "required": ["TipoRelacion"], + "properties": { + "TipoRelacion": { + "$ref": "catalogos.json#/definitions/c_TipoRelacion" + } + }, + "type": "object", + "definitions": {} +} diff --git a/packages/cfdi/schema/src/files/schema/complementos/iedu.json b/packages/cfdi/schema/src/files/schema/complementos/iedu.json new file mode 100644 index 00000000..7b65ccc8 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/complementos/iedu.json @@ -0,0 +1,53 @@ +{ + "$id": "iedu.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from iedu on Tue Dec 26 2023 18:59:29 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Schema tag attributes: xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:iedu='http://www.sat.gob.mx/iedu' targetNamespace='http://www.sat.gob.mx/iedu' elementFormDefault='qualified' attributeFormDefault='unqualified'", + "required": [ + "version", + "nombreAlumno", + "CURP", + "nivelEducativo", + "autRVOE" + ], + "properties": { + "version": { + "description": "Atributo requerido con valor prefijado a 1.0 que indica la versión del estándar bajo el que se encuentra expresado el complemento concepto al comprobante.", + "type": "string" + }, + "nombreAlumno": { + "description": "Atributo requerido para indicar el nombre del Alumno", + "type": "string" + }, + "CURP": { + "maxLength": 18, + "minLength": 18, + "pattern": "[A-Z][A,E,I,O,U,X][A-Z]{2}[0-9]{2}[0-1][0-9][0-3][0-9][M,H][A-Z]{2}[B,C,D,F,G,H,J,K,L,M,N,Ñ,P,Q,R,S,T,V,W,X,Y,Z]{3}[0-9,A-Z][0-9]", + "type": "string" + }, + "nivelEducativo": { + "description": "Atributo requerido para indicar el nivel educativo que cursa el alumno", + "enum": [ + "Preescolar", + "Primaria", + "Secundaria", + "Profesional técnico", + "Bachillerato o su equivalente" + ], + "type": "string" + }, + "autRVOE": { + "description": "Atributo requerido para especificar la clave del centro de trabajo o el reconocimiento de validez oficial de estudios en los términos de la Ley General de Educación que tenga la institución educativa privada donde se realiza el pago.", + "minLength": 1, + "type": "string" + }, + "rfcPago": { + "maxLength": 13, + "minLength": 12, + "pattern": "[A-Z,Ñ,&]{3,4}[0-9]{2}[0-1][0-9][0-3][0-9][A-Z,0-9]?[A-Z,0-9]?[0-9,A-Z]?", + "type": "string" + } + }, + "type": "object", + "definitions": {} +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/comprobante/comprobante.json b/packages/cfdi/schema/src/files/schema/comprobante/comprobante.json new file mode 100644 index 00000000..6383eb79 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/comprobante/comprobante.json @@ -0,0 +1,105 @@ +{ + "$id": "comprobante.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo requerido para incorporar el código postal del lugar de expedición del comprobante (domicilio de la matriz o de la sucursal).", + "required": [ + "Version", + "Fecha", + "Sello", + "NoCertificado", + "Certificado", + "SubTotal", + "Moneda", + "Total", + "TipoDeComprobante", + "Exportacion", + "LugarExpedicion" + ], + "properties": { + "Version": { + "description": "Atributo requerido con valor prefijado a 4.0 que indica la versión del estándar bajo el que se encuentra expresado el comprobante.", + "type": "string" + }, + "Serie": { + "description": "Atributo opcional para precisar la serie para control interno del contribuyente. Este atributo acepta una cadena de caracteres.", + "maxLength": 25, + "minLength": 1, + "pattern": "[^|]{1,25}", + "type": "string" + }, + "Folio": { + "description": "Atributo opcional para control interno del contribuyente que expresa el folio del comprobante, acepta una cadena de caracteres.", + "maxLength": 40, + "minLength": 1, + "pattern": "[^|]{1,40}", + "type": "string" + }, + "Fecha": { + "$ref": "tipoDatos.json#/definitions/t_FechaH" + }, + "Sello": { + "description": "Atributo requerido para contener el sello digital del comprobante fiscal, al que hacen referencia las reglas de resolución miscelánea vigente. El sello debe ser expresado como una cadena de texto en formato Base 64.", + "type": "string" + }, + "FormaPago": { + "$ref": "catalogos.json#/definitions/c_FormaPago" + }, + "NoCertificado": { + "description": "Atributo requerido para expresar el número de serie del certificado de sello digital que ampara al comprobante, de acuerdo con el acuse correspondiente a 20 posiciones otorgado por el sistema del SAT.", + "maxLength": 20, + "minLength": 20, + "pattern": "[0-9]{20}", + "type": "string" + }, + "Certificado": { + "description": "Atributo requerido que sirve para incorporar el certificado de sello digital que ampara al comprobante, como texto en formato base 64.", + "type": "string" + }, + "CondicionesDePago": { + "description": "Atributo condicional para expresar las condiciones comerciales aplicables para el pago del comprobante fiscal digital por Internet. Este atributo puede ser condicionado mediante atributos o complementos.", + "maxLength": 1000, + "minLength": 1, + "pattern": "[^|]{1,1000}", + "type": "string" + }, + "SubTotal": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + }, + "Descuento": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + }, + "Moneda": { + "$ref": "catalogos.json#/definitions/c_Moneda" + }, + "TipoCambio": { + "description": "Atributo condicional para representar el tipo de cambio FIX conforme con la moneda usada. Es requerido cuando la clave de moneda es distinta de MXN y de XXX. El valor debe reflejar el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo moneda. Si el valor está fuera del porcentaje aplicable a la moneda tomado del catálogo c_Moneda, el emisor debe obtener del PAC que vaya a timbrar el CFDI, de manera no automática, una clave de confirmación para ratificar que el valor es correcto e integrar dicha clave en el atributo Confirmacion.", + "minimum": 0.000001, + "type": "number" + }, + "Total": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + }, + "TipoDeComprobante": { + "$ref": "catalogos.json#/definitions/c_TipoDeComprobante" + }, + "Exportacion": { + "$ref": "catalogos.json#/definitions/c_Exportacion" + }, + "MetodoPago": { + "$ref": "catalogos.json#/definitions/c_MetodoPago" + }, + "LugarExpedicion": { + "$ref": "catalogos.json#/definitions/c_CodigoPostal" + }, + "Confirmacion": { + "description": "Atributo condicional para registrar la clave de confirmación que entregue el PAC para expedir el comprobante con importes grandes, con un tipo de cambio fuera del rango establecido o con ambos casos. Es requerido cuando se registra un tipo de cambio o un total fuera del rango establecido.", + "maxLength": 5, + "minLength": 5, + "pattern": "[0-9a-zA-Z]{5}", + "type": "string" + } + }, + "type": "object", + "definitions": {} +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/conceptos/acuentaterceros.json b/packages/cfdi/schema/src/files/schema/conceptos/acuentaterceros.json new file mode 100644 index 00000000..49c7851f --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/conceptos/acuentaterceros.json @@ -0,0 +1 @@ +{"$id":"comprobante_Conceptos_Concepto_ACuentaTerceros.json","$schema":"http://json-schema.org/draft-07/schema#","title":"This JSON Schema file was generated from comprobante_Conceptos_Concepto_ACuentaTerceros on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org","description":"Atributo requerido para incorporar la clave del régimen del contribuyente Tercero, a cuenta del que se realiza la operación.","required":["RfcACuentaTerceros","NombreACuentaTerceros","RegimenFiscalACuentaTerceros","DomicilioFiscalACuentaTerceros"],"properties":{"RfcACuentaTerceros":{"$ref":"tipoDatos.json#/definitions/t_RFC"},"NombreACuentaTerceros":{"description":"Atributo requerido para registrar el nombre, denominación o razón social del contribuyente Tercero correspondiente con el Rfc, a cuenta del que se realiza la operación.","maxLength":300,"minLength":1,"pattern":"[^|]{1,300}","type":"string"},"RegimenFiscalACuentaTerceros":{"$ref":"catalogos.json#/definitions/c_RegimenFiscal"},"DomicilioFiscalACuentaTerceros":{"description":"Atributo requerido para incorporar el código postal del domicilio fiscal del Tercero, a cuenta del que se realiza la operación.","maxLength":5,"minLength":5,"pattern":"[0-9]{5}","type":"string"}},"type":"object","definitions":{}} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/conceptos/concepto.json b/packages/cfdi/schema/src/files/schema/conceptos/concepto.json new file mode 100644 index 00000000..bfd40ab8 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/conceptos/concepto.json @@ -0,0 +1,63 @@ +{ + "$id": "comprobante_Conceptos_Concepto.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_Conceptos_Concepto on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo requerido para expresar si la operación comercial es objeto o no de impuesto.", + "required": [ + "ClaveProdServ", + "Cantidad", + "ClaveUnidad", + "Descripcion", + "ValorUnitario", + "Importe", + "ObjetoImp" + ], + "properties": { + "ClaveProdServ": { + "$ref": "catalogos.json#/definitions/c_ClaveProdServ" + }, + "NoIdentificacion": { + "description": "Atributo opcional para expresar el número de parte, identificador del producto o del servicio, la clave de producto o servicio, SKU o equivalente, propia de la operación del emisor, amparado por el presente concepto. Opcionalmente se puede utilizar claves del estándar GTIN.", + "maxLength": 100, + "minLength": 1, + "pattern": "[^|]{1,100}", + "type": "string" + }, + "Cantidad": { + "description": "Atributo requerido para precisar la cantidad de bienes o servicios del tipo particular definido por el presente concepto.", + "minimum": 0.000001, + "type": "number" + }, + "ClaveUnidad": { + "$ref": "catalogos.json#/definitions/c_ClaveUnidad" + }, + "Unidad": { + "description": "Atributo opcional para precisar la unidad de medida propia de la operación del emisor, aplicable para la cantidad expresada en el concepto. La unidad debe corresponder con la descripción del concepto.", + "maxLength": 20, + "minLength": 1, + "pattern": "[^|]{1,20}", + "type": "string" + }, + "Descripcion": { + "description": "Atributo requerido para precisar la descripción del bien o servicio cubierto por el presente concepto.", + "maxLength": 1000, + "minLength": 1, + "pattern": "[^|]{1,1000}", + "type": "string" + }, + "ValorUnitario": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + }, + "Importe": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + }, + "Descuento": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + }, + "ObjetoImp": { + "$ref": "catalogos.json#/definitions/c_ObjetoImp" + } + }, + "type": "object", + "definitions": {} +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/conceptos/cuentapredial.json b/packages/cfdi/schema/src/files/schema/conceptos/cuentapredial.json new file mode 100644 index 00000000..d204b499 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/conceptos/cuentapredial.json @@ -0,0 +1 @@ +{"$id":"comprobante_Conceptos_Concepto_CuentaPredial.json","$schema":"http://json-schema.org/draft-07/schema#","title":"This JSON Schema file was generated from comprobante_Conceptos_Concepto_CuentaPredial on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org","description":"Schema tag attributes: xmlns:cfdi='http://www.sat.gob.mx/cfd/4' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:catCFDI='http://www.sat.gob.mx/sitio_internet/cfd/catalogos' xmlns:tdCFDI='http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI' targetNamespace='http://www.sat.gob.mx/cfd/4' elementFormDefault='qualified' attributeFormDefault='unqualified'","required":["Numero"],"properties":{"Numero":{"description":"Atributo requerido para precisar el número de la cuenta predial del inmueble cubierto por el presente concepto, o bien para incorporar los datos de identificación del certificado de participación inmobiliaria no amortizable, tratándose de arrendamiento.","maxLength":150,"minLength":1,"pattern":"[0-9a-zA-Z]{1,150}","type":"string"}},"type":"object","definitions":{}} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/conceptos/informacionaduanera.json b/packages/cfdi/schema/src/files/schema/conceptos/informacionaduanera.json new file mode 100644 index 00000000..7688ff3c --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/conceptos/informacionaduanera.json @@ -0,0 +1 @@ +{"$id":"comprobante_Conceptos_Concepto_InformacionAduanera.json","$schema":"http://json-schema.org/draft-07/schema#","title":"This JSON Schema file was generated from comprobante_Conceptos_Concepto_InformacionAduanera on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org","description":"Schema tag attributes: xmlns:cfdi='http://www.sat.gob.mx/cfd/4' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:catCFDI='http://www.sat.gob.mx/sitio_internet/cfd/catalogos' xmlns:tdCFDI='http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI' targetNamespace='http://www.sat.gob.mx/cfd/4' elementFormDefault='qualified' attributeFormDefault='unqualified'","required":["NumeroPedimento"],"properties":{"NumeroPedimento":{"description":"Atributo requerido para expresar el número del pedimento que ampara la importación del bien que se expresa en el siguiente formato: últimos 2 dígitos del año de validación seguidos por dos espacios, 2 dígitos de la aduana de despacho seguidos por dos espacios, 4 dígitos del número de la patente seguidos por dos espacios, 1 dígito que corresponde al último dígito del año en curso, salvo que se trate de un pedimento consolidado iniciado en el año inmediato anterior o del pedimento original de una rectificación, seguido de 6 dígitos de la numeración progresiva por aduana.","maxLength":21,"minLength":21,"pattern":"[0-9]{2} [0-9]{2} [0-9]{4} [0-9]{7}","type":"string"}},"type":"object","definitions":{}} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/conceptos/parte.json b/packages/cfdi/schema/src/files/schema/conceptos/parte.json new file mode 100644 index 00000000..7f1f9a6d --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/conceptos/parte.json @@ -0,0 +1 @@ +{"$id":"comprobante_Conceptos_Concepto_Parte.json","$schema":"http://json-schema.org/draft-07/schema#","title":"This JSON Schema file was generated from comprobante_Conceptos_Concepto_Parte on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org","description":"Atributo opcional para precisar el importe total de los bienes o servicios de la presente parte. Debe ser equivalente al resultado de multiplicar la cantidad por el valor unitario expresado en la parte. No se permiten valores negativos.","required":["ClaveProdServ","Cantidad","Descripcion"],"properties":{"ClaveProdServ":{"$ref":"catalogos.json#/definitions/c_ClaveProdServ"},"NoIdentificacion":{"description":"Atributo opcional para expresar el número de serie, número de parte del bien o identificador del producto o del servicio amparado por la presente parte. Opcionalmente se puede utilizar claves del estándar GTIN.","maxLength":100,"minLength":1,"pattern":"[^|]{1,100}","type":"string"},"Cantidad":{"description":"Atributo requerido para precisar la cantidad de bienes o servicios del tipo particular definido por la presente parte.","minimum":0.000001,"type":"number"},"Unidad":{"description":"Atributo opcional para precisar la unidad de medida propia de la operación del emisor, aplicable para la cantidad expresada en la parte. La unidad debe corresponder con la descripción de la parte.","maxLength":20,"minLength":1,"pattern":"[^|]{1,20}","type":"string"},"Descripcion":{"description":"Atributo requerido para precisar la descripción del bien o servicio cubierto por la presente parte.","maxLength":1000,"minLength":1,"pattern":"[^|]{1,1000}","type":"string"},"ValorUnitario":{"$ref":"tipoDatos.json#/definitions/t_Importe"},"Importe":{"$ref":"tipoDatos.json#/definitions/t_Importe"}},"type":"object","definitions":{}} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/conceptos/retencion.json b/packages/cfdi/schema/src/files/schema/conceptos/retencion.json new file mode 100644 index 00000000..dd6cea90 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/conceptos/retencion.json @@ -0,0 +1,36 @@ +{ + "$id": "comprobante_Conceptos_Concepto_Impuestos_Retenciones_Retencion.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_Conceptos_Concepto_Impuestos_Retenciones_Retencion on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo requerido para señalar el importe del impuesto retenido que aplica al concepto. No se permiten valores negativos.", + "required": [ + "Base", + "Impuesto", + "TipoFactor", + "TasaOCuota", + "Importe" + ], + "properties": { + "Base": { + "description": "Atributo requerido para señalar la base para el cálculo de la retención, la determinación de la base se realiza de acuerdo con las disposiciones fiscales vigentes. No se permiten valores negativos.", + "minimum": 0.000001, + "type": "number" + }, + "Impuesto": { + "$ref": "catalogos.json#/definitions/c_Impuesto" + }, + "TipoFactor": { + "$ref": "catalogos.json#/definitions/c_TipoFactor" + }, + "TasaOCuota": { + "description": "Atributo requerido para señalar la tasa o cuota del impuesto que se retiene para el presente concepto.", + "minimum": 0, + "type": "number" + }, + "Importe": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + } + }, + "type": "object", + "definitions": {} +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/conceptos/traslado.json b/packages/cfdi/schema/src/files/schema/conceptos/traslado.json new file mode 100644 index 00000000..5cea45d4 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/conceptos/traslado.json @@ -0,0 +1,34 @@ +{ + "$id": "comprobante_Conceptos_Concepto_Impuestos_Traslados_Traslado.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_Conceptos_Concepto_Impuestos_Traslados_Traslado on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo condicional para señalar el importe del impuesto trasladado que aplica al concepto. No se permiten valores negativos. Es requerido cuando TipoFactor sea Tasa o Cuota.", + "required": [ + "Base", + "Impuesto", + "TipoFactor" + ], + "properties": { + "Base": { + "description": "Atributo requerido para señalar la base para el cálculo del impuesto, la determinación de la base se realiza de acuerdo con las disposiciones fiscales vigentes. No se permiten valores negativos.", + "minimum": 0.000001, + "type": "number" + }, + "Impuesto": { + "$ref": "catalogos.json#/definitions/c_Impuesto" + }, + "TipoFactor": { + "$ref": "catalogos.json#/definitions/c_TipoFactor" + }, + "TasaOCuota": { + "description": "Atributo condicional para señalar el valor de la tasa o cuota del impuesto que se traslada para el presente concepto. Es requerido cuando el atributo TipoFactor tenga una clave que corresponda a Tasa o Cuota.", + "minimum": 0, + "type": "number" + }, + "Importe": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + } + }, + "type": "object", + "definitions": {} +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/emisor/emisor.json b/packages/cfdi/schema/src/files/schema/emisor/emisor.json new file mode 100644 index 00000000..d4693dbd --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/emisor/emisor.json @@ -0,0 +1,35 @@ +{ + "$id": "comprobante_Emisor.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_Emisor on Tue Dec 26 2023 18:56:11 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo requerido para incorporar la clave del régimen del contribuyente emisor al que aplicará el efecto fiscal de este comprobante.", + "required": [ + "Rfc", + "Nombre", + "RegimenFiscal" + ], + "properties": { + "Rfc": { + "$ref": "tipoDatos.json#/definitions/t_RFC" + }, + "Nombre": { + "description": "Atributo requerido para registrar el nombre, denominación o razón social del contribuyente inscrito en el RFC, del emisor del comprobante.", + "maxLength": 300, + "minLength": 1, + "pattern": "[^|]{1,300}", + "type": "string" + }, + "RegimenFiscal": { + "$ref": "catalogos.json#/definitions/c_RegimenFiscal" + }, + "FacAtrAdquirente": { + "description": "Atributo condicional para expresar el número de operación proporcionado por el SAT cuando se trate de un comprobante a través de un PCECFDI o un PCGCFDISP.", + "maxLength": 10, + "minLength": 10, + "pattern": "[0-9]{10}", + "type": "string" + } + }, + "type": "object", + "definitions": {} +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/impuestos/impuestos.json b/packages/cfdi/schema/src/files/schema/impuestos/impuestos.json new file mode 100644 index 00000000..edba2b32 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/impuestos/impuestos.json @@ -0,0 +1,16 @@ +{ + "$id": "comprobante_Impuestos.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_Impuestos on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo condicional para expresar el total de los impuestos trasladados que se desprenden de los conceptos expresados en el comprobante fiscal digital por Internet. No se permiten valores negativos. Es requerido cuando en los conceptos se registren impuestos trasladados.", + "properties": { + "TotalImpuestosRetenidos": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + }, + "TotalImpuestosTrasladados": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + } + }, + "type": "object", + "definitions": {} +} diff --git a/packages/cfdi/schema/src/files/schema/impuestos/retencion.json b/packages/cfdi/schema/src/files/schema/impuestos/retencion.json new file mode 100644 index 00000000..8254b472 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/impuestos/retencion.json @@ -0,0 +1,20 @@ +{ + "$id": "comprobante_Impuestos_Retenciones_Retencion.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_Impuestos_Retenciones_Retencion on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo requerido para señalar el monto del impuesto retenido. No se permiten valores negativos.", + "required": [ + "Impuesto", + "Importe" + ], + "properties": { + "Impuesto": { + "$ref": "catalogos.json#/definitions/c_Impuesto" + }, + "Importe": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + } + }, + "type": "object", + "definitions": {} +} \ No newline at end of file diff --git a/packages/cfdi/schema/src/files/schema/impuestos/traslado.json b/packages/cfdi/schema/src/files/schema/impuestos/traslado.json new file mode 100644 index 00000000..177db621 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/impuestos/traslado.json @@ -0,0 +1,28 @@ +{ + "$id": "comprobante_Impuestos_Traslados_Traslado.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_Impuestos_Traslados_Traslado on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo condicional para señalar la suma del importe del impuesto trasladado, agrupado por impuesto, TipoFactor y TasaOCuota. No se permiten valores negativos.", + "required": ["Base", "Impuesto", "TipoFactor"], + "properties": { + "Base": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + }, + "Impuesto": { + "$ref": "catalogos.json#/definitions/c_Impuesto" + }, + "TipoFactor": { + "$ref": "catalogos.json#/definitions/c_TipoFactor" + }, + "TasaOCuota": { + "description": "Atributo condicional para señalar el valor de la tasa o cuota del impuesto que se traslada por los conceptos amparados en el comprobante.", + "minimum": 0, + "type": "number" + }, + "Importe": { + "$ref": "tipoDatos.json#/definitions/t_Importe" + } + }, + "type": "object", + "definitions": {} +} diff --git a/packages/cfdi/schema/src/files/schema/informacionglobal/informacionglobal.json b/packages/cfdi/schema/src/files/schema/informacionglobal/informacionglobal.json new file mode 100644 index 00000000..ab82db14 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/informacionglobal/informacionglobal.json @@ -0,0 +1,19 @@ +{ + "$id": "comprobante_InformacionGlobal.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_InformacionGlobal on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo requerido para expresar el mes o los meses al que corresponde la información del comprobante global.", + "required": ["Periodicidad", "Meses", "Año"], + "properties": { + "Periodicidad": { "$ref": "catalogos.json#/definitions/c_Periodicidad" }, + "Meses": { "$ref": "catalogos.json#/definitions/c_Meses" }, + "Año": { + "description": "Atributo requerido para expresar el año al que corresponde la información del comprobante global.", + "maximum": 32767, + "minimum": 2021, + "type": "integer" + } + }, + "type": "object", + "definitions": {} +} diff --git a/packages/cfdi/schema/src/files/schema/receptor/receptor.json b/packages/cfdi/schema/src/files/schema/receptor/receptor.json new file mode 100644 index 00000000..121cc5f8 --- /dev/null +++ b/packages/cfdi/schema/src/files/schema/receptor/receptor.json @@ -0,0 +1,43 @@ +{ + "$id": "comprobante_Receptor.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "This JSON Schema file was generated from comprobante_Receptor on Tue Dec 26 2023 18:31:04 GMT-0500 (Eastern Standard Time). For more information please see http://www.xsd2jsonschema.org", + "description": "Atributo requerido para expresar la clave del uso que dará a esta factura el receptor del CFDI.", + "required": ["Rfc", "Nombre", "DomicilioFiscalReceptor", "RegimenFiscalReceptor", "UsoCFDI"], + "properties": { + "Rfc": { + "$ref": "tipoDatos.json#/definitions/t_RFC" + }, + "Nombre": { + "description": "Atributo requerido para registrar el nombre(s), primer apellido, segundo apellido, según corresponda, denominación o razón social del contribuyente, inscrito en el RFC, del receptor del comprobante.", + "maxLength": 300, + "minLength": 1, + "pattern": "[^|]{1,300}", + "type": "string" + }, + "DomicilioFiscalReceptor": { + "description": "Atributo requerido para registrar el código postal del domicilio fiscal del receptor del comprobante.", + "maxLength": 5, + "minLength": 5, + "pattern": "[0-9]{5}", + "type": "string" + }, + "ResidenciaFiscal": { + "$ref": "catalogos.json#/definitions/c_Pais" + }, + "NumRegIdTrib": { + "description": "Atributo condicional para expresar el número de registro de identidad fiscal del receptor cuando sea residente en el extranjero. Es requerido cuando se incluya el complemento de comercio exterior.", + "maxLength": 40, + "minLength": 1, + "type": "string" + }, + "RegimenFiscalReceptor": { + "$ref": "catalogos.json#/definitions/c_RegimenFiscal" + }, + "UsoCFDI": { + "$ref": "catalogos.json#/definitions/c_UsoCFDI" + } + }, + "type": "object", + "definitions": {} +} diff --git a/packages/cfdi/schema/src/files/tdCFDI.xsd b/packages/cfdi/schema/src/files/tdCFDI.xsd new file mode 100644 index 00000000..86dd233f --- /dev/null +++ b/packages/cfdi/schema/src/files/tdCFDI.xsd @@ -0,0 +1,157 @@ + + + + + Tipo definido para expresar la Clave Única de Registro de Población (CURP) + + + + + + + + + + Tipo definido para expresar importes numéricos con fracción hasta seis decimales. No se permiten valores negativos. + + + + + + + + + + + Tipo definido para la expresión de la fecha. Se expresa en la forma AAAA-MM-DD. + + + + + + + + + Tipo definido para expresar importes monetarios en moneda nacional MXN con fracción hasta dos decimales. No se permiten valores negativos. + + + + + + + + + + + Tipo definido para expresar la cuenta bancarizada. + + + + + + + + + Tipo definido para expresar claves del Registro Federal de Contribuyentes + + + + + + + + + + + Tipo definido para la expresión de un Registro Federal de Contribuyentes de persona moral. + + + + + + + + + + Tipo definido para la expresión de un Registro Federal de Contribuyentes de persona física. + + + + + + + + + + Tipo definido para la expresión de la fecha y hora. Se expresa en la forma AAAA-MM-DDThh:mm:ss + + + + + + + + + Tipo definido para la expresión de la fecha y hora. Se expresa en la forma AAAA-MM-DDThh:mm:ss + + + + + + + + + Tipo definido para expresar la calle en que está ubicado el domicilio del emisor del comprobante o del destinatario de la mercancía. + + + + + + + + + + + Tipo definido para expresar el número interior o el número exterior en donde se ubica el domicilio del emisor del comprobante o del destinatario de la mercancía. + + + + + + + + + + + Tipo definido para expresar la referencia geográfica adicional que permita una fácil o precisa ubicación del domicilio del emisor del comprobante o del destinatario de la mercancía, por ejemplo las coordenadas GPS. + + + + + + + + + + + Tipo definido para expresar la colonia, localidad o municipio en que está ubicado el domicilio del emisor del comprobante o del destinatario de la mercancía. + + + + + + + + + + + Tipo definido para expresar el tipo de cambio. No se permiten valores negativos. + + + + + + + + + diff --git a/packages/cfdi/schema/src/index.ts b/packages/cfdi/schema/src/index.ts new file mode 100644 index 00000000..09943240 --- /dev/null +++ b/packages/cfdi/schema/src/index.ts @@ -0,0 +1,45 @@ +// Exportar clases principales +export { CfdiSchema } from './schema.xsd'; +export { CfdiSchema as default } from './schema.xsd'; +export { CfdiXsd } from './cfdi.xsd'; +export { CatalogProcess } from './catalogos.xsd'; + +// Exportar XSDLoader +export { + XSDLoader, + xsdLoader, + type LoaderOptions +} from './loader.xsd'; + +// Exportar clases base y utilidades +export { BaseXSDProcessor } from './common/base-processor'; +export { XMLUtils } from './common/xml-utils'; +export { XSD_CONSTANTS } from './common/constants'; + +// Exportar interfaces y tipos +export type { + ProcessorConfig, + ProcessingOptions, + ProcessingResult, + XSDGenerationConfig, + IXSDProcessor, + XMLElementOptions +} from './common/interfaces'; + +// Exportar tipos de constantes +export type { + XSDNamespaces, + SchemaLocations +} from './common/constants'; + +// Exportar factory y funciones de conveniencia +export { + ProcessorFactory, + createCfdiProcessor, + createCatalogProcessor, + processXSD +} from './common/processor-factory'; + + + + diff --git a/packages/cfdi/schema/src/loader.xsd.ts b/packages/cfdi/schema/src/loader.xsd.ts new file mode 100644 index 00000000..c9ccc553 --- /dev/null +++ b/packages/cfdi/schema/src/loader.xsd.ts @@ -0,0 +1,179 @@ +import { readFileSync, existsSync } from 'fs'; +import { join, isAbsolute, extname } from 'path'; +import { ElementCompact, xml2js } from 'xml-js'; + +export interface LoaderOptions { + source: string; // Ruta local o URL + encoding?: BufferEncoding; + timeout?: number; +} + +export class XSDLoader { + private static instance: XSDLoader; + + public static getInstance(): XSDLoader { + if (!XSDLoader.instance) { + XSDLoader.instance = new XSDLoader(); + } + return XSDLoader.instance; + } + + /** + * Determina si una fuente es una URL o una ruta local + */ + private isUrl(source: string): boolean { + try { + const url = new URL(source); + return url.protocol === 'http:' || url.protocol === 'https:'; + } catch { + return false; + } + } + + /** + * Valida si el archivo tiene extensión .xsd + */ + private isXsdFile(source: string): boolean { + if (this.isUrl(source)) { + // Para URLs, verificar que termine en .xsd + return source.toLowerCase().endsWith('.xsd'); + } else { + // Para rutas locales, verificar la extensión + return extname(source).toLowerCase() === '.xsd'; + } + } + + /** + * Carga el contenido del archivo desde una URL + */ + private async loadFromUrl(url: string, timeout: number = 10000): Promise { + try { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), timeout); + + const response = await fetch(url, { + signal: controller.signal, + headers: { + 'User-Agent': 'XSDLoader/1.0', + }, + }); + + clearTimeout(timeoutId); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status} - ${response.statusText}`); + } + + const content = await response.text(); + + if (!content.trim()) { + throw new Error('El archivo descargado está vacío'); + } + + return content; + } catch (error) { + if (error instanceof Error) { + if (error.name === 'AbortError') { + throw new Error(`Timeout al descargar el archivo desde ${url}`); + } + throw new Error(`Error descargando XSD desde ${url}: ${error.message}`); + } + throw error; + } + } + + /** + * Carga el contenido del archivo desde una ruta local + */ + private loadFromPath(filePath: string, encoding: BufferEncoding = 'utf-8'): string { + try { + // Verificar si el archivo existe + if (!existsSync(filePath)) { + throw new Error(`El archivo no existe: ${filePath}`); + } + + const content = readFileSync(filePath, encoding); + + if (!content.trim()) { + throw new Error('El archivo está vacío'); + } + + return content; + } catch (error) { + if (error instanceof Error) { + throw new Error(`Error leyendo archivo ${filePath}: ${error.message}`); + } + throw error; + } + } + + /** + * Carga y parsea un archivo XSD desde una URL o ruta local + */ + async loadXSD(options: LoaderOptions): Promise { + const { source, encoding = 'utf-8', timeout = 10000 } = options; + + // Validar que el archivo tenga extensión .xsd + if (!this.isXsdFile(source)) { + throw new Error(`El archivo debe tener extensión .xsd: ${source}`); + } + + let content: string; + + try { + if (this.isUrl(source)) { + //console.log(`Descargando XSD desde URL: ${source}`); + content = await this.loadFromUrl(source, timeout); + } else { + //console.log(`Cargando XSD desde archivo local: ${source}`); + content = this.loadFromPath(source, encoding); + } + + // Parsear el XML + const options = { + compact: true, + ignoreComment: true, + alwaysChildren: true, + }; + + const parsedXsd = xml2js(content, options) as ElementCompact; + + // Validar que sea un esquema XSD válido + if (!parsedXsd['xs:schema']) { + throw new Error('El archivo no es un esquema XSD válido (no contiene xs:schema)'); + } + + //console.log(`XSD cargado exitosamente desde: ${source}`); + return parsedXsd; + + } catch (error) { + if (error instanceof Error) { + throw new Error(`Error procesando XSD desde ${source}: ${error.message}`); + } + throw error; + } + } + + /** + * Carga múltiples archivos XSD + */ + async loadMultipleXSD(sources: LoaderOptions[]): Promise { + const promises = sources.map(options => this.loadXSD(options)); + + try { + return await Promise.all(promises); + } catch (error) { + throw new Error(`Error cargando múltiples archivos XSD: ${error}`); + } + } + + /** + * Utilidad para crear opciones de carga rápida + */ + static createOptions(source: string, encoding?: BufferEncoding, timeout?: number): LoaderOptions { + return { source, encoding, timeout }; + } +} + +// Instancia singleton para uso directo +export const xsdLoader = XSDLoader.getInstance(); \ No newline at end of file diff --git a/packages/cfdi/schema/src/schema.xsd.ts b/packages/cfdi/schema/src/schema.xsd.ts new file mode 100644 index 00000000..59a59f89 --- /dev/null +++ b/packages/cfdi/schema/src/schema.xsd.ts @@ -0,0 +1,173 @@ +import { ElementCompact, js2xml, json2xml, xml2js } from 'xml-js'; +import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'; + +import { CatalogProcess } from './catalogos.xsd'; +import { CfdiXsd } from './cfdi.xsd'; +import { STRUCTURE } from './common/const/structure'; +// @ts-ignore +import { Xsd2JsonSchema, ConverterDraft07 } from 'xsd2jsonschema'; +import { Complementos } from './complementos/complementos.process'; + +export class CfdiSchema { + private static instance: CfdiSchema; + private options = { + xsd: { + cfdi: '', + catalogos: '', + tipoDatos: '', + complementos: [], + }, + }; + private schemaName: any = { + catalogos: [], + comprobante: [], + complementos: [], + unknow: [], + }; + private xs2js: Xsd2JsonSchema; + private schemasJSON: Record = {}; + private schemas: { + name: string; + type: string; + schema: Record; + path: string; + key: string; + }[] = []; + private cfdiProcess: CfdiXsd; + private catalogProcess: CatalogProcess; + private complementos: Complementos; + + constructor() { + this.xs2js = new Xsd2JsonSchema(); + this.catalogProcess = CatalogProcess.of(); + this.cfdiProcess = CfdiXsd.of(); + this.complementos = Complementos.of(); + } + setConfig(options: any) { + this.options.xsd = options.xsd; + this.cfdiProcess.setConfig({ path: options.xsd.cfdi }); + this.catalogProcess.setConfig(options.xsd.catalogos); + this.complementos.setConfig({ path: options.xsd.complementos }); + } + + public static of(): CfdiSchema { + if (!CfdiSchema.instance) { + CfdiSchema.instance = new CfdiSchema(); + } + return CfdiSchema.instance; + } + + async processAll() { + this.schemaName = { + catalogos: [], + comprobante: [], + complementos: [], + unknow: [], + }; + this.schemas = []; + const catalog = await this.catalogProcess.process(); + const tiposDatos = await this.tipoDatos(); + const cfdi = await this.cfdiProcess.process(); + const complementos = await this.complementos.process(); + const extras = { + ...tiposDatos, + ...catalog, + // ...cfdi, + }; + + cfdi + .filter((c: any) => c.name !== 'unknow') + .forEach((c: any) => { + const res = this.generateSchema( + { + ...extras, + [c.key]: c.xsd, + }, + c + ); + const filter = res.filter((r) => { + const index = this.schemas.findIndex((s) => s.key === r.key); + return index === -1 && !!r.schema.properties; + }); + + this.schemas.push(...filter); + }); + + complementos.forEach((c: any) => { + const res = this.generateSchema( + { + // ...extras, + [c.key]: c.xsd, + }, + c + ); + this.schemas.push(...res); + }); + return { + schemas: this.schemas, + }; + } + + xsd2Json(schemasJSON: Record) { + const xs2js = new Xsd2JsonSchema({ + // jsonSchemaVersion: 'draft-07', + //converter: new ConverterDraft07() + //generateTitle: false + }); + + const convertedSchemas = xs2js.processAllSchemas({ + schemas: schemasJSON + }); + + return convertedSchemas; + } + + generateSchema(schemasJSON: Record, c: any) { + const convertedSchemas = this.xsd2Json(schemasJSON); + + return Object.keys(schemasJSON).map((key) => { + const d = STRUCTURE[c.name] ? 'comprobante' : 'catalogos'; + if (c.key !== key) { + console.log(key); + } + return { + name: c.key === key ? c.name : key, + key: c.key === key ? c.key : `catalogos_${key}`, + path: c.key === key ? c.folder || 'catalogos' : 'catalogos', + type: c.key === key ? c.type || 'comprobante' : 'catalogos', + schema: convertedSchemas[key].getJsonSchema(), + }; + }); + } + + async save(path: string) { + const cfdi = `${path}cfdi.json`; + + this.schemas.forEach((schema) => { + const name = schema.name.toLowerCase(); + const fileName = `${name}.json`; + const direction = `${path}${ + schema.path.toLocaleLowerCase() || 'catalogos' + }`; + const file = `${direction}/${fileName}`; + + this.schemaName[schema.type].push({ + name, + type: schema.type, + key: schema.key.toLocaleUpperCase(), + path: schema.path.toLocaleLowerCase() || 'catalogos', + }); + !existsSync(direction) && mkdirSync(direction); + if (!existsSync(file)) { + writeFileSync(file, JSON.stringify(schema.schema)); + } + }); + + writeFileSync(cfdi, JSON.stringify(this.schemaName)); + } + + tipoDatos() { + const tipoDatosXsd = readFileSync(this.options.xsd.tipoDatos, 'utf-8'); + return { tipoDatos: tipoDatosXsd }; + } +} diff --git a/packages/cfdi/schema/src/tipo-datos.xsd.ts b/packages/cfdi/schema/src/tipo-datos.xsd.ts new file mode 100644 index 00000000..7a864211 --- /dev/null +++ b/packages/cfdi/schema/src/tipo-datos.xsd.ts @@ -0,0 +1,36 @@ +import { readFileSync } from "fs"; + +export class TipoDatosXsd { + private static instance: TipoDatosXsd; + private options = { + source: '' + }; + private constructor() { + } + + public static of(): TipoDatosXsd { + if (!TipoDatosXsd.instance) { + TipoDatosXsd.instance = new TipoDatosXsd(); + } + return TipoDatosXsd.instance; + } + + setConfig({ source }: { source: string }) { + this.options.source = source; + } + + public async process() { + const tipoDatosXsd = await this.getXsd(); + return { tipoDatos: tipoDatosXsd }; + } + + public async getXsd() { + const xsd = await this.readXsd(); + return xsd; + } + + private async readXsd() { + const tipoDatosXsd = readFileSync(this.options.source, 'utf-8'); + return tipoDatosXsd; + } +} diff --git a/packages/cfdi/schema/src/utils/manager.ts b/packages/cfdi/schema/src/utils/manager.ts new file mode 100644 index 00000000..b07bc617 --- /dev/null +++ b/packages/cfdi/schema/src/utils/manager.ts @@ -0,0 +1,3 @@ +export function existsFile(filePath: string): boolean { + // return existsSync(`${this.route}${filePath}`); +} diff --git a/packages/cfdi/schema/src/utils/xsdElements.ts b/packages/cfdi/schema/src/utils/xsdElements.ts new file mode 100644 index 00000000..3ed42e93 --- /dev/null +++ b/packages/cfdi/schema/src/utils/xsdElements.ts @@ -0,0 +1,8 @@ +export const INFORMACION_GLOBAL = 'InformacionGlobal'; +export const CFDI_RELACIONADOS = 'CfdiRelacionados'; +export const EMISOR = 'Emisor'; +export const RECEPTOR = 'Receptor'; +export const CONCEPTOS = 'Conceptos'; +export const IMPUESTOS = 'Impuestos'; +export const COMPLEMENTO = 'Complemento'; +export const ADDENDA = 'Addenda'; diff --git a/packages/cfdi/schema/test/cfdi.config.xsd.test.ts b/packages/cfdi/schema/test/cfdi.config.xsd.test.ts new file mode 100644 index 00000000..7c436f7c --- /dev/null +++ b/packages/cfdi/schema/test/cfdi.config.xsd.test.ts @@ -0,0 +1,512 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { CfdiXsd } from '../src/cfdi.xsd'; +import path from 'path'; + +describe('CfdiXsd - Integration Tests', () => { + let cfdiXsd: CfdiXsd; + + // Ruta al archivo XSD real + const realXsdPath = path.join(__dirname, '../src/files/cfdv40.xsd'); + + beforeEach(() => { + cfdiXsd = CfdiXsd.of(); + }); + + describe('Singleton Pattern', () => { + it('should return the same instance when called multiple times', () => { + const instance1 = CfdiXsd.of(); + const instance2 = CfdiXsd.of(); + + expect(instance1).toBe(instance2); + expect(instance1).toBeInstanceOf(CfdiXsd); + }); + + it('should maintain state across instances', () => { + const instance1 = CfdiXsd.of(); + instance1.setConfig({ source: realXsdPath }); + + const instance2 = CfdiXsd.of(); + + expect(instance1).toBe(instance2); + // Ambas instancias deben tener la misma configuración + expect((instance2 as any).source).toBe(realXsdPath); + }); + }); + + describe('Configuration', () => { + it('should set configuration with source parameter', () => { + cfdiXsd.setConfig({ source: realXsdPath }); + + expect((cfdiXsd as any).source).toBe(realXsdPath); + }); + + it('should maintain backward compatibility with path parameter', () => { + cfdiXsd.setConfig({ path: realXsdPath }); + + expect((cfdiXsd as any).source).toBe(realXsdPath); + }); + + it('should prioritize source over path when both are provided', () => { + const testSource = realXsdPath; + const testPath = './other-path.xsd'; + + cfdiXsd.setConfig({ source: testSource, path: testPath }); + + expect((cfdiXsd as any).source).toBe(testSource); + }); + }); + + describe('Real XSD Processing', () => { + beforeEach(() => { + cfdiXsd.setConfig({ source: realXsdPath }); + }); + + it('should process real CFDI XSD successfully', async () => { + const result = await cfdiXsd.process(); + + expect(result).toBeDefined(); + expect(Array.isArray(result)).toBe(true); + expect(result.length).toBeGreaterThan(0); + + // Verificar que todos los elementos tienen la estructura esperada + result.forEach((element: any) => { + expect(element).toHaveProperty('name'); + expect(element).toHaveProperty('xsd'); + expect(typeof element.xsd).toBe('string'); + expect(element.xsd).toContain(' { + const result = await cfdiXsd.process(); + + expect(result).toBeDefined(); + expect(Array.isArray(result)).toBe(true); + expect(result.length).toBeGreaterThan(0); + + // El primer elemento debe ser comprobante + const firstElement = result[0]; + expect(firstElement).toEqual( + expect.objectContaining({ + name: 'comprobante', + path: 'comprobante', + key: 'comprobante', + folder: 'comprobante' + }) + ); + }); + + it('should process real CFDI elements correctly', async () => { + const result = await cfdiXsd.process(); + + // Buscar elementos específicos del CFDI real + const elementNames = result.map((element: any) => element.name); + + // Verificar que se procesan los elementos principales del CFDI + expect(elementNames).toContain('comprobante'); + + // Buscar elementos que deberían estar presentes en cfdv40.xsd + const hasExpectedElements = elementNames.some((name: string) => + ['InformacionGlobal', 'CfdiRelacionados', 'Emisor', 'Receptor', 'Conceptos'] + .some(expectedName => name.toLowerCase().includes(expectedName.toLowerCase())) + ); + + expect(hasExpectedElements).toBe(true); + }); + + it('should throw error when no source is configured', async () => { + const freshInstance = new (CfdiXsd as any)(); + + await expect(freshInstance.process()).rejects.toThrow( + 'Configuración inválida: se requiere source o path' + ); + }); + + it('should handle invalid file path', async () => { + cfdiXsd.setConfig({ source: './non-existent-file.xsd' }); + + await expect(cfdiXsd.process()).rejects.toThrow(); + }); + + it.only('should contain the correct elements', async () => { + const result = await cfdiXsd.process(); + const withoutXsd = result.map(({xsd, ...item}) => item); + const elementNames = result.map((element) => element.name); + + expect(result).toBeDefined(); + expect(result.length).toBeGreaterThan(0); + expect(elementNames).toContain('comprobante'); + expect(elementNames).toContain('InformacionGlobal'); + expect(elementNames).toContain('CfdiRelacionados'); + expect(elementNames).toContain('Emisor'); + expect(elementNames).toContain('Receptor'); + expect(elementNames).toContain('Conceptos'); + + expect(withoutXsd).toBeDefined(); + expect(withoutXsd).toEqual([ + { + name: 'comprobante', + path: 'comprobante', + key: 'comprobante', + folder: 'comprobante' + }, + { + name: 'InformacionGlobal', + folder: 'InformacionGlobal', + path: 'comprobante', + key: 'comprobante_InformacionGlobal' + }, + { + name: 'CfdiRelacionado', + folder: 'CfdiRelacionados', + path: 'comprobante_CfdiRelacionados', + key: 'comprobante_CfdiRelacionados_CfdiRelacionado' + }, + { + name: 'CfdiRelacionados', + folder: 'CfdiRelacionados', + path: 'comprobante', + key: 'comprobante_CfdiRelacionados' + }, + { + name: 'Emisor', + folder: 'Emisor', + path: 'comprobante', + key: 'comprobante_Emisor' + }, + { + name: 'Receptor', + folder: 'Receptor', + path: 'comprobante', + key: 'comprobante_Receptor' + }, + { + name: 'Traslado', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto_Impuestos_Traslados', + key: 'comprobante_Conceptos_Concepto_Impuestos_Traslados_Traslado' + }, + { + name: 'Traslados', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto_Impuestos', + key: 'comprobante_Conceptos_Concepto_Impuestos_Traslados' + }, + { + name: 'Retencion', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto_Impuestos_Retenciones', + key: 'comprobante_Conceptos_Concepto_Impuestos_Retenciones_Retencion' + }, + { + name: 'Retenciones', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto_Impuestos', + key: 'comprobante_Conceptos_Concepto_Impuestos_Retenciones' + }, + { + name: 'Impuestos', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto', + key: 'comprobante_Conceptos_Concepto_Impuestos' + }, + { + name: 'ACuentaTerceros', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto', + key: 'comprobante_Conceptos_Concepto_ACuentaTerceros' + }, + { + name: 'InformacionAduanera', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto', + key: 'comprobante_Conceptos_Concepto_InformacionAduanera' + }, + { + name: 'CuentaPredial', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto', + key: 'comprobante_Conceptos_Concepto_CuentaPredial' + }, + { + name: 'unknown', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto_ComplementoConcepto', + key: 'comprobante_Conceptos_Concepto_ComplementoConcepto_unknown' + }, + { + name: 'ComplementoConcepto', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto', + key: 'comprobante_Conceptos_Concepto_ComplementoConcepto' + }, + { + name: 'InformacionAduanera', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto_Parte', + key: 'comprobante_Conceptos_Concepto_Parte_InformacionAduanera' + }, + { + name: 'Parte', + folder: 'Conceptos', + path: 'comprobante_Conceptos_Concepto', + key: 'comprobante_Conceptos_Concepto_Parte' + }, + { + name: 'Concepto', + folder: 'Conceptos', + path: 'comprobante_Conceptos', + key: 'comprobante_Conceptos_Concepto' + }, + { + name: 'Conceptos', + folder: 'Conceptos', + path: 'comprobante', + key: 'comprobante_Conceptos' + }, + { + name: 'Retencion', + folder: 'Impuestos', + path: 'comprobante_Impuestos_Retenciones', + key: 'comprobante_Impuestos_Retenciones_Retencion' + }, + { + name: 'Retenciones', + folder: 'Impuestos', + path: 'comprobante_Impuestos', + key: 'comprobante_Impuestos_Retenciones' + }, + { + name: 'Traslado', + folder: 'Impuestos', + path: 'comprobante_Impuestos_Traslados', + key: 'comprobante_Impuestos_Traslados_Traslado' + }, + { + name: 'Traslados', + folder: 'Impuestos', + path: 'comprobante_Impuestos', + key: 'comprobante_Impuestos_Traslados' + }, + { + name: 'Impuestos', + folder: 'Impuestos', + path: 'comprobante', + key: 'comprobante_Impuestos' + }, + { + name: 'unknown', + folder: 'Complemento', + path: 'comprobante_Complemento', + key: 'comprobante_Complemento_unknown' + }, + { + name: 'Complemento', + folder: 'Complemento', + path: 'comprobante', + key: 'comprobante_Complemento' + }, + { + name: 'unknown', + folder: 'Addenda', + path: 'comprobante_Addenda', + key: 'comprobante_Addenda_unknown' + }, + { + name: 'Addenda', + folder: 'Addenda', + path: 'comprobante', + key: 'comprobante_Addenda' + } + ]) + }); + }); + + describe('Real Schema Analysis', () => { + beforeEach(() => { + cfdiXsd.setConfig({ source: realXsdPath }); + }); + + it('should extract all sequence elements from real XSD', async () => { + const result = await cfdiXsd.process(); + + expect(result).toBeDefined(); + expect(result.length).toBeGreaterThan(1); // Al menos comprobante + otros elementos + + // Verificar que cada elemento tiene la estructura correcta + result.forEach((element: any) => { + expect(element.name).toBeTruthy(); + expect(element.xsd).toBeTruthy(); + expect(typeof element.xsd).toBe('string'); + }); + }); + + it('should generate valid XSD for each extracted element', async () => { + const result = await cfdiXsd.process(); + + result.forEach((element: any) => { + // Cada XSD debe contener la estructura básica + expect(element.xsd).toContain(''); + }); + }); + + it('should preserve namespaces in generated XSD', async () => { + const result = await cfdiXsd.process(); + + const firstElement = result[0]; + const xsdContent = firstElement.xsd; + + // Verificar que se mantienen los namespaces importantes + expect(xsdContent).toContain('xmlns:cfdi="http://www.sat.gob.mx/cfd/4"'); + expect(xsdContent).toContain('xmlns:xs="http://www.w3.org/2001/XMLSchema"'); + }); + }); + + describe('Utility Methods with Real Data', () => { + beforeEach(() => { + cfdiXsd.setConfig({ source: realXsdPath }); + }); + + it('should generate schemas map from real processed data', async () => { + const processedSchemas = await cfdiXsd.process(); + + const schemasMap = cfdiXsd.generateSchemas(processedSchemas); + + expect(schemasMap).toBeDefined(); + expect(typeof schemasMap).toBe('object'); + expect(schemasMap['comprobante']).toBeDefined(); + + // Verificar que el mapa tiene las claves correctas + Object.keys(schemasMap).forEach(key => { + expect(typeof schemasMap[key]).toBe('string'); + expect(schemasMap[key]).toContain(' { + // Test con elemento que solo tiene atributos + const attributeOnlyElement = { + 'xs:complexType': { + 'xs:attribute': { name: 'test' } + } + }; + + const isOnlyAttr = cfdiXsd.isOnlyAttribute(attributeOnlyElement); + expect(typeof isOnlyAttr).toBe('boolean'); + + // Test con elemento que tiene secuencias + const sequenceElement = { + 'xs:complexType': { + 'xs:sequence': { + 'xs:element': { name: 'child' } + }, + 'xs:attribute': { name: 'attr' } + } + }; + + const hasSequence = cfdiXsd.isOnlyAttribute(sequenceElement); + expect(typeof hasSequence).toBe('boolean'); + }); + }); + + describe('Integration with Base Processor', () => { + it('should inherit readXsd method from BaseXSDProcessor', async () => { + cfdiXsd.setConfig({ source: realXsdPath }); + + const xsdData = await cfdiXsd.readXsd(); + + expect(xsdData).toBeDefined(); + expect(xsdData['xs:schema']).toBeDefined(); + expect(xsdData['xs:schema']['xs:element']).toBeDefined(); + }); + + it('should inherit validateConfig method from BaseXSDProcessor', async () => { + // Test sin configuración + const freshInstance = new (CfdiXsd as any)(); + + await expect(freshInstance.process()).rejects.toThrow(); + }); + + it('should load real XSD and validate schema structure', async () => { + cfdiXsd.setConfig({ source: realXsdPath }); + + const xsdData = await cfdiXsd.readXsd(); + + // Verificar estructura del esquema real + expect(xsdData['xs:schema']).toBeDefined(); + expect(xsdData['xs:schema']['_attributes']).toBeDefined(); + expect(xsdData['xs:schema']['_attributes']['targetNamespace']).toBe('http://www.sat.gob.mx/cfd/4'); + + // Verificar que existe el elemento Comprobante + expect(xsdData['xs:schema']['xs:element']).toBeDefined(); + expect(xsdData['xs:schema']['xs:element']['_attributes']['name']).toBe('Comprobante'); + }); + }); + + describe('Performance and Validation', () => { + it('should process real XSD within reasonable time', async () => { + cfdiXsd.setConfig({ source: realXsdPath }); + + const startTime = Date.now(); + const result = await cfdiXsd.process(); + const endTime = Date.now(); + + expect(result).toBeDefined(); + expect(endTime - startTime).toBeLessThan(5000); // Menos de 5 segundos + }); + + it('should generate consistent output on multiple runs', async () => { + cfdiXsd.setConfig({ source: realXsdPath }); + + const result1 = await cfdiXsd.process(); + const result2 = await cfdiXsd.process(); + + expect(result1.length).toBe(result2.length); + + // Verificar que los nombres son consistentes + const names1 = result1.map((r: any) => r.name).sort(); + const names2 = result2.map((r: any) => r.name).sort(); + expect(names1).toEqual(names2); + }); + }); + + describe('Error Handling with Real Files', () => { + it('should handle non-existent files gracefully', async () => { + cfdiXsd.setConfig({ source: './non-existent-file.xsd' }); + + await expect(cfdiXsd.process()).rejects.toThrow(); + }); + + it('should handle invalid file types', async () => { + // Usar un archivo que no es XSD + const invalidPath = path.join(__dirname, '../package.json'); + cfdiXsd.setConfig({ source: invalidPath }); + + await expect(cfdiXsd.process()).rejects.toThrow(); + }); + + it('should handle files without .xsd extension', async () => { + cfdiXsd.setConfig({ source: './some-file.txt' }); + + await expect(cfdiXsd.process()).rejects.toThrow('El archivo debe tener extensión .xsd'); + }); + }); + + describe('Memory Management', () => { + it('should not create memory leaks with multiple instances', () => { + const instances: CfdiXsd[] = []; + + for (let i = 0; i < 100; i++) { + instances.push(CfdiXsd.of()); + } + + // Todos deben ser la misma instancia + const firstInstance = instances[0]; + instances.forEach(instance => { + expect(instance).toBe(firstInstance); + }); + }); + }); +}); diff --git a/packages/cfdi/schema/test/comprobante/cfdi-relacionados.xsd.test.ts b/packages/cfdi/schema/test/comprobante/cfdi-relacionados.xsd.test.ts new file mode 100644 index 00000000..c912c2e8 --- /dev/null +++ b/packages/cfdi/schema/test/comprobante/cfdi-relacionados.xsd.test.ts @@ -0,0 +1,227 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { CfdiXsd, XsdElement } from '../../src/cfdi.xsd'; +import path from 'path'; +import { XMLUtils } from '../../src/common/xml-utils'; +import { CatalogProcess } from '../../src/catalogos.xsd'; +import { TipoDatosXsd } from '../../src/tipo-datos.xsd'; +import { CfdiSchema } from '../../src/schema.xsd'; +import { + CATALOGOS_NAMESPACE, + CATALOGOS_SCHEMA_LOCATION, + TIPO_DATOS_NAMESPACE, + TIPO_DATOS_SCHEMA_LOCATION, +} from '../shared'; + +describe('CfdiXsd - CfdiRelacionados Integration Tests', () => { + let cfdiXsd: CfdiXsd; + let catalogProcess: CatalogProcess; + let tipoDatosXsd: TipoDatosXsd; + let cfdiSchema: CfdiSchema; + // Ruta al archivo XSD real + const realXsdPath = path.join(__dirname, '../../src/files/cfdv40.xsd'); + const tipoDatosXsdPath = path.join(__dirname, '../../src/files/tdCFDI.xsd'); + const catalogosXsdPath = path.join(__dirname, '../../src/files/catCFDI.xsd'); + + beforeEach(() => { + cfdiXsd = CfdiXsd.of(); + catalogProcess = CatalogProcess.of(); + tipoDatosXsd = TipoDatosXsd.of(); + cfdiSchema = CfdiSchema.of(); + cfdiXsd.setConfig({ source: realXsdPath }); + catalogProcess.setConfig({ source: catalogosXsdPath }); + tipoDatosXsd.setConfig({ source: tipoDatosXsdPath }); + }); + + describe('XSD CfdiRelacionados', () => { + it('should get the XSD CfdiRelacionados', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'CfdiRelacionados' + )) as XsdElement; + + const xsd = result?.xsd; + + // Validar estructura del objeto XSD + expect(xsd).toBeDefined(); + + // Verificar estructura básica del schema + expect(xsd['xs:schema']).toBeDefined(); + expect(xsd['xs:schema']['_attributes']).toBeDefined(); + + // Verificar namespaces y atributos del schema + const schemaAttrs = xsd['xs:schema']['_attributes']; + expect(schemaAttrs['xmlns:cfdi']).toBe('http://www.sat.gob.mx/cfd/4'); + expect(schemaAttrs['xmlns:xs']).toBe('http://www.w3.org/2001/XMLSchema'); + expect(schemaAttrs['xmlns:catCFDI']).toBe( + 'http://www.sat.gob.mx/sitio_internet/cfd/catalogos' + ); + expect(schemaAttrs['xmlns:tdCFDI']).toBe( + 'http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI' + ); + expect(schemaAttrs['targetNamespace']).toBe( + 'http://www.sat.gob.mx/cfd/4' + ); + expect(schemaAttrs['elementFormDefault']).toBe('qualified'); + expect(schemaAttrs['attributeFormDefault']).toBe('unqualified'); + + // Verificar imports + expect(xsd['xs:schema']['xs:import']).toBeDefined(); + expect(Array.isArray(xsd['xs:schema']['xs:import'])).toBe(true); + expect(xsd['xs:schema']['xs:import']).toHaveLength(2); + expect(xsd['xs:schema']['xs:import']).toContainEqual({ + _attributes: { + namespace: CATALOGOS_NAMESPACE, + schemaLocation: CATALOGOS_SCHEMA_LOCATION, + }, + }); + expect(xsd['xs:schema']['xs:import']).toContainEqual({ + _attributes: { + namespace: TIPO_DATOS_NAMESPACE, + schemaLocation: TIPO_DATOS_SCHEMA_LOCATION, + }, + }); + + // Verificar elemento CfdiRelacionados + expect(xsd['xs:schema']['xs:element']).toBeDefined(); + expect(xsd['xs:schema']['xs:element']['_attributes']).toEqual({ + maxOccurs: 'unbounded', + minOccurs: '0', + name: 'CfdiRelacionados', + }); + + // Verificar complexType + expect(xsd['xs:schema']['xs:element']['xs:complexType']).toBeDefined(); + + }); + it('should get the JsonSchema CfdiRelacionados', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'CfdiRelacionados' + )) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + CfdiRelacionados: XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['CfdiRelacionados'].getJsonSchema(); + + expect(jsonSchema).toBeDefined(); + expect(jsonSchema.type).toBe('object'); + + // Verificar propiedades que no cambian + expect(jsonSchema.$id).toBe('CfdiRelacionados.json'); + expect(jsonSchema.$schema).toBe( + 'http://json-schema.org/draft-07/schema#' + ); + + // Usar regex para el title que contiene timestamp + expect(jsonSchema.title).toMatch( + /^This JSON Schema file was generated from CfdiRelacionados on .*\. For more information please see http:\/\/www\.xsd2jsonschema\.org$/ + ); + + // Verificar required array para CfdiRelacionados + expect(jsonSchema.required).toContain('TipoRelacion'); + + // Verificar que properties existe y tiene las propiedades esperadas + expect(jsonSchema.properties).toBeDefined(); + expect(jsonSchema.properties).toEqual({ + "TipoRelacion": { + "$ref": "catalogos.json#/definitions/c_TipoRelacion" + } + }); + + + }); + }); + + describe('XSD CfdiRelacionado', () => { + it('should get the XSD CfdiRelacionado', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'CfdiRelacionado' + )) as XsdElement; + + const xsd = result?.xsd; + + // Validar estructura del objeto XSD + expect(xsd).toBeDefined(); + + // Verificar estructura básica del schema + expect(xsd['xs:schema']).toBeDefined(); + expect(xsd['xs:schema']['_attributes']).toBeDefined(); + + // Verificar elemento CfdiRelacionado + expect(xsd['xs:schema']['xs:element']).toBeDefined(); + expect(xsd['xs:schema']['xs:element']['_attributes']).toEqual({ + maxOccurs: 'unbounded', + name: 'CfdiRelacionado', + }); + + // Verificar complexType y sus atributos + expect(xsd['xs:schema']['xs:element']['xs:complexType']).toBeDefined(); + + // Verificar atributos del complexType + const attributes = + xsd['xs:schema']['xs:element']['xs:complexType']['xs:attribute']; + + // CfdiRelacionado debe tener el atributo UUID + + }); + + it('should get the JsonSchema CfdiRelacionado', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'CfdiRelacionado' + )) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + CfdiRelacionado: XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['CfdiRelacionado'].getJsonSchema(); + + expect(jsonSchema).toBeDefined(); + expect(jsonSchema.type).toBe('object'); + + // Verificar propiedades que no cambian + expect(jsonSchema.$id).toBe('CfdiRelacionado.json'); + expect(jsonSchema.$schema).toBe( + 'http://json-schema.org/draft-07/schema#' + ); + + // Usar regex para el title que contiene timestamp + expect(jsonSchema.title).toMatch( + /^This JSON Schema file was generated from CfdiRelacionado on .*\. For more information please see http:\/\/www\.xsd2jsonschema\.org$/ + ); + + // Verificar required array para CfdiRelacionado + expect(jsonSchema.required).toContain('UUID'); + + // Verificar que properties existe y tiene las propiedades esperadas + expect(jsonSchema.properties).toBeDefined(); + expect(jsonSchema.properties).toEqual({ + "UUID": { + "description": "Atributo requerido para registrar el folio fiscal (UUID) de un CFDI relacionado con el presente comprobante, por ejemplo: Si el CFDI relacionado es un comprobante de traslado que sirve para registrar el movimiento de la mercancía. Si este comprobante se usa como nota de crédito o nota de débito del comprobante relacionado. Si este comprobante es una devolución sobre el comprobante relacionado. Si éste sustituye a una factura cancelada.", + "maxLength": 36, + "minLength": 36, + "pattern": "[a-f0-9A-F]{8}-[a-f0-9A-F]{4}-[a-f0-9A-F]{4}-[a-f0-9A-F]{4}-[a-f0-9A-F]{12}", + "type": "string" + } + }); + + + }); + }); +}); diff --git a/packages/cfdi/schema/test/comprobante/comprobante.xsd.test.ts b/packages/cfdi/schema/test/comprobante/comprobante.xsd.test.ts new file mode 100644 index 00000000..387f0c7c --- /dev/null +++ b/packages/cfdi/schema/test/comprobante/comprobante.xsd.test.ts @@ -0,0 +1,249 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { CfdiXsd, XsdElement } from '../../src/cfdi.xsd'; +import path from 'path'; +import { XMLUtils } from '../../src/common/xml-utils'; +import { CatalogProcess } from '../../src/catalogos.xsd'; +import { TipoDatosXsd } from '../../src/tipo-datos.xsd'; +import { CfdiSchema } from '../../src/schema.xsd'; + +describe('CfdiXsd - Integration Tests', () => { + let cfdiXsd: CfdiXsd; + let catalogProcess: CatalogProcess; + let tipoDatosXsd: TipoDatosXsd; + let cfdiSchema: CfdiSchema; + // Ruta al archivo XSD real + const realXsdPath = path.join(__dirname, '../../src/files/cfdv40.xsd'); + const tipoDatosXsdPath = path.join(__dirname, '../../src/files/tdCFDI.xsd'); + const catalogosXsdPath = path.join(__dirname, '../../src/files/catCFDI.xsd'); + + beforeEach(() => { + cfdiXsd = CfdiXsd.of(); + catalogProcess = CatalogProcess.of(); + tipoDatosXsd = TipoDatosXsd.of(); + cfdiSchema = CfdiSchema.of(); + }); + + describe('XSD', () => { + it('should get the XSD comprobante', async () => { + cfdiXsd.setConfig({ source: realXsdPath }); + catalogProcess.setConfig({ source: catalogosXsdPath }); + tipoDatosXsd.setConfig({ source: tipoDatosXsdPath }); + + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante' + )) as XsdElement; + + const xsd = result?.xsd + + console.log(JSON.stringify(xsd, null, 2)); + // Validar estructura del objeto XSD + expect(xsd).toBeDefined(); + + // Verificar estructura básica del schema + expect(xsd['xs:schema']).toBeDefined(); + expect(xsd['xs:schema']['_attributes']).toBeDefined(); + + // Verificar namespaces y atributos del schema + const schemaAttrs = xsd['xs:schema']['_attributes']; + expect(schemaAttrs['xmlns:cfdi']).toBe('http://www.sat.gob.mx/cfd/4'); + expect(schemaAttrs['xmlns:xs']).toBe('http://www.w3.org/2001/XMLSchema'); + expect(schemaAttrs['xmlns:catCFDI']).toBe('http://www.sat.gob.mx/sitio_internet/cfd/catalogos'); + expect(schemaAttrs['xmlns:tdCFDI']).toBe('http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI'); + expect(schemaAttrs['targetNamespace']).toBe('http://www.sat.gob.mx/cfd/4'); + expect(schemaAttrs['elementFormDefault']).toBe('qualified'); + expect(schemaAttrs['attributeFormDefault']).toBe('unqualified'); + + // Verificar imports + expect(xsd['xs:schema']['xs:import']).toBeDefined(); + expect(Array.isArray(xsd['xs:schema']['xs:import'])).toBe(true); + expect(xsd['xs:schema']['xs:import']).toHaveLength(2); + + // Verificar elemento Comprobante + expect(xsd['xs:schema']['xs:element']).toBeDefined(); + expect(xsd['xs:schema']['xs:element']['_attributes']['name']).toBe('Comprobante'); + + // Verificar annotation del elemento + expect(xsd['xs:schema']['xs:element']['xs:annotation']).toBeDefined(); + + // Verificar complexType + expect(xsd['xs:schema']['xs:element']['xs:complexType']).toBeDefined(); + + // Verificar atributos del complexType + const attributes = xsd['xs:schema']['xs:element']['xs:complexType']['xs:attribute']; + expect(Array.isArray(attributes)).toBe(true); + expect(attributes.length).toBeGreaterThan(10); // Debe tener varios atributos + + // Verificar algunos atributos específicos + const attributeNames = attributes.map((attr: any) => attr._attributes.name); + expect(attributeNames).toContain('Version'); + expect(attributeNames).toContain('Fecha'); + expect(attributeNames).toContain('Sello'); + expect(attributeNames).toContain('SubTotal'); + expect(attributeNames).toContain('Total'); + expect(attributeNames).toContain('TipoDeComprobante'); + expect(attributeNames).toContain('Exportacion'); + expect(attributeNames).toContain('LugarExpedicion'); + + // Verificar estructura de un atributo específico (Version) + const versionAttr = attributes.find((attr: any) => attr._attributes.name === 'Version'); + expect(versionAttr).toBeDefined(); + expect(versionAttr._attributes.use).toBe('required'); + expect(versionAttr._attributes.fixed).toBe('4.0'); + expect(versionAttr['xs:annotation']).toBeDefined(); + expect(versionAttr['xs:simpleType']).toBeDefined(); + + console.log('✅ XSD object validation passed!'); + console.log('Found attributes:', attributeNames); + + }); + }); + + describe('JsonSchema', () => { + it('should get the JsonSchema comprobante', async () => { + cfdiXsd.setConfig({ source: realXsdPath }); + catalogProcess.setConfig({ source: catalogosXsdPath }); + tipoDatosXsd.setConfig({ source: tipoDatosXsdPath }); + + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante' + )) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + comprobante: XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['comprobante'].getJsonSchema(); + + expect(jsonSchema.type).toBe('object'); + + expect(jsonSchema.$id).toBe('comprobante.json'); + expect(jsonSchema.$schema).toBe( + 'http://json-schema.org/draft-07/schema#' + ); + expect(jsonSchema.title).toMatch( + /^This JSON Schema file was generated from comprobante on .*\. For more information please see http:\/\/www\.xsd2jsonschema\.org$/ + ); + expect(jsonSchema.description).toBe( + 'Atributo requerido para incorporar el código postal del lugar de expedición del comprobante (domicilio de la matriz o de la sucursal).' + ); + + // Verificar required array + expect(jsonSchema.required).toEqual([ + 'Version', + 'Fecha', + 'Sello', + 'NoCertificado', + 'Certificado', + 'SubTotal', + 'Moneda', + 'Total', + 'TipoDeComprobante', + 'Exportacion', + 'LugarExpedicion', + ]); + + expect(jsonSchema.properties).toEqual({ + Version: { + description: + 'Atributo requerido con valor prefijado a 4.0 que indica la versión del estándar bajo el que se encuentra expresado el comprobante.', + type: 'string', + }, + Serie: { + description: + 'Atributo opcional para precisar la serie para control interno del contribuyente. Este atributo acepta una cadena de caracteres.', + maxLength: 25, + minLength: 1, + pattern: '[^|]{1,25}', + type: 'string', + }, + Folio: { + description: + 'Atributo opcional para control interno del contribuyente que expresa el folio del comprobante, acepta una cadena de caracteres.', + maxLength: 40, + minLength: 1, + pattern: '[^|]{1,40}', + type: 'string', + }, + Fecha: { + $ref: 'tipoDatos.json#/definitions/t_FechaH', + }, + Sello: { + description: + 'Atributo requerido para contener el sello digital del comprobante fiscal, al que hacen referencia las reglas de resolución miscelánea vigente. El sello debe ser expresado como una cadena de texto en formato Base 64.', + type: 'string', + }, + FormaPago: { + $ref: 'catalogos.json#/definitions/c_FormaPago', + }, + NoCertificado: { + description: + 'Atributo requerido para expresar el número de serie del certificado de sello digital que ampara al comprobante, de acuerdo con el acuse correspondiente a 20 posiciones otorgado por el sistema del SAT.', + maxLength: 20, + minLength: 20, + pattern: '[0-9]{20}', + type: 'string', + }, + Certificado: { + description: + 'Atributo requerido que sirve para incorporar el certificado de sello digital que ampara al comprobante, como texto en formato base 64.', + type: 'string', + }, + CondicionesDePago: { + description: + 'Atributo condicional para expresar las condiciones comerciales aplicables para el pago del comprobante fiscal digital por Internet. Este atributo puede ser condicionado mediante atributos o complementos.', + maxLength: 1000, + minLength: 1, + pattern: '[^|]{1,1000}', + type: 'string', + }, + SubTotal: { + $ref: 'tipoDatos.json#/definitions/t_Importe', + }, + Descuento: { + $ref: 'tipoDatos.json#/definitions/t_Importe', + }, + Moneda: { + $ref: 'catalogos.json#/definitions/c_Moneda', + }, + TipoCambio: { + description: + 'Atributo condicional para representar el tipo de cambio FIX conforme con la moneda usada. Es requerido cuando la clave de moneda es distinta de MXN y de XXX. El valor debe reflejar el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo moneda. Si el valor está fuera del porcentaje aplicable a la moneda tomado del catálogo c_Moneda, el emisor debe obtener del PAC que vaya a timbrar el CFDI, de manera no automática, una clave de confirmación para ratificar que el valor es correcto e integrar dicha clave en el atributo Confirmacion.', + minimum: 0.000001, + type: 'number', + }, + Total: { + $ref: 'tipoDatos.json#/definitions/t_Importe', + }, + TipoDeComprobante: { + $ref: 'catalogos.json#/definitions/c_TipoDeComprobante', + }, + Exportacion: { + $ref: 'catalogos.json#/definitions/c_Exportacion', + }, + MetodoPago: { + $ref: 'catalogos.json#/definitions/c_MetodoPago', + }, + LugarExpedicion: { + $ref: 'catalogos.json#/definitions/c_CodigoPostal', + }, + Confirmacion: { + description: + 'Atributo condicional para registrar la clave de confirmación que entregue el PAC para expedir el comprobante con importes grandes, con un tipo de cambio fuera del rango establecido o con ambos casos. Es requerido cuando se registra un tipo de cambio o un total fuera del rango establecido.', + maxLength: 5, + minLength: 5, + pattern: '[0-9a-zA-Z]{5}', + type: 'string', + }, + }); + //console.log(JSON.stringify(res['comprobante'].getJsonSchema(), null, 2)); + }); + }); +}); diff --git a/packages/cfdi/schema/test/comprobante/emisor.xsd.test.ts b/packages/cfdi/schema/test/comprobante/emisor.xsd.test.ts new file mode 100644 index 00000000..1276e27c --- /dev/null +++ b/packages/cfdi/schema/test/comprobante/emisor.xsd.test.ts @@ -0,0 +1,116 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { CfdiXsd, XsdElement } from '../../src/cfdi.xsd'; +import path from 'path'; +import { XMLUtils } from '../../src/common/xml-utils'; +import { CatalogProcess } from '../../src/catalogos.xsd'; +import { TipoDatosXsd } from '../../src/tipo-datos.xsd'; +import { CfdiSchema } from '../../src/schema.xsd'; +import { + CATALOGOS_NAMESPACE, + CATALOGOS_SCHEMA_LOCATION, + TIPO_DATOS_NAMESPACE, + TIPO_DATOS_SCHEMA_LOCATION, +} from '../shared'; + +describe('CfdiXsd - Integration Tests', () => { + let cfdiXsd: CfdiXsd; + let catalogProcess: CatalogProcess; + let tipoDatosXsd: TipoDatosXsd; + let cfdiSchema: CfdiSchema; + // Ruta al archivo XSD real + const realXsdPath = path.join(__dirname, '../../src/files/cfdv40.xsd'); + const tipoDatosXsdPath = path.join(__dirname, '../../src/files/tdCFDI.xsd'); + const catalogosXsdPath = path.join(__dirname, '../../src/files/catCFDI.xsd'); + + beforeEach(() => { + cfdiXsd = CfdiXsd.of(); + catalogProcess = CatalogProcess.of(); + tipoDatosXsd = TipoDatosXsd.of(); + cfdiSchema = CfdiSchema.of(); + cfdiXsd.setConfig({ source: realXsdPath }); + catalogProcess.setConfig({ source: catalogosXsdPath }); + tipoDatosXsd.setConfig({ source: tipoDatosXsdPath }); + }); + + describe('XSD', () => { + it('should get the XSD comprobante', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement('Emisor')) as XsdElement; + + const xsd = result?.xsd; + + expect(xsd).toBeDefined(); + expect(xsd['xs:schema']['xs:import']).toBeDefined(); + expect(Array.isArray(xsd['xs:schema']['xs:import'])).toBe(true); + expect(xsd['xs:schema']['xs:import']).toHaveLength(2); + expect(xsd['xs:schema']['xs:import']).toContainEqual({ + _attributes: { + namespace: CATALOGOS_NAMESPACE, + schemaLocation: CATALOGOS_SCHEMA_LOCATION, + }, + }); + expect(xsd['xs:schema']['xs:import']).toContainEqual({ + _attributes: { + namespace: TIPO_DATOS_NAMESPACE, + schemaLocation: TIPO_DATOS_SCHEMA_LOCATION, + }, + }); + expect(xsd['xs:schema']['xs:element']['_attributes']).toEqual({ + name: 'Emisor', + }); + + expect( + xsd['xs:schema']['xs:element']['xs:complexType']['xs:attribute'] + ).toHaveLength(4); + + }); + }); + + describe('JsonSchema', () => { + it('should get the JsonSchema comprobante', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement('Emisor')) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + Emisor: XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['Emisor'].getJsonSchema(); + + expect(jsonSchema).toBeDefined(); + expect(jsonSchema.type).toBe('object'); + + expect(jsonSchema.required).toEqual(['Rfc', 'Nombre', 'RegimenFiscal']); + expect(jsonSchema.properties).toEqual({ + Rfc: { + $ref: 'tipoDatos.json#/definitions/t_RFC', + }, + Nombre: { + description: + 'Atributo requerido para registrar el nombre, denominación o razón social del contribuyente inscrito en el RFC, del emisor del comprobante.', + maxLength: 300, + minLength: 1, + pattern: '[^|]{1,300}', + type: 'string', + }, + RegimenFiscal: { + $ref: 'catalogos.json#/definitions/c_RegimenFiscal', + }, + FacAtrAdquirente: { + description: + 'Atributo condicional para expresar el número de operación proporcionado por el SAT cuando se trate de un comprobante a través de un PCECFDI o un PCGCFDISP.', + maxLength: 10, + minLength: 10, + pattern: '[0-9]{10}', + type: 'string', + }, + }); + }); + }); +}); diff --git a/packages/cfdi/schema/test/comprobante/impuestos.xsd.test.ts b/packages/cfdi/schema/test/comprobante/impuestos.xsd.test.ts new file mode 100644 index 00000000..45000c17 --- /dev/null +++ b/packages/cfdi/schema/test/comprobante/impuestos.xsd.test.ts @@ -0,0 +1,431 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { CfdiXsd, XsdElement } from '../../src/cfdi.xsd'; +import path from 'path'; +import { XMLUtils } from '../../src/common/xml-utils'; +import { CatalogProcess } from '../../src/catalogos.xsd'; +import { TipoDatosXsd } from '../../src/tipo-datos.xsd'; +import { CfdiSchema } from '../../src/schema.xsd'; +import { + CATALOGOS_NAMESPACE, + CATALOGOS_SCHEMA_LOCATION, + TIPO_DATOS_NAMESPACE, + TIPO_DATOS_SCHEMA_LOCATION, +} from '../shared'; + +describe('CfdiXsd - Impuestos Integration Tests', () => { + let cfdiXsd: CfdiXsd; + let catalogProcess: CatalogProcess; + let tipoDatosXsd: TipoDatosXsd; + let cfdiSchema: CfdiSchema; + // Ruta al archivo XSD real + const realXsdPath = path.join(__dirname, '../../src/files/cfdv40.xsd'); + const tipoDatosXsdPath = path.join(__dirname, '../../src/files/tdCFDI.xsd'); + const catalogosXsdPath = path.join(__dirname, '../../src/files/catCFDI.xsd'); + + beforeEach(() => { + cfdiXsd = CfdiXsd.of(); + catalogProcess = CatalogProcess.of(); + tipoDatosXsd = TipoDatosXsd.of(); + cfdiSchema = CfdiSchema.of(); + cfdiXsd.setConfig({ source: realXsdPath }); + catalogProcess.setConfig({ source: catalogosXsdPath }); + tipoDatosXsd.setConfig({ source: tipoDatosXsdPath }); + }); + + describe('XSD Impuestos', () => { + it('should get the XSD Impuestos', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante_Impuestos', + 'key' + )) as XsdElement; + + const xsd = result?.xsd; + // Validar estructura del objeto XSD + expect(xsd).toBeDefined(); + + // Verificar estructura básica del schema + expect(xsd['xs:schema']).toBeDefined(); + expect(xsd['xs:schema']['_attributes']).toBeDefined(); + + // Verificar namespaces y atributos del schema + const schemaAttrs = xsd['xs:schema']['_attributes']; + expect(schemaAttrs['xmlns:cfdi']).toBe('http://www.sat.gob.mx/cfd/4'); + expect(schemaAttrs['xmlns:xs']).toBe('http://www.w3.org/2001/XMLSchema'); + expect(schemaAttrs['xmlns:catCFDI']).toBe( + 'http://www.sat.gob.mx/sitio_internet/cfd/catalogos' + ); + expect(schemaAttrs['xmlns:tdCFDI']).toBe( + 'http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI' + ); + expect(schemaAttrs['targetNamespace']).toBe( + 'http://www.sat.gob.mx/cfd/4' + ); + expect(schemaAttrs['elementFormDefault']).toBe('qualified'); + expect(schemaAttrs['attributeFormDefault']).toBe('unqualified'); + + // Verificar imports + expect(xsd['xs:schema']['xs:import']).toBeDefined(); + expect(Array.isArray(xsd['xs:schema']['xs:import'])).toBe(true); + expect(xsd['xs:schema']['xs:import']).toHaveLength(2); + expect(xsd['xs:schema']['xs:import']).toContainEqual({ + _attributes: { + namespace: CATALOGOS_NAMESPACE, + schemaLocation: CATALOGOS_SCHEMA_LOCATION, + }, + }); + expect(xsd['xs:schema']['xs:import']).toContainEqual({ + _attributes: { + namespace: TIPO_DATOS_NAMESPACE, + schemaLocation: TIPO_DATOS_SCHEMA_LOCATION, + }, + }); + + // Verificar elemento Impuestos + expect(xsd['xs:schema']['xs:element']).toBeDefined(); + expect(xsd['xs:schema']['xs:element']['_attributes']).toEqual( + expect.objectContaining({ + name: 'Impuestos', + }) + ); + + // Verificar complexType + expect(xsd['xs:schema']['xs:element']['xs:complexType']).toBeDefined(); + }); + + it('should get the JsonSchema Impuestos', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante_Impuestos', + 'key' + )) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + Impuestos: XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['Impuestos'].getJsonSchema(); + expect(jsonSchema).toBeDefined(); + expect(jsonSchema.type).toBe('object'); + + // Verificar propiedades que no cambian + expect(jsonSchema.$id).toBe('Impuestos.json'); + expect(jsonSchema.$schema).toBe( + 'http://json-schema.org/draft-07/schema#' + ); + + // Usar regex para el title que contiene timestamp + expect(jsonSchema.title).toMatch( + /^This JSON Schema file was generated from Impuestos on .*\. For more information please see http:\/\/www\.xsd2jsonschema\.org$/ + ); + + // Verificar que properties existe + expect(jsonSchema.properties).toBeDefined(); + + // Impuestos puede tener TotalImpuestosRetenidos y TotalImpuestosTrasladados + if (jsonSchema.properties.TotalImpuestosRetenidos) { + expect(jsonSchema.properties.TotalImpuestosRetenidos.$ref).toContain( + 'tipoDatos.json#/definitions/t_Importe' + ); + } + if (jsonSchema.properties.TotalImpuestosTrasladados) { + expect(jsonSchema.properties.TotalImpuestosTrasladados.$ref).toContain( + 'tipoDatos.json#/definitions/t_Importe' + ); + } + }); + }); + + describe('XSD Retenciones', () => { + it('should get the XSD Retenciones', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante_Impuestos_Retenciones', + 'key' + )) as XsdElement; + + const xsd = result?.xsd; + + // Validar estructura del objeto XSD + expect(xsd).toBeDefined(); + + // Verificar elemento Retenciones + expect(xsd['xs:schema']['xs:element']).toBeDefined(); + expect(xsd['xs:schema']['xs:element']['_attributes']).toEqual( + expect.objectContaining({ + name: 'Retenciones', + }) + ); + + // Verificar complexType + expect(xsd['xs:schema']['xs:element']['xs:complexType']).toBeDefined(); + }); + + it('should get the JsonSchema Retenciones', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante_Impuestos_Retenciones', + 'key' + )) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + Retenciones: XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['Retenciones'].getJsonSchema(); + + expect(jsonSchema).toBeDefined(); + expect(jsonSchema.type).toBe('object'); + + // Verificar propiedades que no cambian + expect(jsonSchema.$id).toBe('Retenciones.json'); + expect(jsonSchema.$schema).toBe( + 'http://json-schema.org/draft-07/schema#' + ); + }); + }); + + describe('XSD Retencion', () => { + it('should get the XSD Retencion', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante_Impuestos_Retenciones_Retencion', + 'key' + )) as XsdElement; + + const xsd = result?.xsd; + + // Validar estructura del objeto XSD + expect(xsd).toBeDefined(); + + // Verificar elemento Retencion + expect(xsd['xs:schema']['xs:element']).toBeDefined(); + expect(xsd['xs:schema']['xs:element']['_attributes']).toEqual( + expect.objectContaining({ + name: 'Retencion', + }) + ); + + // Verificar complexType y sus atributos + expect(xsd['xs:schema']['xs:element']['xs:complexType']).toBeDefined(); + + // Verificar atributos del complexType + const attributes = + xsd['xs:schema']['xs:element']['xs:complexType']['xs:attribute']; + expect(Array.isArray(attributes)).toBe(true); + + // Retencion debe tener atributos específicos + const attributeNames = attributes.map( + (attr: any) => attr._attributes.name + ); + expect(attributeNames).toContain('Impuesto'); + expect(attributeNames).toContain('Importe'); + }); + + it('should get the JsonSchema Retencion', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante_Impuestos_Retenciones_Retencion', + 'key' + )) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + Retencion: XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['Retencion'].getJsonSchema(); + + expect(jsonSchema).toBeDefined(); + expect(jsonSchema.type).toBe('object'); + + // Verificar required array para Retencion + expect(jsonSchema.required).toContain('Impuesto'); + expect(jsonSchema.required).toContain('Importe'); + + // Verificar que properties existe y tiene las propiedades esperadas + expect(jsonSchema.properties).toBeDefined(); + expect(jsonSchema.properties.Impuesto).toBeDefined(); + expect(jsonSchema.properties.Importe).toBeDefined(); + + // Verificar referencias específicas + expect(jsonSchema.properties.Impuesto.$ref).toContain( + 'catalogos.json#/definitions/c_Impuesto' + ); + expect(jsonSchema.properties.Importe.$ref).toContain( + 'tipoDatos.json#/definitions/t_Importe' + ); + }); + }); + + describe('XSD Traslados', () => { + it('should get the XSD Traslados', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante_Impuestos_Traslados', + 'key' + )) as XsdElement; + + const xsd = result?.xsd; + + // Validar estructura del objeto XSD + expect(xsd).toBeDefined(); + + // Verificar elemento Traslados + expect(xsd['xs:schema']['xs:element']).toBeDefined(); + expect(xsd['xs:schema']['xs:element']['_attributes']).toEqual( + expect.objectContaining({ + name: 'Traslados', + }) + ); + + // Verificar complexType + expect(xsd['xs:schema']['xs:element']['xs:complexType']).toBeDefined(); + }); + + it('should get the JsonSchema Traslados', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante_Impuestos_Traslados', + 'key' + )) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + Traslados: XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['Traslados'].getJsonSchema(); + + expect(jsonSchema).toBeDefined(); + expect(jsonSchema.type).toBe('object'); + + // Verificar propiedades que no cambian + expect(jsonSchema.$id).toBe('Traslados.json'); + expect(jsonSchema.$schema).toBe( + 'http://json-schema.org/draft-07/schema#' + ); + }); + }); + + describe('XSD Traslado', () => { + it('should get the XSD Traslado', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante_Impuestos_Traslados_Traslado', + 'key' + )) as XsdElement; + + const xsd = result?.xsd; + + // Validar estructura del objeto XSD + expect(xsd).toBeDefined(); + + // Verificar elemento Traslado + expect(xsd['xs:schema']['xs:element']).toBeDefined(); + expect(xsd['xs:schema']['xs:element']['_attributes']).toEqual( + expect.objectContaining({ + name: 'Traslado', + }) + ); + + // Verificar complexType y sus atributos + expect(xsd['xs:schema']['xs:element']['xs:complexType']).toBeDefined(); + + // Verificar atributos del complexType + const attributes = + xsd['xs:schema']['xs:element']['xs:complexType']['xs:attribute']; + expect(Array.isArray(attributes)).toBe(true); + + // Traslado debe tener atributos específicos + const attributeNames = attributes.map( + (attr: any) => attr._attributes.name + ); + expect(attributeNames).toContain('Base'); + expect(attributeNames).toContain('Impuesto'); + expect(attributeNames).toContain('TipoFactor'); + }); + + it('should get the JsonSchema Traslado', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'comprobante_Impuestos_Traslados_Traslado', + 'key' + )) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + Traslado: XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['Traslado'].getJsonSchema(); + + expect(jsonSchema).toBeDefined(); + expect(jsonSchema.type).toBe('object'); + + // Verificar required array para Traslado + expect(jsonSchema.required).toContain('Base'); + expect(jsonSchema.required).toContain('Impuesto'); + expect(jsonSchema.required).toContain('TipoFactor'); + + // Verificar que properties existe y tiene las propiedades esperadas + expect(jsonSchema.properties).toBeDefined(); + expect(jsonSchema.properties.Base).toBeDefined(); + expect(jsonSchema.properties.Impuesto).toBeDefined(); + expect(jsonSchema.properties.TipoFactor).toBeDefined(); + + // Verificar referencias específicas + expect(jsonSchema.properties.Base.$ref).toContain( + 'tipoDatos.json#/definitions/t_Importe' + ); + expect(jsonSchema.properties.Impuesto.$ref).toContain( + 'catalogos.json#/definitions/c_Impuesto' + ); + expect(jsonSchema.properties.TipoFactor.$ref).toContain( + 'catalogos.json#/definitions/c_TipoFactor' + ); + + // Verificar propiedades opcionales si existen + if (jsonSchema.properties.TasaOCuota) { + expect(jsonSchema.properties.TasaOCuota).toEqual({ + description: + 'Atributo condicional para señalar el valor de la tasa o cuota del impuesto que se traslada por los conceptos amparados en el comprobante.', + minimum: 0, + type: 'number', + }); + } + if (jsonSchema.properties.Importe) { + expect(jsonSchema.properties.Importe).toEqual({ + $ref: 'tipoDatos.json#/definitions/t_Importe', + }); + } + }); + }); +}); diff --git a/packages/cfdi/schema/test/comprobante/informacion_g.xsd.test.ts b/packages/cfdi/schema/test/comprobante/informacion_g.xsd.test.ts new file mode 100644 index 00000000..f8c498a9 --- /dev/null +++ b/packages/cfdi/schema/test/comprobante/informacion_g.xsd.test.ts @@ -0,0 +1,180 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { CfdiXsd, XsdElement } from '../../src/cfdi.xsd'; +import path from 'path'; +import { XMLUtils } from '../../src/common/xml-utils'; +import { CatalogProcess } from '../../src/catalogos.xsd'; +import { TipoDatosXsd } from '../../src/tipo-datos.xsd'; +import { CfdiSchema } from '../../src/schema.xsd'; +const CATALOGOS_NAMESPACE = + 'http://www.sat.gob.mx/sitio_internet/cfd/catalogos'; +const TIPO_DATOS_NAMESPACE = + 'http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI'; +const CATALOGOS_SCHEMA_LOCATION = + 'http://www.sat.gob.mx/sitio_internet/cfd/catalogos/catCFDI.xsd'; +const TIPO_DATOS_SCHEMA_LOCATION = + 'http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI/tdCFDI.xsd'; + +describe('CfdiXsd - Integration Tests', () => { + let cfdiXsd: CfdiXsd; + let catalogProcess: CatalogProcess; + let tipoDatosXsd: TipoDatosXsd; + let cfdiSchema: CfdiSchema; + // Ruta al archivo XSD real + const realXsdPath = path.join(__dirname, '../../src/files/cfdv40.xsd'); + const tipoDatosXsdPath = path.join(__dirname, '../../src/files/tdCFDI.xsd'); + const catalogosXsdPath = path.join(__dirname, '../../src/files/catCFDI.xsd'); + + beforeEach(() => { + cfdiXsd = CfdiXsd.of(); + catalogProcess = CatalogProcess.of(); + tipoDatosXsd = TipoDatosXsd.of(); + cfdiSchema = CfdiSchema.of(); + cfdiXsd.setConfig({ source: realXsdPath }); + catalogProcess.setConfig({ source: catalogosXsdPath }); + tipoDatosXsd.setConfig({ source: tipoDatosXsdPath }); + }); + + describe('XSD', () => { + it('should get the XSD comprobante', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'InformacionGlobal' + )) as XsdElement; + + const xsd = result?.xsd; + + console.log(JSON.stringify(xsd, null, 2)); + expect(xsd).toBeDefined(); + expect(xsd['xs:schema']['xs:import']).toBeDefined(); + expect(Array.isArray(xsd['xs:schema']['xs:import'])).toBe(true); + expect(xsd['xs:schema']['xs:import']).toHaveLength(2); + expect(xsd['xs:schema']['xs:import']).toContainEqual({ + _attributes: { + namespace: CATALOGOS_NAMESPACE, + schemaLocation: CATALOGOS_SCHEMA_LOCATION, + }, + }); + expect(xsd['xs:schema']['xs:import']).toContainEqual({ + _attributes: { + namespace: TIPO_DATOS_NAMESPACE, + schemaLocation: TIPO_DATOS_SCHEMA_LOCATION, + }, + }); + expect(xsd['xs:schema']['xs:element']['_attributes']).toEqual({ + name: 'InformacionGlobal', + minOccurs: '0', + }); + + expect(xsd['xs:schema']['xs:element']['xs:complexType']['xs:attribute']).toHaveLength(3); + expect(xsd['xs:schema']['xs:element']['xs:complexType']['xs:attribute']).toContainEqual({ + "_attributes": { + "name": "Periodicidad", + "type": "catCFDI:c_Periodicidad", + "use": "required" + }, + "xs:annotation": { + "xs:documentation": { + "_text": "Atributo requerido para expresar el período al que corresponde la información del comprobante global." + } + } + }); + expect(xsd['xs:schema']['xs:element']['xs:complexType']['xs:attribute']).toContainEqual( { + "_attributes": { + "name": "Meses", + "type": "catCFDI:c_Meses", + "use": "required" + }, + "xs:annotation": { + "xs:documentation": { + "_text": "Atributo requerido para expresar el mes o los meses al que corresponde la información del comprobante global." + } + } + },); + expect(xsd['xs:schema']['xs:element']['xs:complexType']['xs:attribute']).toContainEqual({ + "_attributes": { + "name": "Año", + "use": "required" + }, + "xs:annotation": { + "xs:documentation": { + "_text": "Atributo requerido para expresar el año al que corresponde la información del comprobante global." + } + }, + "xs:simpleType": { + "xs:restriction": { + "_attributes": { + "base": "xs:short" + }, + "xs:minInclusive": { + "_attributes": { + "value": "2021" + } + }, + "xs:whiteSpace": { + "_attributes": { + "value": "collapse" + } + } + } + } + }); + }); + }); + + describe('JsonSchema', () => { + it('should get the JsonSchema comprobante', async () => { + cfdiXsd.setConfig({ source: realXsdPath }); + catalogProcess.setConfig({ source: catalogosXsdPath }); + tipoDatosXsd.setConfig({ source: tipoDatosXsdPath }); + + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement( + 'InformacionGlobal' + )) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + 'InformacionGlobal': XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['InformacionGlobal'].getJsonSchema(); + + console.log(JSON.stringify(jsonSchema, null, 2)); + expect(jsonSchema).toBeDefined(); + expect(jsonSchema.type).toBe('object'); + + expect(jsonSchema.title).toMatch( + /This JSON Schema file was generated from InformacionGlobal on .*\. For more information please see http:\/\/www\.xsd2jsonschema\.org$/ + ); + expect(jsonSchema.description).toBe( + 'Atributo requerido para expresar el mes o los meses al que corresponde la información del comprobante global.' + ); + expect(jsonSchema.required).toEqual([ + 'Periodicidad', + 'Meses', + 'Año' + ]); + expect(jsonSchema.properties).toEqual({ + 'Periodicidad': { + '$ref': 'catalogos.json#/definitions/c_Periodicidad' + }, + 'Meses': { + '$ref': 'catalogos.json#/definitions/c_Meses' + }, + 'Año': { + 'description': 'Atributo requerido para expresar el año al que corresponde la información del comprobante global.', + 'maximum': 32767, + 'minimum': 2021, + 'type': 'integer' + } + }); + }); + }); +}); + + \ No newline at end of file diff --git a/packages/cfdi/schema/test/comprobante/receptor.xsd.test.ts b/packages/cfdi/schema/test/comprobante/receptor.xsd.test.ts new file mode 100644 index 00000000..0c655e25 --- /dev/null +++ b/packages/cfdi/schema/test/comprobante/receptor.xsd.test.ts @@ -0,0 +1,179 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { CfdiXsd, XsdElement } from '../../src/cfdi.xsd'; +import path from 'path'; +import { XMLUtils } from '../../src/common/xml-utils'; +import { CatalogProcess } from '../../src/catalogos.xsd'; +import { TipoDatosXsd } from '../../src/tipo-datos.xsd'; +import { CfdiSchema } from '../../src/schema.xsd'; +import { + CATALOGOS_NAMESPACE, + CATALOGOS_SCHEMA_LOCATION, + TIPO_DATOS_NAMESPACE, + TIPO_DATOS_SCHEMA_LOCATION, +} from '../shared'; + +describe('CfdiXsd - Receptor Integration Tests', () => { + let cfdiXsd: CfdiXsd; + let catalogProcess: CatalogProcess; + let tipoDatosXsd: TipoDatosXsd; + let cfdiSchema: CfdiSchema; + // Ruta al archivo XSD real + const realXsdPath = path.join(__dirname, '../../src/files/cfdv40.xsd'); + const tipoDatosXsdPath = path.join(__dirname, '../../src/files/tdCFDI.xsd'); + const catalogosXsdPath = path.join(__dirname, '../../src/files/catCFDI.xsd'); + + beforeEach(() => { + cfdiXsd = CfdiXsd.of(); + catalogProcess = CatalogProcess.of(); + tipoDatosXsd = TipoDatosXsd.of(); + cfdiSchema = CfdiSchema.of(); + cfdiXsd.setConfig({ source: realXsdPath }); + catalogProcess.setConfig({ source: catalogosXsdPath }); + tipoDatosXsd.setConfig({ source: tipoDatosXsdPath }); + }); + + describe('XSD', () => { + it('should get the XSD Receptor', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement('Receptor')) as XsdElement; + + const xsd = result?.xsd; + console.log(JSON.stringify(xsd, null, 2)); + + // Validar estructura del objeto XSD + expect(xsd).toBeDefined(); + + // Verificar estructura básica del schema + expect(xsd['xs:schema']).toBeDefined(); + expect(xsd['xs:schema']['_attributes']).toBeDefined(); + + // Verificar namespaces y atributos del schema + const schemaAttrs = xsd['xs:schema']['_attributes']; + expect(schemaAttrs['xmlns:cfdi']).toBe('http://www.sat.gob.mx/cfd/4'); + expect(schemaAttrs['xmlns:xs']).toBe('http://www.w3.org/2001/XMLSchema'); + expect(schemaAttrs['xmlns:catCFDI']).toBe('http://www.sat.gob.mx/sitio_internet/cfd/catalogos'); + expect(schemaAttrs['xmlns:tdCFDI']).toBe('http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI'); + expect(schemaAttrs['targetNamespace']).toBe('http://www.sat.gob.mx/cfd/4'); + expect(schemaAttrs['elementFormDefault']).toBe('qualified'); + expect(schemaAttrs['attributeFormDefault']).toBe('unqualified'); + + // Verificar imports + expect(xsd['xs:schema']['xs:import']).toBeDefined(); + expect(Array.isArray(xsd['xs:schema']['xs:import'])).toBe(true); + expect(xsd['xs:schema']['xs:import']).toHaveLength(2); + expect(xsd['xs:schema']['xs:import']).toContainEqual({ + _attributes: { + namespace: CATALOGOS_NAMESPACE, + schemaLocation: CATALOGOS_SCHEMA_LOCATION, + }, + }); + expect(xsd['xs:schema']['xs:import']).toContainEqual({ + _attributes: { + namespace: TIPO_DATOS_NAMESPACE, + schemaLocation: TIPO_DATOS_SCHEMA_LOCATION, + }, + }); + + // Verificar elemento Receptor + expect(xsd['xs:schema']['xs:element']).toBeDefined(); + expect(xsd['xs:schema']['xs:element']['_attributes']).toEqual({ + name: 'Receptor', + }); + + // Verificar complexType y sus atributos + expect(xsd['xs:schema']['xs:element']['xs:complexType']).toBeDefined(); + + // Verificar atributos del complexType + const attributes = xsd['xs:schema']['xs:element']['xs:complexType']['xs:attribute']; + expect(Array.isArray(attributes)).toBe(true); + expect(attributes.length).toBeGreaterThan(3); // Receptor tiene varios atributos + + // Verificar algunos atributos específicos del Receptor + const attributeNames = attributes.map((attr: any) => attr._attributes.name); + expect(attributeNames).toContain('Rfc'); + expect(attributeNames).toContain('Nombre'); + expect(attributeNames).toContain('DomicilioFiscalReceptor'); + expect(attributeNames).toContain('RegimenFiscalReceptor'); + expect(attributeNames).toContain('UsoCFDI'); + + console.log('✅ XSD Receptor validation passed!'); + console.log('Found attributes:', attributeNames); + }); + }); + + describe('JsonSchema', () => { + it('should get the JsonSchema Receptor', async () => { + const catalogos = await catalogProcess.process(); + const tipoDatos = await tipoDatosXsd.process(); + + const result = (await cfdiXsd.getXsdByElement('Receptor')) as XsdElement; + + const res = await cfdiSchema.xsd2Json({ + ...catalogos, + ...tipoDatos, + Receptor: XMLUtils.toXsd(result?.xsd), + }); + + const jsonSchema = res['Receptor'].getJsonSchema(); + + expect(jsonSchema).toBeDefined(); + expect(jsonSchema.type).toBe('object'); + + // Verificar propiedades que no cambian + expect(jsonSchema.$id).toBe('Receptor.json'); + expect(jsonSchema.$schema).toBe('http://json-schema.org/draft-07/schema#'); + + // Usar regex para el title que contiene timestamp + expect(jsonSchema.title).toMatch(/^This JSON Schema file was generated from Receptor on .*\. For more information please see http:\/\/www\.xsd2jsonschema\.org$/); + + // Verificar required array para Receptor + expect(jsonSchema.required).toContain('Rfc'); + expect(jsonSchema.required).toContain('Nombre'); + expect(jsonSchema.required).toContain('DomicilioFiscalReceptor'); + expect(jsonSchema.required).toContain('RegimenFiscalReceptor'); + expect(jsonSchema.required).toContain('UsoCFDI'); + + // Verificar que properties existe y tiene las propiedades esperadas del Receptor + expect(jsonSchema.properties).toBeDefined(); + expect(jsonSchema.properties).toEqual( { + "Rfc": { + "$ref": "tipoDatos.json#/definitions/t_RFC" + }, + "Nombre": { + "description": "Atributo requerido para registrar el nombre(s), primer apellido, segundo apellido, según corresponda, denominación o razón social del contribuyente, inscrito en el RFC, del receptor del comprobante.", + "maxLength": 300, + "minLength": 1, + "pattern": "[^|]{1,300}", + "type": "string" + }, + "DomicilioFiscalReceptor": { + "description": "Atributo requerido para registrar el código postal del domicilio fiscal del receptor del comprobante.", + "maxLength": 5, + "minLength": 5, + "pattern": "[0-9]{5}", + "type": "string" + }, + "ResidenciaFiscal": { + "$ref": "catalogos.json#/definitions/c_Pais" + }, + "NumRegIdTrib": { + "description": "Atributo condicional para expresar el número de registro de identidad fiscal del receptor cuando sea residente en el extranjero. Es requerido cuando se incluya el complemento de comercio exterior.", + "maxLength": 40, + "minLength": 1, + "type": "string" + }, + "RegimenFiscalReceptor": { + "$ref": "catalogos.json#/definitions/c_RegimenFiscal" + }, + "UsoCFDI": { + "$ref": "catalogos.json#/definitions/c_UsoCFDI" + } + }); + + console.log('✅ JsonSchema Receptor validation passed!'); + console.log(JSON.stringify(jsonSchema, null, 2)); + }); + }); +}); \ No newline at end of file diff --git a/packages/cfdi/schema/test/shared.ts b/packages/cfdi/schema/test/shared.ts new file mode 100644 index 00000000..f3e9b4b0 --- /dev/null +++ b/packages/cfdi/schema/test/shared.ts @@ -0,0 +1,10 @@ +const CATALOGOS_NAMESPACE = + 'http://www.sat.gob.mx/sitio_internet/cfd/catalogos'; +const TIPO_DATOS_NAMESPACE = + 'http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI'; +const CATALOGOS_SCHEMA_LOCATION = + 'http://www.sat.gob.mx/sitio_internet/cfd/catalogos/catCFDI.xsd'; +const TIPO_DATOS_SCHEMA_LOCATION = + 'http://www.sat.gob.mx/sitio_internet/cfd/tipoDatos/tdCFDI/tdCFDI.xsd'; + +export { CATALOGOS_NAMESPACE, TIPO_DATOS_NAMESPACE, CATALOGOS_SCHEMA_LOCATION, TIPO_DATOS_SCHEMA_LOCATION }; \ No newline at end of file diff --git a/packages/cfdi/schema/tsconfig.json b/packages/cfdi/schema/tsconfig.json new file mode 100644 index 00000000..53e2475f --- /dev/null +++ b/packages/cfdi/schema/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "lib": ["dom", "esnext"], + "types": [ "node" ], + "importHelpers": true, + // output .d.ts declaration files for consumers + "declaration": true, + // output .js.map sourcemap files for consumers + "sourceMap": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + } +} diff --git a/packages/cfdi/schema/vite.config.mts b/packages/cfdi/schema/vite.config.mts new file mode 100644 index 00000000..db0b620a --- /dev/null +++ b/packages/cfdi/schema/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xsd2jsonschema', 'xml-js', 'ajv'], + }, + }, +})); diff --git a/packages/cfdi/schema/vitest.config.mts b/packages/cfdi/schema/vitest.config.mts new file mode 100644 index 00000000..f2a4ec65 --- /dev/null +++ b/packages/cfdi/schema/vitest.config.mts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; // only if you are using custom tsconfig paths + +export default defineConfig({ + test: {}, + plugins: [tsconfigPaths()], // only if you are using custom tsconfig paths +}); diff --git a/packages/cfdi/transform/README.md b/packages/cfdi/transform/README.md index 9487075c..893a60fc 100644 --- a/packages/cfdi/transform/README.md +++ b/packages/cfdi/transform/README.md @@ -1 +1,54 @@ -utils +# @cfdi/transform + +Transformacion de datos XML CFDI. Extrae los valores de un comprobante fiscal XML y genera una cadena con formato de expresion impresa. + +## Instalacion + +```bash +npm install @cfdi/transform +``` + +## Uso + +```typescript +import { Transform } from '@cfdi/transform'; + +// Crear instancia con el XML parseado +const transform = new Transform(xmlObject); + +// Ejecutar la transformacion para obtener la cadena de valores +const resultado = await transform.run(); +// Resultado: ||valor1|valor2|valor3|...|| +``` + +### Configuracion adicional + +```typescript +const transform = new Transform(xmlObject); + +// Especificar ruta XSLT +transform.json('/ruta/al/archivo.xsl'); + +// Configurar advertencias +transform.warnings('silent'); + +// Ejecutar +const cadena = await transform.run(); +``` + +## API + +### Clase `Transform` + +| Metodo | Retorno | Descripcion | +|--------|---------|-------------| +| `constructor(xml)` | `Transform` | Recibe el objeto XML parseado del CFDI | +| `run()` | `Promise` | Extrae los valores del comprobante y retorna la cadena con formato `\|\|valor1\|valor2\|...\|\|` | +| `json(xslPath)` | `Transform` | Establece la ruta del archivo XSLT | +| `warnings(type)` | `Transform` | Configura el nivel de advertencias (`'silent'` por defecto) | + +La transformacion recorre la estructura del comprobante en el siguiente orden: atributos, InformacionGlobal, CfdiRelacionados, Emisor, Receptor, Conceptos, Impuestos y Complemento. Omite automaticamente namespaces, esquemas y el sello digital. + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/transform/config/index.js b/packages/cfdi/transform/config/index.js deleted file mode 100644 index e940f4aa..00000000 --- a/packages/cfdi/transform/config/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict' -module.exports = require('./transform.cjs.production.min.js') diff --git a/packages/cfdi/transform/package.json b/packages/cfdi/transform/package.json index c966b3d2..5ffc8428 100644 --- a/packages/cfdi/transform/package.json +++ b/packages/cfdi/transform/package.json @@ -2,9 +2,9 @@ "name": "@cfdi/transform", "version": "4.0.13", "license": "MIT", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "module": "dist/transform.esm.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "release": { "branches": [ @@ -17,25 +17,14 @@ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build --env production --minify && rimraf ./dist/index.js ./dist/xsd.cjs.development.* && npm run cp", - "cp": "cp ./config/index.js ./dist", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "publishConfig": { "registry": "https://registry.npmjs.org/", @@ -45,55 +34,20 @@ "type": "git", "url": "https://github.com/MisaelMa/recreando" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, "author": { "name": "Amir Misael Marin Coh, Signati", "email": "amisael.amir.misae@gmail.com, signatidev@gmail.com,", "url": "" }, - "size-limit": [ - { - "path": "dist/transform.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/transform.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "xml-js": "^1.6.11", - "@cfdi/2json": "workspace:*" + "xml-js": "^1.6.11" }, "devDependencies": { - "rimraf": "^6.0.1", "@recreando/vite": "workspace:*", - "@saxon-he/cli": "workspace:*", "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", + "@types/node": "^22", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/transform/src/cadena-engine.ts b/packages/cfdi/transform/src/cadena-engine.ts new file mode 100644 index 00000000..ff1d482a --- /dev/null +++ b/packages/cfdi/transform/src/cadena-engine.ts @@ -0,0 +1,233 @@ +import xmlJs from 'xml-js'; +import type { AttrRule, TextRule, ChildRule, TemplateRegistry, XmlElement } from './types'; + +export function normalizeSpace(s: string): string { + return s.replace(/\s+/g, ' ').trim(); +} + +export function requerido(value: string | undefined): string { + return `|${normalizeSpace(value ?? '')}`; +} + +export function opcional(value: string | undefined): string { + if (value === undefined || value === null) return ''; + return `|${normalizeSpace(value)}`; +} + +export function generateCadenaOriginal( + xmlContent: string, + registry: TemplateRegistry +): string { + const doc = xmlJs.xml2js(xmlContent, { compact: false }) as { + elements?: XmlElement[]; + }; + + const root = doc.elements?.find(e => e.type === 'element'); + if (!root) return '||||'; + + // Find the root element that matches any template in the registry + const rootTemplate = findRootElement(doc.elements!, registry); + if (!rootTemplate) return '|||'; + + // Verify namespaces: the XML must declare the same namespace URIs as the XSLT + if (!namespacesMatch(rootTemplate, registry)) { + return '|||'; + } + + const result = processNode(rootTemplate, registry); + return `|${result}||`; +} + +function namespacesMatch( + xmlElement: XmlElement, + registry: TemplateRegistry +): boolean { + if (registry.namespaces.size === 0) return true; + + for (const [prefix, xsltUri] of registry.namespaces) { + const xmlUri = xmlElement.attributes?.[`xmlns:${prefix}`] as string | undefined; + if (xmlUri && xmlUri !== xsltUri) { + return false; + } + } + return true; +} + +function findRootElement( + elements: XmlElement[], + registry: TemplateRegistry +): XmlElement | undefined { + for (const el of elements) { + if (el.type === 'element' && registry.templates.has(el.name)) { + return el; + } + if (el.elements) { + const found = findRootElement(el.elements, registry); + if (found) return found; + } + } + return undefined; +} + +export function processNode( + node: XmlElement, + registry: TemplateRegistry +): string { + const template = registry.templates.get(node.name); + if (!template) return ''; + + let result = ''; + + for (const rule of template.rules) { + if (rule.type === 'attr') { + result += processAttrRule(node, rule); + } else if (rule.type === 'text') { + result += processTextRule(node, rule); + } else { + result += processChildRule(node, rule, registry); + } + } + + return result; +} + +function processAttrRule(node: XmlElement, rule: AttrRule): string { + const value = node.attributes?.[rule.name] as string | undefined; + return rule.required ? requerido(value) : opcional(value); +} + +function processTextRule(node: XmlElement, rule: TextRule): string { + let value: string | undefined; + + if (rule.select === '.') { + value = getTextContent(node); + } else { + const elements = resolveSelect(node, rule.select); + if (elements.length > 0) { + value = getTextContent(elements[0]); + } + } + + return rule.required ? requerido(value) : opcional(value); +} + +function getTextContent(node: XmlElement): string | undefined { + if (!node.elements) return undefined; + const parts: string[] = []; + for (const child of node.elements) { + if ((child as any).type === 'text' && (child as any).text !== undefined) { + parts.push(String((child as any).text)); + } + } + return parts.length > 0 ? parts.join('') : undefined; +} + +function processChildRule( + node: XmlElement, + rule: ChildRule, + registry: TemplateRegistry +): string { + if (rule.condition) { + const conditionElements = resolveSelect(node, rule.condition); + if (conditionElements.length === 0) return ''; + } + + if (rule.wildcard) { + return processWildcard(node, registry); + } + + const elements = rule.descendant + ? resolveDescendant(node, getLastSegment(rule.select)) + : resolveSelect(node, rule.select); + + let result = ''; + + if (rule.forEach || elements.length > 0) { + for (const el of elements) { + if (rule.inline.length > 0) { + for (const inlineRule of rule.inline) { + if (inlineRule.type === 'attr') { + result += processAttrRule(el, inlineRule); + } else { + result += processTextRule(el, inlineRule); + } + } + } + if (rule.applyTemplates) { + result += processNode(el, registry); + } + } + } else if (!rule.forEach && rule.applyTemplates) { + for (const el of elements) { + result += processNode(el, registry); + } + } + + return result; +} + +function processWildcard(node: XmlElement, registry: TemplateRegistry): string { + if (!node.elements) return ''; + let result = ''; + for (const child of node.elements) { + if (child.type === 'element') { + result += processNode(child, registry); + } + } + return result; +} + +export function resolveSelect( + node: XmlElement, + selectPath: string +): XmlElement[] { + const cleanPath = selectPath.replace(/^\.\//, ''); + const segments = cleanPath.split('/'); + let current: XmlElement[] = [node]; + + for (const segment of segments) { + const next: XmlElement[] = []; + for (const el of current) { + if (el.elements) { + for (const child of el.elements) { + if (child.type === 'element' && child.name === segment) { + next.push(child); + } + } + } + } + current = next; + } + + return current; +} + +function resolveDescendant( + node: XmlElement, + elementName: string +): XmlElement[] { + const results: XmlElement[] = []; + collectDescendants(node, elementName, results); + return results; +} + +function collectDescendants( + node: XmlElement, + elementName: string, + results: XmlElement[] +): void { + if (!node.elements) return; + for (const child of node.elements) { + if (child.type === 'element') { + if (child.name === elementName) { + results.push(child); + } + collectDescendants(child, elementName, results); + } + } +} + +function getLastSegment(path: string): string { + const segments = path.split('/'); + return segments[segments.length - 1]; +} diff --git a/packages/cfdi/transform/src/index.ts b/packages/cfdi/transform/src/index.ts index 354a0839..4bd91b25 100644 --- a/packages/cfdi/transform/src/index.ts +++ b/packages/cfdi/transform/src/index.ts @@ -1 +1,4 @@ export { default as Transform } from './transform'; +export { parseXslt } from './xslt-parser'; +export { generateCadenaOriginal, normalizeSpace, requerido, opcional } from './cadena-engine'; +export type { AttrRule, ChildRule, Rule, ParsedTemplate, TemplateRegistry, XsltParseResult } from './types'; diff --git a/packages/cfdi/transform/src/transform.ts b/packages/cfdi/transform/src/transform.ts index 43c45c8c..ade16f0a 100644 --- a/packages/cfdi/transform/src/transform.ts +++ b/packages/cfdi/transform/src/transform.ts @@ -1,73 +1,34 @@ -import { XmlToJson } from '@cfdi/2json'; +import fs from 'fs'; +import { parseXslt } from './xslt-parser'; +import { generateCadenaOriginal } from './cadena-engine'; +import type { TemplateRegistry } from './types'; + export default class Transform { - xml: any = {}; - xslPath = ''; - fullPath = ''; - - s(archivo: string) { - this.xml = XmlToJson(archivo, { original: true }); - console.log(JSON.stringify(this.xml['cfdi:Comprobante']['cfdi:Impuestos'], null, 2)); + private xmlContent: string = ''; + private registry: TemplateRegistry | null = null; + + s(archivo: string): this { + this.xmlContent = fs.readFileSync(archivo, 'utf-8'); return this; } - async run() { - const rear = await this.obtenerValores(this.xml['cfdi:Comprobante']); - const clean = rear.filter((e) => Boolean(e)); - return `||${clean.join('|')}||`; + xsl(xslPath: string): this { + this.registry = parseXslt(xslPath); + return this; } - json(xslPath: string) { - this.xslPath = xslPath; - return this; + json(xslPath: string): this { + return this.xsl(xslPath); } - warnings(type: string = 'silent') { + warnings(_type: string = 'silent'): this { return this; } - private obtenerValores(obj: any, options: any = { tagKey: 'comprobante' }) { - const { tagKey = 'comprobante', ignore = false } = options; - let valores: (string | number)[] = []; - const omitKeys = [ - 'xmlns:cfdi', - 'xmlns:xsi', - 'xsi:schemaLocation', - 'Certificado', - 'xmlns:destruccion', - 'xmlns:iedu', - 'xmlns:pago10', - 'xmlns:vehiculousado', - ]; - const miObjeto = { - comprobante: [ - '_attributes', - 'cfdi:InformacionGlobal', - 'cfdi:CfdiRelacionados', - 'cfdi:Emisor', - 'cfdi:Receptor', - 'cfdi:Conceptos', - 'cfdi:Impuestos', - 'cfdi:Complemento', - ], - concepto: [], - }; - - const ingnore: string[] = ['Sello']; - // @ts-ignore - const clavesOrdenadas = ignore ? Object.keys(obj) : miObjeto[tagKey]; - for (let key of clavesOrdenadas) { - - if (!omitKeys.includes(key)) { - if (typeof obj[key] === 'object') { - valores = valores.concat(this.obtenerValores(obj[key], { ignore: true })); - } else { - if (!ingnore.includes(key)) { - valores.push(obj[key]); - } - } - } + run(): string { + if (!this.registry) { + throw new Error('XSLT not loaded. Call xsl() or json() first.'); } - - return valores; + return generateCadenaOriginal(this.xmlContent, this.registry); } } diff --git a/packages/cfdi/transform/src/types.ts b/packages/cfdi/transform/src/types.ts new file mode 100644 index 00000000..2810a5ac --- /dev/null +++ b/packages/cfdi/transform/src/types.ts @@ -0,0 +1,47 @@ +export interface AttrRule { + type: 'attr'; + name: string; + required: boolean; +} + +export interface ChildRule { + type: 'child'; + select: string; + forEach: boolean; + inline: (AttrRule | TextRule)[]; + applyTemplates: boolean; + condition?: string; + wildcard?: boolean; + descendant?: boolean; +} + +export interface TextRule { + type: 'text'; + select: string; + required: boolean; +} + +export type Rule = AttrRule | TextRule | ChildRule; + +export interface ParsedTemplate { + match: string; + rules: Rule[]; +} + +export interface XsltParseResult { + templates: Map; + namespaces: Map; +} + +export type TemplateRegistry = XsltParseResult; + +export interface XmlElement { + type: 'element'; + name: string; + attributes?: Record; + elements?: XmlElement[]; +} + +export interface XmlDocument { + elements?: XmlElement[]; +} diff --git a/packages/cfdi/transform/src/xslt-parser.ts b/packages/cfdi/transform/src/xslt-parser.ts new file mode 100644 index 00000000..cfb4c609 --- /dev/null +++ b/packages/cfdi/transform/src/xslt-parser.ts @@ -0,0 +1,253 @@ +import fs from 'fs'; +import path from 'path'; +import xmlJs from 'xml-js'; +import type { + AttrRule, + TextRule, + ChildRule, + Rule, + ParsedTemplate, + TemplateRegistry, + XmlElement, +} from './types'; + +const NAMED_TEMPLATES = ['Requerido', 'Opcional', 'ManejaEspacios']; + +export function parseXslt(mainXsltPath: string): TemplateRegistry { + const templates = new Map(); + const namespaces = new Map(); + const { elements, stylesheetElement } = collectAllTemplateElements(mainXsltPath); + + if (stylesheetElement?.attributes) { + for (const [key, value] of Object.entries(stylesheetElement.attributes)) { + if (key.startsWith('xmlns:') && !key.startsWith('xmlns:xsl') && !key.startsWith('xmlns:xs') && !key.startsWith('xmlns:fn')) { + const prefix = key.substring(6); + namespaces.set(prefix, value as string); + } + } + } + + for (const el of elements) { + const matchAttr = el.attributes?.match as string | undefined; + if (!matchAttr || matchAttr === '/') continue; + + const template = parseTemplate(el, matchAttr); + templates.set(template.match, template); + } + + return { templates, namespaces }; +} + +function collectAllTemplateElements(mainXsltPath: string): { elements: XmlElement[]; stylesheetElement: XmlElement | null } { + const visited = new Set(); + const templates: XmlElement[] = []; + let stylesheetElement: XmlElement | null = null; + + const onStylesheet = (el: XmlElement, isMain: boolean) => { + if (isMain) stylesheetElement = el; + }; + + collectFromFile(mainXsltPath, visited, templates, onStylesheet, true); + return { elements: templates, stylesheetElement }; +} + +function collectFromFile( + filePath: string, + visited: Set, + templates: XmlElement[], + onStylesheet?: (el: XmlElement, isMain: boolean) => void, + isMain = false +): void { + const resolved = path.resolve(filePath); + if (visited.has(resolved)) return; + visited.add(resolved); + + const content = fs.readFileSync(resolved, 'utf-8'); + const doc = xmlJs.xml2js(content, { compact: false }) as { elements?: XmlElement[] }; + + const stylesheet = doc.elements?.find( + e => e.name === 'xsl:stylesheet' || e.name === 'xsl:transform' + ); + if (!stylesheet?.elements) return; + + onStylesheet?.(stylesheet, isMain); + + for (const el of stylesheet.elements) { + if (el.name === 'xsl:include') { + const href = el.attributes?.href as string | undefined; + if (href) { + const includePath = path.resolve(path.dirname(resolved), href); + collectFromFile(includePath, visited, templates, onStylesheet, false); + } + } else if (el.name === 'xsl:template') { + const matchAttr = el.attributes?.match as string | undefined; + const nameAttr = el.attributes?.name as string | undefined; + if (matchAttr && !NAMED_TEMPLATES.includes(nameAttr || '')) { + templates.push(el); + } + } + } +} + +function parseTemplate(templateEl: XmlElement, match: string): ParsedTemplate { + const rules: Rule[] = []; + if (templateEl.elements) { + extractRulesFromElements(templateEl.elements, rules); + } + return { match, rules }; +} + +function extractRulesFromElements(elements: XmlElement[], rules: Rule[]): void { + for (const el of elements) { + if (!el.name) continue; + + if (el.name === 'xsl:call-template') { + const attrRule = parseCallTemplate(el); + if (attrRule) rules.push(attrRule); + } else if (el.name === 'xsl:apply-templates') { + const select = el.attributes?.select as string | undefined; + if (select && select !== '.') { + rules.push({ + type: 'child', + select: normalizeSelect(select), + forEach: false, + inline: [], + applyTemplates: true, + }); + } + } else if (el.name === 'xsl:for-each') { + const forEachRule = parseForEach(el); + if (forEachRule) rules.push(forEachRule); + } else if (el.name === 'xsl:if') { + const test = el.attributes?.test as string | undefined; + if (test && el.elements) { + const innerRules: Rule[] = []; + extractRulesFromElements(el.elements, innerRules); + for (const r of innerRules) { + if (r.type === 'child') { + r.condition = normalizeSelect(test); + } + rules.push(r); + } + } + } + } +} + +function parseCallTemplate(el: XmlElement): AttrRule | TextRule | null { + const name = el.attributes?.name as string | undefined; + if (name !== 'Requerido' && name !== 'Opcional') return null; + + const withParam = el.elements?.find(e => e.name === 'xsl:with-param'); + if (!withParam) return null; + + const select = withParam.attributes?.select as string | undefined; + if (!select) return null; + + const attrName = extractAttrName(select); + if (attrName) { + return { + type: 'attr', + name: attrName, + required: name === 'Requerido', + }; + } + + // Text content extraction: select="." or select="ns:Element/ns:Child" + return { + type: 'text', + select: normalizeSelect(select), + required: name === 'Requerido', + }; +} + +function parseForEach(el: XmlElement): ChildRule | null { + const select = el.attributes?.select as string | undefined; + if (!select) return null; + + const isWildcard = select === './*' || select === '*'; + const isDescendant = select.startsWith('.//'); + const normalizedSelect = normalizeSelect(select); + + const innerRules: Rule[] = []; + if (el.elements) { + extractRulesFromElements(el.elements, innerRules); + } + + const hasApplyTemplates = el.elements?.some( + e => e.name === 'xsl:apply-templates' + ); + const inlineAttrs = innerRules.filter( + (r): r is AttrRule | TextRule => r.type === 'attr' || r.type === 'text' + ); + const innerChildren = innerRules.filter( + (r): r is ChildRule => r.type === 'child' + ); + + if (isWildcard) { + return { + type: 'child', + select: normalizedSelect, + forEach: true, + inline: [], + applyTemplates: true, + wildcard: true, + }; + } + + if (hasApplyTemplates && inlineAttrs.length === 0 && innerChildren.length === 0) { + return { + type: 'child', + select: normalizedSelect, + forEach: true, + inline: [], + applyTemplates: true, + descendant: isDescendant, + }; + } + + if (inlineAttrs.length > 0) { + const rule: ChildRule = { + type: 'child', + select: normalizedSelect, + forEach: true, + inline: inlineAttrs, + applyTemplates: false, + descendant: isDescendant, + }; + if (innerChildren.length > 0) { + rule.applyTemplates = true; + } + return rule; + } + + if (innerChildren.length > 0) { + return { + type: 'child', + select: normalizedSelect, + forEach: true, + inline: [], + applyTemplates: true, + descendant: isDescendant, + }; + } + + return { + type: 'child', + select: normalizedSelect, + forEach: true, + inline: [], + applyTemplates: !!hasApplyTemplates, + descendant: isDescendant, + }; +} + +function extractAttrName(select: string): string | null { + // Pattern: ./@AttributeName or @AttributeName + const match = select.match(/\.?\/?@(.+)$/); + return match ? match[1] : null; +} + +function normalizeSelect(select: string): string { + return select.replace(/^\.\//, ''); +} diff --git a/packages/cfdi/transform/test/check.test.ts b/packages/cfdi/transform/test/check.test.ts index e9b96c85..0363b251 100644 --- a/packages/cfdi/transform/test/check.test.ts +++ b/packages/cfdi/transform/test/check.test.ts @@ -1,28 +1,158 @@ -import { describe, expect, it, TaskContext, test, TestContext } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { Transform as SaxonHe } from '@saxon-he/cli'; import { Transform } from '../src'; import path from 'path'; +import fs from 'fs'; + const files = path.resolve(__dirname, '..', '..', '..', 'files'); const xml_path = `${files}/xml`; -const key_path = `${files}/certificados/LAN7008173R5.key`; -const cer_path = `${files}/certificados/LAN7008173R5.cer`; -const xslt_path = `${files}/4.0/cadenaoriginal.xslt`; +const xslt_40 = `${files}/4.0/cadenaoriginal.xslt`; +const xslt_33 = `${files}/3.3/cadenaoriginal-3.3.xslt`; const vehiculo_usado = `${xml_path}/vehiculo_usado.xml`; -describe('transform', () => { - it('with saxon-he', async (context: TaskContext) => { - const saxonhe = new SaxonHe(); +function hasSaxon(): boolean { + try { + const saxon = new SaxonHe(); + saxon.s(vehiculo_usado).xsl(xslt_40).run(); + return true; + } catch { + return false; + } +} + +const saxonAvailable = hasSaxon(); - const cadena_saxon = saxonhe.s(vehiculo_usado).xsl(xslt_path).run(); - - //expect(cadena_saxon).toBe('||4.0|Serie|Folio|2024-03-01T00:00:00|99|20001000000300022815|CondicionesDePago|2000|MXN|1|2000.16|I|01|PUE|20000|EKU9003173C9|ESCUELA KEMPER URGATE|601|URE180429TM6|UNIVERSIDAD ROBOTICA ESPAÑOLA|86991|601|S01|50211503|1|H87|Servicio|Servicio|200.00|200.00|02|1|002|Tasa|0.160000|0.16|1|002|Tasa|0.160000|0.16|0.16|1.0|10000.00|0.00|AAAABBB|FORD|Mustang|1989|123123123|12312323|1234ASD|5000.00||') - +describe('transform', () => { + it('should generate cadena original from vehiculo_usado.xml', () => { + const transform = new Transform(); + const cadena = transform.s(vehiculo_usado).xsl(xslt_40).run(); + expect(cadena).toBeTypeOf('string'); + expect(cadena.startsWith('||')).toBe(true); + expect(cadena.endsWith('||')).toBe(true); }); - it('with transform', async (context: TaskContext) => { + it('should throw if xsl not loaded', () => { const transform = new Transform(); - const cadena = await transform.s(vehiculo_usado).json(xslt_path).run(); - //expect(cadena).toBe('||4.0|Serie|Folio|2024-03-01T00:00:00|99|20001000000300022815|CondicionesDePago|2000|MXN|1|2000.16|I|01|PUE|20000|EKU9003173C9|ESCUELA KEMPER URGATE|601|URE180429TM6|UNIVERSIDAD ROBOTICA ESPAÑOLA|86991|601|S01|50211503|1|H87|Servicio|Servicio|200.00|200.00|02|1|002|Tasa|0.160000|0.16|1|002|Tasa|0.160000|0.16|0.16|1.0|10000.00|0.00|AAAABBB|FORD|Mustang|1989|123123123|12312323|1234ASD|5000.00||') + expect(() => transform.s(vehiculo_usado).run()).toThrow('XSLT not loaded'); }); }); + +describe('transform vs saxon-he (xml/)', () => { + const xmlFiles = fs.readdirSync(xml_path).filter((f: string) => f.endsWith('.xml')); + + for (const xmlFile of xmlFiles) { + const xmlFilePath = `${xml_path}/${xmlFile}`; + + it.skipIf(!saxonAvailable)(`${xmlFile}: output must match Saxon-HE (4.0)`, () => { + let cadenaSaxon: string; + try { + const saxon = new SaxonHe(); + cadenaSaxon = saxon.s(xmlFilePath).xsl(xslt_40).run(); + } catch { + return; + } + + const transform = new Transform(); + const cadenaTransform = transform.s(xmlFilePath).xsl(xslt_40).run(); + + expect(cadenaTransform).toBe(cadenaSaxon); + }); + } +}); + +const examplesPath = `${xml_path}/examples`; + +function getExampleFiles(subdir: string): string[] { + const dirPath = `${examplesPath}/${subdir}`; + if (!fs.existsSync(dirPath)) return []; + return fs.readdirSync(dirPath).filter((f: string) => f.endsWith('.xml')); +} + +function compareSaxonVsTransform(xmlFilePath: string, xsltPath: string) { + let cadenaSaxon: string; + try { + const saxon = new SaxonHe(); + cadenaSaxon = saxon.s(xmlFilePath).xsl(xsltPath).run(); + } catch { + return; + } + + const transform = new Transform(); + const cadenaTransform = transform.s(xmlFilePath).xsl(xsltPath).run(); + + console.log(` + Saxon: ${cadenaSaxon} + Transform: ${cadenaTransform} + Difference: ${cadenaTransform !== cadenaSaxon} + `); + expect(cadenaTransform).toBe(cadenaSaxon); +} + +describe('transform vs saxon-he (examples cfdi40 con xslt 4.0)', () => { + const cfdi40Files = getExampleFiles('cfdi40'); + + for (const xmlFile of cfdi40Files) { + const xmlFilePath = `${examplesPath}/cfdi40/${xmlFile}`; + + it.skipIf(!saxonAvailable)(`${xmlFile}: output must match Saxon-HE`, () => { + compareSaxonVsTransform(xmlFilePath, xslt_40); + }); + } +}); + +describe('transform vs saxon-he (examples cfdi33 con xslt 3.3)', () => { + const cfdi33Files = getExampleFiles('cfdi33'); + + for (const xmlFile of cfdi33Files) { + const xmlFilePath = `${examplesPath}/cfdi33/${xmlFile}`; + + it.skipIf(!saxonAvailable)(`${xmlFile}: output must match Saxon-HE`, () => { + compareSaxonVsTransform(xmlFilePath, xslt_33); + }); + } +}); + +describe('transform vs saxon-he (test-cfdi40 con xslt 4.0)', () => { + const testFiles = getExampleFiles('test-cfdi40'); + + for (const xmlFile of testFiles) { + const xmlFilePath = `${examplesPath}/test-cfdi40/${xmlFile}`; + + it.skipIf(!saxonAvailable)(`${xmlFile}: output must match Saxon-HE`, () => { + compareSaxonVsTransform(xmlFilePath, xslt_40); + }); + + it(`${xmlFile}: cadena original should be valid`, () => { + const transform = new Transform(); + const cadena = transform.s(xmlFilePath).xsl(xslt_40).run(); + + expect(cadena).toBeTypeOf('string'); + expect(cadena.startsWith('||')).toBe(true); + expect(cadena.endsWith('||')).toBe(true); + expect(cadena.length).toBeGreaterThan(4); + }); + } +}); + +describe('transform vs saxon-he (test-cfdi33 con xslt 3.3)', () => { + const testFiles = getExampleFiles('test-cfdi33'); + + for (const xmlFile of testFiles) { + const xmlFilePath = `${examplesPath}/test-cfdi33/${xmlFile}`; + + it.skipIf(!saxonAvailable)(`${xmlFile}: output must match Saxon-HE`, () => { + compareSaxonVsTransform(xmlFilePath, xslt_33); + }); + + it(`${xmlFile}: cadena original should be valid`, () => { + const transform = new Transform(); + const cadena = transform.s(xmlFilePath).xsl(xslt_33).run(); + + expect(cadena).toBeTypeOf('string'); + expect(cadena.startsWith('||')).toBe(true); + expect(cadena.endsWith('||')).toBe(true); + expect(cadena.length).toBeGreaterThan(4); + }); + } +}); diff --git a/packages/cfdi/transform/test/xslt.test.ts b/packages/cfdi/transform/test/xslt.test.ts index 60e3b895..2aa2d850 100644 --- a/packages/cfdi/transform/test/xslt.test.ts +++ b/packages/cfdi/transform/test/xslt.test.ts @@ -1,22 +1,57 @@ -import { describe, expect, it, TaskContext, test, TestContext } from 'vitest'; +import { describe, expect, it } from 'vitest'; import path from 'path'; +import { parseXslt } from '../src'; + const files = path.resolve(__dirname, '..', '..', '..', 'files'); const xslt_path = `${files}/4.0/cadenaoriginal.xslt`; -import { ElementCompact, Element, Options, xml2js } from 'xml-js'; -import { readFileSync } from 'fs'; - - -describe('xslt', () => { - it('json', async (context: TaskContext) => { - const options: Options.XML2JS = { - ignoreComment: false, - alwaysChildren: false, - compact: false, - ignoreDeclaration: true, - //elementNameFn: (name: string) => original ? name : name.replace(/^.*:/, '') - }; - const xml = readFileSync(xslt_path, 'utf8') - const json = xml2js(xml, options); - console.log(JSON.stringify(json, null, 2)); + +describe('xslt parser', () => { + it('should parse cadenaoriginal.xslt and extract templates', () => { + const { templates } = parseXslt(xslt_path); + + expect(templates.size).toBeGreaterThan(0); + expect(templates.has('cfdi:Comprobante')).toBe(true); + expect(templates.has('cfdi:Emisor')).toBe(true); + expect(templates.has('cfdi:Receptor')).toBe(true); + expect(templates.has('cfdi:Concepto')).toBe(true); + expect(templates.has('cfdi:Impuestos')).toBe(true); + expect(templates.has('cfdi:Complemento')).toBe(true); + }); + + it('should parse complemento templates', () => { + const { templates } = parseXslt(xslt_path); + + expect(templates.has('vehiculousado:VehiculoUsado')).toBe(true); + expect(templates.has('pago20:Pagos')).toBe(true); + expect(templates.has('nomina12:Nomina')).toBe(true); + }); + + it('should extract correct attribute order for Comprobante', () => { + const { templates } = parseXslt(xslt_path); + const comprobante = templates.get('cfdi:Comprobante')!; + const attrRules = comprobante.rules.filter(r => r.type === 'attr'); + + expect(attrRules[0]).toEqual({ type: 'attr', name: 'Version', required: true }); + expect(attrRules[1]).toEqual({ type: 'attr', name: 'Serie', required: false }); + expect(attrRules[2]).toEqual({ type: 'attr', name: 'Folio', required: false }); + expect(attrRules[3]).toEqual({ type: 'attr', name: 'Fecha', required: true }); + }); + + it('should distinguish Requerido from Opcional', () => { + const { templates } = parseXslt(xslt_path); + const emisor = templates.get('cfdi:Emisor')!; + const attrRules = emisor.rules.filter(r => r.type === 'attr'); + + expect(attrRules[0]).toEqual({ type: 'attr', name: 'Rfc', required: true }); + expect(attrRules[3]).toEqual({ type: 'attr', name: 'FacAtrAdquirente', required: false }); + }); + + it('should extract namespaces from XSLT', () => { + const { namespaces } = parseXslt(xslt_path); + + expect(namespaces.get('cfdi')).toBe('http://www.sat.gob.mx/cfd/4'); + expect(namespaces.get('pago20')).toBe('http://www.sat.gob.mx/Pagos20'); + expect(namespaces.get('nomina12')).toBe('http://www.sat.gob.mx/nomina12'); + expect(namespaces.get('vehiculousado')).toBe('http://www.sat.gob.mx/vehiculousado'); }); }); diff --git a/packages/cfdi/transform/vite.config.mts b/packages/cfdi/transform/vite.config.mts new file mode 100644 index 00000000..78f30cf9 --- /dev/null +++ b/packages/cfdi/transform/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xml-js'], + }, + }, +})); diff --git a/packages/cfdi/types/README.md b/packages/cfdi/types/README.md index 9f7b855e..9bac2203 100644 --- a/packages/cfdi/types/README.md +++ b/packages/cfdi/types/README.md @@ -1,205 +1,115 @@ -# CFDI +# @cfdi/types -

- - Nest Logo -

-
    -
  • @cfdi/xml
  • +Definiciones de tipos TypeScript para CFDI 4.0. Proporciona interfaces y tipos para la estructura del comprobante fiscal, sus elementos y complementos. -
  • @cfdi/catalogos
  • @cfdi/csd
  • @cfdi/utils
  • @cfdi/pdf
  • @cfdi/curp +## Instalacion -
  • @cfdi/csf
  • -
  • @cfdi/rfc
-Documentacion -

- Este módulo genera un CFDI a partir de clases lo que facilita la creacion de XMl y sellarlo sin nigun problema de compatibilidad de las versiones 2.0 del xml de complementos. -

- -
- - - - -
- -Instala las dependencias and devDependencies y comienza a crear xml CFDI 4.0. -Para Windows Lea la Documentacion - -# Dependeces - -JDK - -```sh - sudo apt install default-jre - sudo apt install default-jdk -``` - -Openssl - -```sh - Debian/Ubuntu: sudo apt-get install openssl - CentOS, Red Hat: yum install openssl - Archlinux: sudo pacman -S openssl -``` - -Saxon-HE >=9.9.1.6J - -```sh - - official: http://saxon.sourceforge.net/ - Archlinux: https://aur.archlinux.org/packages/saxon-he - - Automatic Installation Alternative - - https://github.com/MisaelMa/saxon-he - sudo chmod 777 saxon.sh - sudo ./saxon.sh - - ███████╗ █████╗ ██╗ ██╗ ██████╗ ███╗ ██╗ ██╗ ██╗███████╗ - ██╔════╝██╔══██╗╚██╗██╔╝██╔═══██╗████╗ ██║ ██║ ██║██╔════╝ - ███████╗███████║ ╚███╔╝ ██║ ██║██╔██╗ ██║ ███████║█████╗ - ╚════██║██╔══██║ ██╔██╗ ██║ ██║██║╚██╗██║ ██╔══██║██╔══╝ - ███████║██║ ██║██╔╝ ██╗╚██████╔╝██║ ╚████║ ██║ ██║███████╗ - ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝ -``` - -# Installation - -```sh -npm i --save @cfdi/xml -``` - -# Complementos - -## Información adicional para las Facturas - -- [x] :pushpin: Timbre fiscal digital (TFD). -- [ ] Estado de cuenta de combustibles de monederos electrónicos. -- [x] :pushpin: Donatarias. -- [x] :pushpin: Compra venta de divisas. -- [x] :pushpin: Otros derechos e impuestos. -- [x] :pushpin: Leyendas fiscales. -- [x] :pushpin: Persona física integrante de coordinado. -- [x] :pushpin: Turista pasajero extranjero. -- [x] :pushpin: Spei de tercero a tercero. -- [ ] Sector de ventas al detalle (Detallista). -- [x] :pushpin: CFDI Registro fiscal. -- [ ] Recibo de pago de nómina. -- [x] :pushpin: Pago en especie. -- [x] :pushpin: Vales de despensa. -- [x] :pushpin: Consumo de combustibles. versión 1.1 -- [x] :pushpin: Aerolíneas. -- [ ] Notarios Públicos. -- [x] :pushpin: Vehículo usado. -- [x] :pushpin: Servicios parciales de construcción. -- [x] :pushpin: Renovación y sustitución de vehículos. -- [x] :pushpin: Certificado de destrucción -- [x] :pushpin: Obras de arte plásticas y antigüedades -- [x] :pushpin: INE -- [x] :pushpin: Comercio Exterior versión 1.1 -- [x] :pushpin: Recepción de pagos -- [x] Hidrocarburos - - [x] :pushpin: IngresosHidrocarburos - - [x] :pushpin: GastosHidrocarburos10 - -## Complementos de Concepto - -- [x] :pushpin: Instituciones educativas privadas. -- [ ] Venta de vehículos. -- [ ] Terceros. -- [ ] Acreditamiento del IEPS - -# Informacion Oficial - -- Certificados de prueba - http://omawww.sat.gob.mx/tramitesyservicios/Paginas/certificado_sello_digital.htm -- Anexo 20 - http://omawww.sat.gob.mx/tramitesyservicios/Paginas/anexo_20_version3-3.htm -- Catálogo de productos y servicios - http://pys.sat.gob.mx/PyS/catPyS.aspx -- Catálogo de unidades de medida - http://pys.sat.gob.mx/PyS/catUnidades.aspx -- Consulta los complementos y complementos concepto de factura - -https://www.sat.gob.mx/consultas/49522/complementos-y-complementos-concepto-de-factura- - -https://www.sat.gob.mx/cs/Satellite?blobcol=urldata&blobkey=id&blobtable=MungoBlobs&blobwhere=1461173971924&ssbinary=true - -# Generar archivos .pem - -Lo primero que se necesita es tener instalada la librería OpenSSL (programa dedicado a la generación y tratado de claves, certificados y keyStore) para poder utilizar los comandos que nos ayudarán a crear las llaves de nuestros sellos digitales. - -## Linux - -Instalar librería: - -Debian/Ubuntu: #sudo apt-get install openssl - -CentOS, Red Hat: #yum install openssl - -Ejecutar las instrucciones: - -Archivo key.pem - -```sh -openssl pkcs8 -inform DER -in nombrearchivo.key -out nombrearchivo.key.pem -passin pass:contraseña +```bash +npm install @cfdi/types ``` -archivo cer.pem - -```sh -openssl x509 -inform DER -outform PEM -in ruta/nombreArchivo.cer -pubkey -out ruta/nombreArchivo.cer.pem +## Uso + +```typescript +import { + XmlComprobante, + XmlConcepto, + XmlEmisor, + XmlReceptor, + XmlImpuestos, + XmlRelacionados, + CFDIComprobante, + XmlComplements, +} from '@cfdi/types'; + +// Definir atributos del comprobante +const comprobante: CFDIComprobante = { + Fecha: '2024-01-15T12:00:00', + SubTotal: '1000.00', + Total: '1160.00', + Moneda: 'MXN', + TipoDeComprobante: 'I', + Exportacion: '01', + MetodoPago: 'PUE', + FormaPago: '01', + LugarExpedicion: '12345', +}; ``` -## Windows - -Descargar libreria: http://slproweb.com/products/Win32OpenSSL.html +### Tipos de complementos -Deberán descargar la versión según su sistema operativo, e instalar. - -Ejecutar desde terminal - -Archivo key.pem - -```sh -openssl.exe pkcs8 -inform DER -in ruta/nombreArchivo.key -passin pass:contraseña -out ruta/nombreArchivo.key.pem +```typescript +import { + Ine, + Aerolineas, + CartaPorte20, + Pago20, + Iedu, +} from '@cfdi/types'; ``` -archivo cer.pem - -```sh -openssl.exe x509 -inform DER -outform PEM -in ruta/nombreArchivo.cer -pubkey -out ruta/nombreArchivo.cer.pem +### Tipos de configuracion + +```typescript +import type { + Config, + SaxonHe, + XsltSheet, + InvoiceType, + InvoiceRelation, + TaxSystem, +} from '@cfdi/types'; + +// Enums disponibles +InvoiceType.INGRESO; // 'I' +InvoiceType.EGRESO; // 'E' +InvoiceType.TRASLADO; // 'T' +InvoiceType.NOMINA; // 'N' +InvoiceType.PAGO; // 'P' ``` -# Generar QR - -ESPECIFICACIÓN TÉCNICA DEL CÓDIGO DE BARRAS BIDIMENSIONAL A INCORPORAR EN LA REPRESENTACIÓN IMPRESA. +## API -Las representaciones impresas de los dos tipos de comprobantes fiscales digitales por Internet deben incluir un código de barras bidimensional conforme al formato de QR Code (Quick Response Code),usando la capacidad de corrección de error con nivel mínimo M, descrito en el estándar ISO/IEC18004, con base en los siguientes lineamientos. +### Interfaces del comprobante -a) Debe contener los siguientes datos en la siguiente secuencia: +| Tipo | Descripcion | +|------|-------------| +| `XmlComprobante` | Estructura completa del nodo Comprobante | +| `CFDIComprobante` | Atributos del comprobante (Fecha, Total, Moneda, etc.) | +| `XmlEmisor` | Estructura del nodo Emisor | +| `XmlReceptor` | Estructura del nodo Receptor | +| `XmlConcepto` | Estructura del nodo Conceptos | +| `XmlImpuestos` | Estructura del nodo Impuestos | +| `XmlRelacionados` | Estructura del nodo CfdiRelacionados | +| `XmlComplements` | Estructura del nodo Complemento | - *La URL del acceso al servicio que pueda mostrar los datos de la versión publica del comprobante. - *Numero de folio fiscal del comprobante (UUID). - *RFC del emisor. - *RFC del receptor. - *Ocho últimos caracteres del sello digital del emisor del comprobante. +### Interfaces de complementos -Donde se manejan / caracteres conformados de la siguiente manera: +| Tipo | Descripcion | +|------|-------------| +| `Ine` | Complemento INE | +| `Aerolineas` | Complemento de aerolineas | +| `CartaPorte20` | Complemento carta porte 2.0 | +| `Pago20` | Complemento de pagos 2.0 | +| `Iedu` | Complemento instituciones educativas | -

- The house from the offer. -

+### Enums -De esta manera se generan los datos validos para realizar una consulta de un CFDI por medio de su expresión impresa. +| Enum | Descripcion | +|------|-------------| +| `InvoiceType` | Tipos de comprobante (I, E, T, N, P) | +| `InvoiceRelation` | Tipos de relacion entre CFDI | +| `TaxSystem` | Regimenes fiscales | -Ejemplo: +### Interfaces de configuracion -https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=5803EB8D-81CD-4557-8719-26632D2FA434&re=XAXX010101000&rr=CARR861127SB0&tt=0000014300.000000&fe=rH8/bw== +| Tipo | Descripcion | +|------|-------------| +| `Config` | Configuracion general del CFDI | +| `SaxonHe` | Configuracion del binario Saxon-HE | +| `XsltSheet` | Ruta a la hoja de transformacion XSLT | +| `Schema` | Ruta al esquema XSD | -El código de barras bidimensional debe ser impreso en un cuadro con lados no menores a 2.75 centímetros. +## Licencia -

-The house from the offer. -

+[MIT](../../LICENSE) diff --git a/packages/cfdi/types/config/index.js b/packages/cfdi/types/config/index.js deleted file mode 100644 index ca1e7edb..00000000 --- a/packages/cfdi/types/config/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict' -module.exports = require('./types.cjs.production.min.js') diff --git a/packages/cfdi/types/package.json b/packages/cfdi/types/package.json index 723d8118..01bbf39b 100644 --- a/packages/cfdi/types/package.json +++ b/packages/cfdi/types/package.json @@ -4,9 +4,9 @@ "description": "Libreria para crear y sellar xml cfdi V4.0", "homepage": "https://cfdi.recreando.dev", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/types.esm.production.min.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "release": { "branches": [ @@ -27,42 +27,15 @@ "url": "https://github.com/MisaelMa/recreando" }, "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build --env production --minify && rimraf ./dist/index.js ./dist/types.cjs.development.* && npm run cp", - "cp": "cp ./config/index.js ./dist", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", "test:coverage": "vitest run --coverage", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" + "test:ui": "vitest --ui" }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/types.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/types.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "@cfdi/catalogos": "workspace:*", "@cfdi/csd": "workspace:*", @@ -72,18 +45,11 @@ "xml-js": "^1.6.11" }, "devDependencies": { - "rimraf": "^6.0.1", "@recreando/vite": "workspace:*", "@recreando/eslint-settings": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@types/node": "^18.11.3", + "@types/node": "^22", "eslint": "^8.57.0", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/types/vite.config.mts b/packages/cfdi/types/vite.config.mts new file mode 100644 index 00000000..78f30cf9 --- /dev/null +++ b/packages/cfdi/types/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xml-js'], + }, + }, +})); diff --git a/packages/cfdi/utils/README.md b/packages/cfdi/utils/README.md index 9487075c..b40ae936 100644 --- a/packages/cfdi/utils/README.md +++ b/packages/cfdi/utils/README.md @@ -1 +1,61 @@ -utils +# @cfdi/utils + +Utilidades generales para el ecosistema CFDI. Incluye conversion de numeros a letras en español (para totales en facturas), manejo de logos y utilidades de archivos. + +## Instalacion + +```bash +npm install @cfdi/utils +``` + +## Uso + +### Numeros a letras + +```typescript +import { NumeroALetras } from '@cfdi/utils'; + +const converter = new NumeroALetras(); + +// Convertir numero a letras con moneda +converter.NumeroALetras(1234.56, { plural: 'PESOS', singular: 'PESO' }); +// "MIL DOSCIENTOS TREINTA Y CUATRO PESOS 56/100 M.N" + +converter.NumeroALetras(1, { plural: 'PESOS', singular: 'PESO' }); +// "UN PESO 00/100 M.N" + +converter.NumeroALetras(1000000); +// "UN MILLON" +``` + +### Logo + +```typescript +import { Logo } from '@cfdi/utils'; + +const logo = new Logo(); +// Manejo de logos para representacion impresa de CFDI +``` + +### Utilidades de archivo + +```typescript +import { isPath } from '@cfdi/utils'; + +// Detecta si un string es una ruta de archivo o contenido directo +isPath('/ruta/archivo.xml'); // true +isPath('contenido'); // false +``` + +## API + +| Export | Tipo | Descripcion | +|--------|------|-------------| +| `NumeroALetras` | clase | Convierte numeros a texto en español con formato de moneda | +| `Logo` | clase | Manejo de logos para PDF | +| `File` | clase | Utilidades de lectura de archivos | +| `isPath(input)` | funcion | Detecta si un string es ruta o contenido | + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/utils/package.json b/packages/cfdi/utils/package.json index 2d12482b..24cd8c84 100644 --- a/packages/cfdi/utils/package.json +++ b/packages/cfdi/utils/package.json @@ -2,66 +2,38 @@ "name": "@cfdi/utils", "version": "4.0.16", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/utils.esm.min.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "files": [ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "build": "tsdx build --env production --minify && rimraf ./dist/index.js ./dist/utils.cjs.development.*", - "cp": "cp ./config/index.js ./dist", - "start": "tsdx watch", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, - "dependencies": { "xml-js": "^1.6.11" }, "devDependencies": { - "rimraf": "^6.0.1", "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", "@recreando/vite": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", + "@types/node": "^22", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", "@vitest/coverage-v8": "2.1.3", "@vitest/ui": "2.1.3" }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, "publishConfig": { "registry": "https://registry.npmjs.org/", "access": "public" @@ -70,25 +42,9 @@ "type": "git", "url": "https://github.com/MisaelMa/recreando" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, "author": { "name": "Amir Misael Marin Coh, Signati", "email": "amisael.amir.misae@gmail.com, signatidev@gmail.com,", "url": "" - }, - "size-limit": [ - { - "path": "dist/utils.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/utils.esm.js", - "limit": "10 KB" - } - ] + } } diff --git a/packages/cfdi/utils/vite.config.mts b/packages/cfdi/utils/vite.config.mts new file mode 100644 index 00000000..78f30cf9 --- /dev/null +++ b/packages/cfdi/utils/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xml-js'], + }, + }, +})); diff --git a/packages/cfdi/validador/package.json b/packages/cfdi/validador/package.json new file mode 100644 index 00000000..72c83989 --- /dev/null +++ b/packages/cfdi/validador/package.json @@ -0,0 +1,47 @@ +{ + "name": "@cfdi/validador", + "version": "0.0.1", + "license": "MIT", + "main": "src/index.ts", + "module": "src/index.ts", + "types": "src/index.ts", + "source": "src/index.ts", + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org/", + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/MisaelMa/cfdi" + }, + "author": { + "name": "Amir Misael Marin Coh, Signati", + "email": "amisael.amir.misae@gmail.com, signatidev@gmail.com,", + "url": "" + }, + "dependencies": { + "xml-js": "^1.6.11" + }, + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/cfdi/validador/src/Validador.ts b/packages/cfdi/validador/src/Validador.ts new file mode 100644 index 00000000..609be154 --- /dev/null +++ b/packages/cfdi/validador/src/Validador.ts @@ -0,0 +1,50 @@ +import fs from 'fs'; +import { parseXml } from './parser'; +import * as rules from './rules'; +import type { ValidationIssue, ValidationResult, ValidationRule } from './types'; + +export class Validador { + private _rules: ValidationRule[]; + + constructor() { + this._rules = [ + ...rules.estructuraRules, + ...rules.montosRules, + ...rules.emisorRules, + ...rules.receptorRules, + ...rules.conceptosRules, + ...rules.impuestosRules, + ...rules.timbreRules, + ...rules.selloRules, + ]; + } + + validate(xml: string): ValidationResult { + const data = parseXml(xml); + const errors: ValidationIssue[] = []; + const warnings: ValidationIssue[] = []; + + for (const rule of this._rules) { + const issues = rule(data); + for (const issue of issues) { + if (issue.code.endsWith('W')) { + warnings.push(issue); + } else { + errors.push(issue); + } + } + } + + return { + valid: errors.length === 0, + errors, + warnings, + version: data.version, + }; + } + + validateFile(filePath: string): ValidationResult { + const xml = fs.readFileSync(filePath, 'utf-8'); + return this.validate(xml); + } +} diff --git a/packages/cfdi/validador/src/index.ts b/packages/cfdi/validador/src/index.ts new file mode 100644 index 00000000..68724d9c --- /dev/null +++ b/packages/cfdi/validador/src/index.ts @@ -0,0 +1,4 @@ +export { Validador } from './Validador'; +export { parseXml } from './parser'; +export * from './types'; +export * from './rules'; diff --git a/packages/cfdi/validador/src/parser.ts b/packages/cfdi/validador/src/parser.ts new file mode 100644 index 00000000..29c8fad2 --- /dev/null +++ b/packages/cfdi/validador/src/parser.ts @@ -0,0 +1,166 @@ +import xmljs from 'xml-js'; +import type { + CfdiData, + ConceptoData, + ImpuestosData, + TimbreData, +} from './types'; + +/** + * Strips namespace prefix from element/attribute name. + * e.g. "cfdi:Comprobante" -> "Comprobante", "tfd:TimbreFiscalDigital" -> "TimbreFiscalDigital" + */ +function stripNs(name: string): string { + const idx = name.indexOf(':'); + return idx >= 0 ? name.slice(idx + 1) : name; +} + +/** + * Normalizes attributes Record by stripping namespaces from keys. + */ +function normalizeAttrs( + attrs: Record | undefined +): Record { + if (!attrs) return {}; + const result: Record = {}; + for (const [k, v] of Object.entries(attrs)) { + result[stripNs(k)] = String(v ?? ''); + } + return result; +} + +/** + * Finds a child element by local name (ignoring namespace prefix). + */ +function findChild( + elements: xmljs.Element[] | undefined, + localName: string +): xmljs.Element | undefined { + if (!elements) return undefined; + return elements.find( + el => el.type === 'element' && stripNs(el.name ?? '') === localName + ); +} + +/** + * Finds all children with a given local name. + */ +function findChildren( + elements: xmljs.Element[] | undefined, + localName: string +): xmljs.Element[] { + if (!elements) return []; + return elements.filter( + el => el.type === 'element' && stripNs(el.name ?? '') === localName + ); +} + +function parseTraslados( + impuestosEl: xmljs.Element | undefined +): Record[] { + const trasladosEl = findChild(impuestosEl?.elements, 'Traslados'); + return findChildren(trasladosEl?.elements, 'Traslado').map(t => + normalizeAttrs(t.attributes as Record) + ); +} + +function parseRetenciones( + impuestosEl: xmljs.Element | undefined +): Record[] { + const retencionesEl = findChild(impuestosEl?.elements, 'Retenciones'); + return findChildren(retencionesEl?.elements, 'Retencion').map(r => + normalizeAttrs(r.attributes as Record) + ); +} + +function parseConcepto(conceptoEl: xmljs.Element): ConceptoData { + const attributes = normalizeAttrs( + conceptoEl.attributes as Record + ); + const impuestosEl = findChild(conceptoEl.elements, 'Impuestos'); + + if (!impuestosEl) { + return { attributes }; + } + + return { + attributes, + impuestos: { + traslados: parseTraslados(impuestosEl), + retenciones: parseRetenciones(impuestosEl), + }, + }; +} + +function parseImpuestos( + impuestosEl: xmljs.Element | undefined +): ImpuestosData | undefined { + if (!impuestosEl) return undefined; + const attrs = normalizeAttrs(impuestosEl.attributes as Record); + return { + totalImpuestosTrasladados: attrs['TotalImpuestosTrasladados'], + totalImpuestosRetenidos: attrs['TotalImpuestosRetenidos'], + traslados: parseTraslados(impuestosEl), + retenciones: parseRetenciones(impuestosEl), + }; +} + +function parseTimbre( + complementoEl: xmljs.Element | undefined +): TimbreData | undefined { + if (!complementoEl) return undefined; + const tfdEl = findChild(complementoEl.elements, 'TimbreFiscalDigital'); + if (!tfdEl) return undefined; + const attrs = normalizeAttrs(tfdEl.attributes as Record); + return { + uuid: attrs['UUID'] ?? '', + fechaTimbrado: attrs['FechaTimbrado'] ?? '', + rfcProvCertif: attrs['RfcProvCertif'] ?? '', + selloCFD: attrs['SelloCFD'] ?? '', + selloSAT: attrs['SelloSAT'] ?? '', + noCertificadoSAT: attrs['NoCertificadoSAT'] ?? '', + version: attrs['Version'] ?? '', + }; +} + +export function parseXml(xml: string): CfdiData { + const doc = xmljs.xml2js(xml, { + compact: false, + ignoreComment: true, + ignoreDeclaration: true, + ignoreInstruction: true, + ignoreDoctype: true, + }) as xmljs.Element; + + const comprobante = findChild(doc.elements, 'Comprobante'); + if (!comprobante) { + throw new Error( + 'XML no contiene el elemento Comprobante en el namespace cfdi' + ); + } + + const comprobanteAttrs = normalizeAttrs( + comprobante.attributes as Record + ); + const version = comprobanteAttrs['Version'] ?? ''; + + const emisorEl = findChild(comprobante.elements, 'Emisor'); + const receptorEl = findChild(comprobante.elements, 'Receptor'); + const conceptosEl = findChild(comprobante.elements, 'Conceptos'); + const impuestosEl = findChild(comprobante.elements, 'Impuestos'); + const complementoEl = findChild(comprobante.elements, 'Complemento'); + + const conceptoEls = findChildren(conceptosEl?.elements, 'Concepto'); + + return { + version, + comprobante: comprobanteAttrs, + emisor: normalizeAttrs(emisorEl?.attributes as Record), + receptor: normalizeAttrs(receptorEl?.attributes as Record), + conceptos: conceptoEls.map(parseConcepto), + impuestos: parseImpuestos(impuestosEl), + complemento: complementoEl ?? undefined, + timbre: parseTimbre(complementoEl), + raw: xml, + }; +} diff --git a/packages/cfdi/validador/src/rules/conceptos.ts b/packages/cfdi/validador/src/rules/conceptos.ts new file mode 100644 index 00000000..22ec118e --- /dev/null +++ b/packages/cfdi/validador/src/rules/conceptos.ts @@ -0,0 +1,136 @@ +import type { CfdiData, ConceptoData, ValidationIssue, ValidationRule } from '../types'; + +const TOLERANCIA = 0.011; + +function parseDecimal(val: string | undefined): number | null { + if (val === undefined || val === null || val === '') return null; + const n = parseFloat(val); + return isNaN(n) ? null : n; +} + +function checkConceptoMinimo(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + if (data.conceptos.length === 0) { + issues.push({ + code: 'CFDI501', + message: 'El CFDI debe tener al menos un Concepto', + field: 'Conceptos', + rule: 'conceptos.minimo', + }); + } + return issues; +} + +function checkConcepto( + concepto: ConceptoData, + idx: number, + version: string +): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const attrs = concepto.attributes; + const prefix = `Conceptos[${idx}]`; + + const camposRequeridos = [ + 'ClaveProdServ', + 'Cantidad', + 'ClaveUnidad', + 'Descripcion', + 'ValorUnitario', + 'Importe', + ]; + + for (const campo of camposRequeridos) { + if (attrs[campo] === undefined || attrs[campo] === null) { + issues.push({ + code: 'CFDI502', + message: `Campo requerido '${campo}' no presente en Concepto[${idx}]`, + field: `${prefix}.${campo}`, + rule: 'conceptos.camposRequeridos', + }); + } + } + + const cantidad = parseDecimal(attrs['Cantidad']); + if (cantidad !== null && cantidad <= 0) { + issues.push({ + code: 'CFDI503', + message: `Cantidad en Concepto[${idx}] debe ser mayor a 0, valor actual: ${attrs['Cantidad']}`, + field: `${prefix}.Cantidad`, + rule: 'conceptos.cantidad', + }); + } + + const valorUnitario = parseDecimal(attrs['ValorUnitario']); + if (valorUnitario !== null && valorUnitario < 0) { + issues.push({ + code: 'CFDI504', + message: `ValorUnitario en Concepto[${idx}] no puede ser negativo: ${attrs['ValorUnitario']}`, + field: `${prefix}.ValorUnitario`, + rule: 'conceptos.valorUnitario', + }); + } + + const importe = parseDecimal(attrs['Importe']); + if (importe !== null && importe < 0) { + issues.push({ + code: 'CFDI505', + message: `Importe en Concepto[${idx}] no puede ser negativo: ${attrs['Importe']}`, + field: `${prefix}.Importe`, + rule: 'conceptos.importe', + }); + } + + if ( + cantidad !== null && + valorUnitario !== null && + importe !== null + ) { + const importeEsperado = cantidad * valorUnitario; + const diferencia = Math.abs(importe - importeEsperado); + if (diferencia > TOLERANCIA) { + issues.push({ + code: 'CFDI506', + message: `Importe en Concepto[${idx}] (${importe}) no coincide con Cantidad * ValorUnitario = ${importeEsperado.toFixed(6)} (diferencia: ${diferencia.toFixed(6)})`, + field: `${prefix}.Importe`, + rule: 'conceptos.importeCalculado', + }); + } + } + + const descuento = parseDecimal(attrs['Descuento']); + if (descuento !== null && importe !== null && descuento > importe + TOLERANCIA) { + issues.push({ + code: 'CFDI507', + message: `Descuento en Concepto[${idx}] (${descuento}) no puede ser mayor al Importe (${importe})`, + field: `${prefix}.Descuento`, + rule: 'conceptos.descuento', + }); + } + + if (version === '4.0') { + const objetoImp = attrs['ObjetoImp']; + if (!objetoImp || objetoImp.trim() === '') { + issues.push({ + code: 'CFDI508', + message: `ObjetoImp es requerido en Concepto[${idx}] para CFDI 4.0`, + field: `${prefix}.ObjetoImp`, + rule: 'conceptos.objetoImp', + }); + } + } + + return issues; +} + +function checkConceptos(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + data.conceptos.forEach((concepto, idx) => { + issues.push(...checkConcepto(concepto, idx, data.version)); + }); + return issues; +} + +export const conceptosRules: ValidationRule[] = [ + checkConceptoMinimo, + checkConceptos, +]; diff --git a/packages/cfdi/validador/src/rules/emisor.ts b/packages/cfdi/validador/src/rules/emisor.ts new file mode 100644 index 00000000..849c89e5 --- /dev/null +++ b/packages/cfdi/validador/src/rules/emisor.ts @@ -0,0 +1,75 @@ +import type { CfdiData, ValidationIssue, ValidationRule } from '../types'; + +const RFC_REGEX_PM = /^[A-Z&Ñ]{3}[0-9]{6}[A-Z0-9]{3}$/; +const RFC_REGEX_PF = /^[A-Z&Ñ]{4}[0-9]{6}[A-Z0-9]{3}$/; +const RFC_GENERICO = /^(XAXX010101000|XEXX010101000)$/; + +function isRfcValido(rfc: string): boolean { + if (!rfc) return false; + if (RFC_GENERICO.test(rfc)) return true; + return RFC_REGEX_PM.test(rfc) || RFC_REGEX_PF.test(rfc); +} + +function checkRfcEmisor(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const rfc = data.emisor['Rfc']; + + if (!rfc) { + issues.push({ + code: 'CFDI301', + message: 'RFC del Emisor es requerido', + field: 'Emisor.Rfc', + rule: 'emisor.rfc', + }); + return issues; + } + + if (!isRfcValido(rfc)) { + issues.push({ + code: 'CFDI302', + message: `RFC del Emisor '${rfc}' no tiene un formato valido (12 chars PM o 13 chars PF)`, + field: 'Emisor.Rfc', + rule: 'emisor.rfc', + }); + } + + return issues; +} + +function checkNombreEmisor(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const nombre = data.emisor['Nombre']; + + if (data.version === '4.0' && (!nombre || nombre.trim() === '')) { + issues.push({ + code: 'CFDI303', + message: 'Nombre del Emisor es requerido en CFDI 4.0', + field: 'Emisor.Nombre', + rule: 'emisor.nombre', + }); + } + + return issues; +} + +function checkRegimenFiscalEmisor(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const regimen = data.emisor['RegimenFiscal']; + + if (!regimen || regimen.trim() === '') { + issues.push({ + code: 'CFDI304', + message: 'RegimenFiscal del Emisor es requerido', + field: 'Emisor.RegimenFiscal', + rule: 'emisor.regimenFiscal', + }); + } + + return issues; +} + +export const emisorRules: ValidationRule[] = [ + checkRfcEmisor, + checkNombreEmisor, + checkRegimenFiscalEmisor, +]; diff --git a/packages/cfdi/validador/src/rules/estructura.ts b/packages/cfdi/validador/src/rules/estructura.ts new file mode 100644 index 00000000..058119fb --- /dev/null +++ b/packages/cfdi/validador/src/rules/estructura.ts @@ -0,0 +1,152 @@ +import type { CfdiData, ValidationIssue, ValidationRule } from '../types'; + +const VERSIONES_VALIDAS = ['3.3', '4.0']; +const TIPOS_COMPROBANTE = ['I', 'E', 'T', 'P', 'N']; + +const CAMPOS_REQUERIDOS_COMUNES = [ + 'Version', + 'Fecha', + 'LugarExpedicion', + 'Moneda', + 'SubTotal', + 'Total', + 'TipoDeComprobante', + 'NoCertificado', + 'Sello', + 'Certificado', +]; + +const CAMPOS_REQUERIDOS_40 = ['Exportacion']; + +function checkVersion(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + if (!VERSIONES_VALIDAS.includes(data.version)) { + issues.push({ + code: 'CFDI001', + message: `Version '${data.version}' no es valida. Se esperaba 3.3 o 4.0`, + field: 'Version', + rule: 'estructura.version', + }); + } + return issues; +} + +function checkCamposRequeridos(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const campos = + data.version === '4.0' + ? [...CAMPOS_REQUERIDOS_COMUNES, ...CAMPOS_REQUERIDOS_40] + : CAMPOS_REQUERIDOS_COMUNES; + + for (const campo of campos) { + if ( + data.comprobante[campo] === undefined || + data.comprobante[campo] === null + ) { + issues.push({ + code: 'CFDI002', + message: `Campo requerido '${campo}' no esta presente en el Comprobante`, + field: campo, + rule: 'estructura.camposRequeridos', + }); + } + } + return issues; +} + +function checkTipoDeComprobante(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const tipo = data.comprobante['TipoDeComprobante']; + if (tipo && !TIPOS_COMPROBANTE.includes(tipo)) { + issues.push({ + code: 'CFDI003', + message: `TipoDeComprobante '${tipo}' no es valido. Valores permitidos: ${TIPOS_COMPROBANTE.join(', ')}`, + field: 'TipoDeComprobante', + rule: 'estructura.tipoDeComprobante', + }); + } + return issues; +} + +function checkTipoTraslado(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const tipo = data.comprobante['TipoDeComprobante']; + if (tipo === 'T') { + const subtotal = data.comprobante['SubTotal']; + const total = data.comprobante['Total']; + if (subtotal !== '0' && subtotal !== '0.00') { + issues.push({ + code: 'CFDI004', + message: + "Para TipoDeComprobante='T' (Traslado), SubTotal debe ser '0'", + field: 'SubTotal', + rule: 'estructura.tipoTraslado', + }); + } + if (total !== '0' && total !== '0.00') { + issues.push({ + code: 'CFDI005', + message: "Para TipoDeComprobante='T' (Traslado), Total debe ser '0'", + field: 'Total', + rule: 'estructura.tipoTraslado', + }); + } + } + return issues; +} + +function checkMonedaTipoCambio(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const moneda = data.comprobante['Moneda']; + const tipoCambio = data.comprobante['TipoCambio']; + + if (moneda === 'XXX' && tipoCambio !== undefined) { + issues.push({ + code: 'CFDI006', + message: "Cuando Moneda='XXX', no debe existir el atributo TipoCambio", + field: 'TipoCambio', + rule: 'estructura.monedaTipoCambio', + }); + } + + if ( + moneda && + moneda !== 'MXN' && + moneda !== 'XXX' && + tipoCambio === undefined + ) { + issues.push({ + code: 'CFDI007', + message: `Cuando Moneda='${moneda}' (distinta de MXN y XXX), TipoCambio es requerido`, + field: 'TipoCambio', + rule: 'estructura.monedaTipoCambio', + }); + } + return issues; +} + +function checkFecha(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const fecha = data.comprobante['Fecha']; + if (fecha) { + const ISO_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/; + if (!ISO_REGEX.test(fecha)) { + issues.push({ + code: 'CFDI008', + message: `Fecha '${fecha}' no tiene el formato ISO 8601 requerido (YYYY-MM-DDTHH:mm:ss)`, + field: 'Fecha', + rule: 'estructura.fecha', + }); + } + } + return issues; +} + +export const estructuraRules: ValidationRule[] = [ + checkVersion, + checkCamposRequeridos, + checkTipoDeComprobante, + checkTipoTraslado, + checkMonedaTipoCambio, + checkFecha, +]; diff --git a/packages/cfdi/validador/src/rules/impuestos.ts b/packages/cfdi/validador/src/rules/impuestos.ts new file mode 100644 index 00000000..ff5101b7 --- /dev/null +++ b/packages/cfdi/validador/src/rules/impuestos.ts @@ -0,0 +1,180 @@ +import type { CfdiData, ValidationIssue, ValidationRule } from '../types'; + +const TOLERANCIA = 0.011; +const IMPUESTOS_VALIDOS = ['001', '002', '003']; +const TIPOS_FACTOR_VALIDOS = ['Tasa', 'Cuota', 'Exento']; + +function parseDecimal(val: string | undefined): number | null { + if (val === undefined || val === null || val === '') return null; + const n = parseFloat(val); + return isNaN(n) ? null : n; +} + +function checkImpuesto( + val: string | undefined, + prefix: string +): ValidationIssue | null { + if (!val) return null; + if (!IMPUESTOS_VALIDOS.includes(val)) { + return { + code: 'CFDI601', + message: `Impuesto '${val}' en ${prefix} no es valido. Valores permitidos: ${IMPUESTOS_VALIDOS.join(', ')} (001=ISR, 002=IVA, 003=IEPS)`, + field: `${prefix}.Impuesto`, + rule: 'impuestos.impuestoValido', + }; + } + return null; +} + +function checkTipoFactor( + val: string | undefined, + prefix: string +): ValidationIssue | null { + if (!val) return null; + if (!TIPOS_FACTOR_VALIDOS.includes(val)) { + return { + code: 'CFDI602', + message: `TipoFactor '${val}' en ${prefix} no es valido. Valores permitidos: ${TIPOS_FACTOR_VALIDOS.join(', ')}`, + field: `${prefix}.TipoFactor`, + rule: 'impuestos.tipoFactor', + }; + } + return null; +} + +function checkExento( + traslado: Record, + prefix: string +): ValidationIssue[] { + const issues: ValidationIssue[] = []; + if (traslado['TipoFactor'] === 'Exento') { + if (traslado['TasaOCuota'] !== undefined) { + issues.push({ + code: 'CFDI603', + message: `TasaOCuota no debe estar presente cuando TipoFactor='Exento' en ${prefix}`, + field: `${prefix}.TasaOCuota`, + rule: 'impuestos.exento', + }); + } + if (traslado['Importe'] !== undefined) { + issues.push({ + code: 'CFDI604', + message: `Importe no debe estar presente cuando TipoFactor='Exento' en ${prefix}`, + field: `${prefix}.Importe`, + rule: 'impuestos.exento', + }); + } + } + return issues; +} + +function checkTrasladosConcepto(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + + data.conceptos.forEach((concepto, ci) => { + const traslados = concepto.impuestos?.traslados ?? []; + traslados.forEach((t, ti) => { + const prefix = `Concepto[${ci}].Impuestos.Traslados[${ti}]`; + const impIssue = checkImpuesto(t['Impuesto'], prefix); + if (impIssue) issues.push(impIssue); + const factorIssue = checkTipoFactor(t['TipoFactor'], prefix); + if (factorIssue) issues.push(factorIssue); + issues.push(...checkExento(t, prefix)); + }); + + const retenciones = concepto.impuestos?.retenciones ?? []; + retenciones.forEach((r, ri) => { + const prefix = `Concepto[${ci}].Impuestos.Retenciones[${ri}]`; + const impIssue = checkImpuesto(r['Impuesto'], prefix); + if (impIssue) issues.push(impIssue); + }); + }); + + return issues; +} + +function checkTrasladosGlobales(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + if (!data.impuestos) return issues; + + data.impuestos.traslados.forEach((t, i) => { + const prefix = `Impuestos.Traslados[${i}]`; + const impIssue = checkImpuesto(t['Impuesto'], prefix); + if (impIssue) issues.push(impIssue); + const factorIssue = checkTipoFactor(t['TipoFactor'], prefix); + if (factorIssue) issues.push(factorIssue); + issues.push(...checkExento(t, prefix)); + }); + + data.impuestos.retenciones.forEach((r, i) => { + const prefix = `Impuestos.Retenciones[${i}]`; + const impIssue = checkImpuesto(r['Impuesto'], prefix); + if (impIssue) issues.push(impIssue); + }); + + return issues; +} + +function checkSumaTrasladados(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const totalDeclarado = parseDecimal( + data.impuestos?.totalImpuestosTrasladados + ); + if (totalDeclarado === null) return issues; + + // Sum traslados from conceptos (excluding Exento which have no Importe) + let sumaConceptos = 0; + for (const concepto of data.conceptos) { + for (const t of concepto.impuestos?.traslados ?? []) { + if (t['TipoFactor'] !== 'Exento') { + const imp = parseDecimal(t['Importe']); + if (imp !== null) sumaConceptos += imp; + } + } + } + + const diferencia = Math.abs(totalDeclarado - sumaConceptos); + if (diferencia > TOLERANCIA) { + issues.push({ + code: 'CFDI605', + message: `TotalImpuestosTrasladados (${totalDeclarado}) no coincide con la suma de traslados en conceptos (${sumaConceptos.toFixed(2)}) (diferencia: ${diferencia.toFixed(6)})`, + field: 'Impuestos.TotalImpuestosTrasladados', + rule: 'impuestos.sumaTrasladados', + }); + } + + return issues; +} + +function checkSumaRetenidos(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const totalDeclarado = parseDecimal(data.impuestos?.totalImpuestosRetenidos); + if (totalDeclarado === null) return issues; + + let sumaConceptos = 0; + for (const concepto of data.conceptos) { + for (const r of concepto.impuestos?.retenciones ?? []) { + const imp = parseDecimal(r['Importe']); + if (imp !== null) sumaConceptos += imp; + } + } + + const diferencia = Math.abs(totalDeclarado - sumaConceptos); + if (diferencia > TOLERANCIA) { + issues.push({ + code: 'CFDI606', + message: `TotalImpuestosRetenidos (${totalDeclarado}) no coincide con la suma de retenciones en conceptos (${sumaConceptos.toFixed(2)}) (diferencia: ${diferencia.toFixed(6)})`, + field: 'Impuestos.TotalImpuestosRetenidos', + rule: 'impuestos.sumaRetenidos', + }); + } + + return issues; +} + +export const impuestosRules: ValidationRule[] = [ + checkTrasladosConcepto, + checkTrasladosGlobales, + checkSumaTrasladados, + checkSumaRetenidos, +]; diff --git a/packages/cfdi/validador/src/rules/index.ts b/packages/cfdi/validador/src/rules/index.ts new file mode 100644 index 00000000..a24831ea --- /dev/null +++ b/packages/cfdi/validador/src/rules/index.ts @@ -0,0 +1,8 @@ +export { estructuraRules } from './estructura'; +export { montosRules } from './montos'; +export { emisorRules } from './emisor'; +export { receptorRules } from './receptor'; +export { conceptosRules } from './conceptos'; +export { impuestosRules } from './impuestos'; +export { timbreRules } from './timbre'; +export { selloRules } from './sello'; diff --git a/packages/cfdi/validador/src/rules/montos.ts b/packages/cfdi/validador/src/rules/montos.ts new file mode 100644 index 00000000..c7e5a032 --- /dev/null +++ b/packages/cfdi/validador/src/rules/montos.ts @@ -0,0 +1,160 @@ +import type { CfdiData, ValidationIssue, ValidationRule } from '../types'; + +const MAX_DECIMALES = 6; +const TOLERANCIA = 0.01; + +function parseDecimal(val: string | undefined): number | null { + if (val === undefined || val === null || val === '') return null; + const n = parseFloat(val); + return isNaN(n) ? null : n; +} + +function countDecimals(val: string): number { + const parts = val.split('.'); + return parts.length > 1 ? parts[1].length : 0; +} + +function checkDecimales( + val: string | undefined, + field: string, + rule: string +): ValidationIssue | null { + if (!val) return null; + if (countDecimals(val) > MAX_DECIMALES) { + return { + code: 'CFDI201', + message: `El campo '${field}' tiene mas de ${MAX_DECIMALES} decimales: '${val}'`, + field, + rule, + }; + } + return null; +} + +function checkSubTotal(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const val = data.comprobante['SubTotal']; + const n = parseDecimal(val); + + if (val !== undefined && n === null) { + issues.push({ + code: 'CFDI202', + message: `SubTotal '${val}' no es un numero valido`, + field: 'SubTotal', + rule: 'montos.subtotal', + }); + return issues; + } + + if (n !== null && n < 0) { + issues.push({ + code: 'CFDI203', + message: `SubTotal no puede ser negativo: '${val}'`, + field: 'SubTotal', + rule: 'montos.subtotal', + }); + } + + const dec = checkDecimales(val, 'SubTotal', 'montos.subtotal'); + if (dec) issues.push(dec); + + return issues; +} + +function checkTotal(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const val = data.comprobante['Total']; + const n = parseDecimal(val); + + if (val !== undefined && n === null) { + issues.push({ + code: 'CFDI204', + message: `Total '${val}' no es un numero valido`, + field: 'Total', + rule: 'montos.total', + }); + return issues; + } + + if (n !== null && n < 0) { + issues.push({ + code: 'CFDI205', + message: `Total no puede ser negativo: '${val}'`, + field: 'Total', + rule: 'montos.total', + }); + } + + const dec = checkDecimales(val, 'Total', 'montos.total'); + if (dec) issues.push(dec); + + return issues; +} + +function checkDescuento(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const descuentoVal = data.comprobante['Descuento']; + if (descuentoVal === undefined) return issues; + + const descuento = parseDecimal(descuentoVal); + const subtotal = parseDecimal(data.comprobante['SubTotal']); + + if (descuento === null) { + issues.push({ + code: 'CFDI206', + message: `Descuento '${descuentoVal}' no es un numero valido`, + field: 'Descuento', + rule: 'montos.descuento', + }); + return issues; + } + + if (subtotal !== null && descuento > subtotal + TOLERANCIA) { + issues.push({ + code: 'CFDI207', + message: `Descuento (${descuento}) no puede ser mayor que SubTotal (${subtotal})`, + field: 'Descuento', + rule: 'montos.descuento', + }); + } + + const dec = checkDecimales(descuentoVal, 'Descuento', 'montos.descuento'); + if (dec) issues.push(dec); + + return issues; +} + +function checkTotalCalculado(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const subtotal = parseDecimal(data.comprobante['SubTotal']); + const total = parseDecimal(data.comprobante['Total']); + const descuento = parseDecimal(data.comprobante['Descuento']) ?? 0; + const trasladados = parseDecimal( + data.impuestos?.totalImpuestosTrasladados + ) ?? 0; + const retenidos = parseDecimal(data.impuestos?.totalImpuestosRetenidos) ?? 0; + + if (subtotal === null || total === null) return issues; + + const totalEsperado = + subtotal - descuento + trasladados - retenidos; + const diferencia = Math.abs(total - totalEsperado); + + if (diferencia > TOLERANCIA) { + issues.push({ + code: 'CFDI208', + message: `Total (${total}) no coincide con SubTotal - Descuento + TotalImpuestosTrasladados - TotalImpuestosRetenidos = ${totalEsperado.toFixed(2)} (diferencia: ${diferencia.toFixed(6)})`, + field: 'Total', + rule: 'montos.totalCalculado', + }); + } + + return issues; +} + +export const montosRules: ValidationRule[] = [ + checkSubTotal, + checkTotal, + checkDescuento, + checkTotalCalculado, +]; diff --git a/packages/cfdi/validador/src/rules/receptor.ts b/packages/cfdi/validador/src/rules/receptor.ts new file mode 100644 index 00000000..1aedece3 --- /dev/null +++ b/packages/cfdi/validador/src/rules/receptor.ts @@ -0,0 +1,102 @@ +import type { CfdiData, ValidationIssue, ValidationRule } from '../types'; + +const RFC_REGEX_PM = /^[A-Z&Ñ]{3}[0-9]{6}[A-Z0-9]{3}$/; +const RFC_REGEX_PF = /^[A-Z&Ñ]{4}[0-9]{6}[A-Z0-9]{3}$/; +const RFC_GENERICO = /^(XAXX010101000|XEXX010101000)$/; +const CODIGO_POSTAL_REGEX = /^\d{5}$/; + +function isRfcValido(rfc: string): boolean { + if (!rfc) return false; + if (RFC_GENERICO.test(rfc)) return true; + return RFC_REGEX_PM.test(rfc) || RFC_REGEX_PF.test(rfc); +} + +function checkRfcReceptor(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const rfc = data.receptor['Rfc']; + + if (!rfc) { + issues.push({ + code: 'CFDI401', + message: 'RFC del Receptor es requerido', + field: 'Receptor.Rfc', + rule: 'receptor.rfc', + }); + return issues; + } + + if (!isRfcValido(rfc)) { + issues.push({ + code: 'CFDI402', + message: `RFC del Receptor '${rfc}' no tiene un formato valido (12 chars PM o 13 chars PF)`, + field: 'Receptor.Rfc', + rule: 'receptor.rfc', + }); + } + + return issues; +} + +function checkUsoCFDI(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const uso = data.receptor['UsoCFDI']; + + if (!uso || uso.trim() === '') { + issues.push({ + code: 'CFDI403', + message: 'UsoCFDI del Receptor es requerido', + field: 'Receptor.UsoCFDI', + rule: 'receptor.usoCFDI', + }); + } + + return issues; +} + +function checkDomicilioFiscal40(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + if (data.version !== '4.0') return issues; + + const domicilio = data.receptor['DomicilioFiscalReceptor']; + if (!domicilio || domicilio.trim() === '') { + issues.push({ + code: 'CFDI404', + message: 'DomicilioFiscalReceptor es requerido en CFDI 4.0', + field: 'Receptor.DomicilioFiscalReceptor', + rule: 'receptor.domicilioFiscal', + }); + } else if (!CODIGO_POSTAL_REGEX.test(domicilio)) { + issues.push({ + code: 'CFDI405', + message: `DomicilioFiscalReceptor '${domicilio}' debe ser un codigo postal de 5 digitos`, + field: 'Receptor.DomicilioFiscalReceptor', + rule: 'receptor.domicilioFiscal', + }); + } + + return issues; +} + +function checkRegimenFiscalReceptor40(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + if (data.version !== '4.0') return issues; + + const regimen = data.receptor['RegimenFiscalReceptor']; + if (!regimen || regimen.trim() === '') { + issues.push({ + code: 'CFDI406', + message: 'RegimenFiscalReceptor es requerido en CFDI 4.0', + field: 'Receptor.RegimenFiscalReceptor', + rule: 'receptor.regimenFiscal', + }); + } + + return issues; +} + +export const receptorRules: ValidationRule[] = [ + checkRfcReceptor, + checkUsoCFDI, + checkDomicilioFiscal40, + checkRegimenFiscalReceptor40, +]; diff --git a/packages/cfdi/validador/src/rules/sello.ts b/packages/cfdi/validador/src/rules/sello.ts new file mode 100644 index 00000000..ef503b1c --- /dev/null +++ b/packages/cfdi/validador/src/rules/sello.ts @@ -0,0 +1,93 @@ +import type { CfdiData, ValidationIssue, ValidationRule } from '../types'; + +const NO_CERTIFICADO_REGEX = /^\d{20}$/; +const BASE64_REGEX = /^[A-Za-z0-9+/]*={0,2}$/; + +function isBase64Valido(val: string): boolean { + if (!val || val.trim() === '') return true; // empty is ok — not present + return BASE64_REGEX.test(val) && val.length % 4 === 0; +} + +function checkNoCertificado(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const noCert = data.comprobante['NoCertificado']; + + if (noCert === undefined || noCert === null) { + issues.push({ + code: 'CFDI801', + message: 'NoCertificado es requerido en el Comprobante', + field: 'NoCertificado', + rule: 'sello.noCertificado', + }); + return issues; + } + + if (noCert !== '' && !NO_CERTIFICADO_REGEX.test(noCert)) { + issues.push({ + code: 'CFDI802', + message: `NoCertificado '${noCert}' debe tener exactamente 20 digitos numericos`, + field: 'NoCertificado', + rule: 'sello.noCertificado', + }); + } + + return issues; +} + +function checkSello(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const sello = data.comprobante['Sello']; + + if (sello === undefined || sello === null) { + issues.push({ + code: 'CFDI803', + message: 'Sello es requerido en el Comprobante', + field: 'Sello', + rule: 'sello.sello', + }); + return issues; + } + + if (sello !== '' && !isBase64Valido(sello)) { + issues.push({ + code: 'CFDI804', + message: 'Sello no es una cadena base64 valida', + field: 'Sello', + rule: 'sello.sello', + }); + } + + return issues; +} + +function checkCertificado(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + const certificado = data.comprobante['Certificado']; + + if (certificado === undefined || certificado === null) { + issues.push({ + code: 'CFDI805', + message: 'Certificado es requerido en el Comprobante', + field: 'Certificado', + rule: 'sello.certificado', + }); + return issues; + } + + if (certificado !== '' && !isBase64Valido(certificado)) { + issues.push({ + code: 'CFDI806', + message: 'Certificado no es una cadena base64 valida', + field: 'Certificado', + rule: 'sello.certificado', + }); + } + + return issues; +} + +export const selloRules: ValidationRule[] = [ + checkNoCertificado, + checkSello, + checkCertificado, +]; diff --git a/packages/cfdi/validador/src/rules/timbre.ts b/packages/cfdi/validador/src/rules/timbre.ts new file mode 100644 index 00000000..bb158155 --- /dev/null +++ b/packages/cfdi/validador/src/rules/timbre.ts @@ -0,0 +1,43 @@ +import type { CfdiData, ValidationIssue, ValidationRule } from '../types'; + +const UUID_REGEX = + /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/; +const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/; + +function checkTimbre(data: CfdiData): ValidationIssue[] { + const issues: ValidationIssue[] = []; + if (!data.timbre) return issues; + + const { uuid, fechaTimbrado, version } = data.timbre; + + if (!UUID_REGEX.test(uuid)) { + issues.push({ + code: 'CFDI701', + message: `UUID del TimbreFiscalDigital '${uuid}' no tiene el formato valido (8-4-4-4-12 hex)`, + field: 'Complemento.TimbreFiscalDigital.UUID', + rule: 'timbre.uuid', + }); + } + + if (fechaTimbrado && !ISO_DATE_REGEX.test(fechaTimbrado)) { + issues.push({ + code: 'CFDI702', + message: `FechaTimbrado '${fechaTimbrado}' no tiene el formato ISO 8601 requerido (YYYY-MM-DDTHH:mm:ss)`, + field: 'Complemento.TimbreFiscalDigital.FechaTimbrado', + rule: 'timbre.fechaTimbrado', + }); + } + + if (version && version !== '1.1') { + issues.push({ + code: 'CFDI703', + message: `Version del TimbreFiscalDigital debe ser '1.1', se encontro '${version}'`, + field: 'Complemento.TimbreFiscalDigital.Version', + rule: 'timbre.version', + }); + } + + return issues; +} + +export const timbreRules: ValidationRule[] = [checkTimbre]; diff --git a/packages/cfdi/validador/src/types.ts b/packages/cfdi/validador/src/types.ts new file mode 100644 index 00000000..20309b3a --- /dev/null +++ b/packages/cfdi/validador/src/types.ts @@ -0,0 +1,52 @@ +export interface ValidationResult { + valid: boolean; + errors: ValidationIssue[]; + warnings: ValidationIssue[]; + version: string; +} + +export interface ValidationIssue { + code: string; + message: string; + field?: string; + rule: string; +} + +export type ValidationRule = (xml: CfdiData) => ValidationIssue[]; + +export interface CfdiData { + version: string; + comprobante: Record; + emisor: Record; + receptor: Record; + conceptos: ConceptoData[]; + impuestos?: ImpuestosData; + complemento?: any; + timbre?: TimbreData; + raw: string; +} + +export interface ConceptoData { + attributes: Record; + impuestos?: { + traslados: Record[]; + retenciones: Record[]; + }; +} + +export interface ImpuestosData { + totalImpuestosTrasladados?: string; + totalImpuestosRetenidos?: string; + traslados: Record[]; + retenciones: Record[]; +} + +export interface TimbreData { + uuid: string; + fechaTimbrado: string; + rfcProvCertif: string; + selloCFD: string; + selloSAT: string; + noCertificadoSAT: string; + version: string; +} diff --git a/packages/cfdi/validador/test/impuestos.test.ts b/packages/cfdi/validador/test/impuestos.test.ts new file mode 100644 index 00000000..7d0d1c5b --- /dev/null +++ b/packages/cfdi/validador/test/impuestos.test.ts @@ -0,0 +1,307 @@ +import { describe, it, expect } from 'vitest'; +import path from 'path'; +import { Validador } from '../src/Validador'; + +const FILES_DIR = path.resolve(__dirname, '../../../files/xml/examples'); + +const BASE_XML_40 = ` + + + + + + + + + + + + + + + + + +`; + +describe('Reglas de impuestos - suma de traslados', () => { + const validador = new Validador(); + + it('acepta cuando TotalImpuestosTrasladados coincide con la suma', () => { + const result = validador.validate(BASE_XML_40); + expect(result.errors.some(e => e.code === 'CFDI605')).toBe(false); + }); + + it('rechaza cuando TotalImpuestosTrasladados no coincide', () => { + const xml = ` + + + + + + + + + + + + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI605')).toBe(true); + }); +}); + +describe('Reglas de impuestos - suma de retenciones', () => { + const validador = new Validador(); + + it('acepta cuando TotalImpuestosRetenidos coincide con la suma', () => { + const xml = ` + + + + + + + + + + + + + + + + + + + + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI606')).toBe(false); + expect(result.errors.some(e => e.code === 'CFDI605')).toBe(false); + }); + + it('rechaza cuando TotalImpuestosRetenidos no coincide', () => { + const xml = ` + + + + + + + + + + + + + + + + + + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI606')).toBe(true); + }); +}); + +describe('Reglas de impuestos - impuesto invalido', () => { + const validador = new Validador(); + + it('rechaza impuesto con codigo no valido', () => { + const xml = ` + + + + + + + + + + + + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI601')).toBe(true); + }); +}); + +describe('Reglas de impuestos - TipoFactor Exento', () => { + const validador = new Validador(); + + it('rechaza TasaOCuota cuando TipoFactor=Exento', () => { + const xml = ` + + + + + + + + + + + + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI603')).toBe(true); + }); + + it('acepta traslado Exento sin TasaOCuota ni Importe', () => { + const result = validador.validateFile( + path.join(FILES_DIR, 'test-cfdi40/ingreso-exento.xml') + ); + expect(result.errors.some(e => e.code === 'CFDI603')).toBe(false); + expect(result.errors.some(e => e.code === 'CFDI604')).toBe(false); + }); +}); + +describe('Reglas de impuestos - TipoFactor invalido', () => { + const validador = new Validador(); + + it('rechaza TipoFactor desconocido', () => { + const xml = ` + + + + + + + + + + + + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI602')).toBe(true); + }); +}); + +describe('Reglas de estructura - campos faltantes', () => { + const validador = new Validador(); + + it('rechaza CFDI 4.0 sin DomicilioFiscalReceptor', () => { + const xml = ` + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI404')).toBe(true); + }); + + it('rechaza CFDI 4.0 sin ObjetoImp en concepto', () => { + const xml = ` + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI508')).toBe(true); + }); + + it('rechaza CFDI con RFC del emisor invalido', () => { + const xml = ` + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI302')).toBe(true); + }); +}); diff --git a/packages/cfdi/validador/test/montos.test.ts b/packages/cfdi/validador/test/montos.test.ts new file mode 100644 index 00000000..cc1cf117 --- /dev/null +++ b/packages/cfdi/validador/test/montos.test.ts @@ -0,0 +1,232 @@ +import { describe, it, expect } from 'vitest'; +import { Validador } from '../src/Validador'; + +function buildXml(overrides: { + subtotal?: string; + total?: string; + descuento?: string; + moneda?: string; + tipoCambio?: string; + tipoCambioAttr?: string; + totalTrasladados?: string; + totalRetenidos?: string; + tipoComprobante?: string; + version?: string; + emisorNombre?: string; + receptorExtra?: string; + impuestosAttr?: string; + impuestosContent?: string; + conceptoImporte?: string; + conceptoValorUnitario?: string; +}): string { + const { + subtotal = '1000.00', + total = '1160.00', + descuento, + moneda = 'MXN', + tipoCambioAttr = '', + totalTrasladados = '160.00', + totalRetenidos, + tipoComprobante = 'I', + version = '4.0', + emisorNombre = 'Nombre="TEST"', + receptorExtra = 'DomicilioFiscalReceptor="06600" RegimenFiscalReceptor="601"', + impuestosAttr, + impuestosContent, + conceptoImporte = '1000.00', + conceptoValorUnitario = '1000.00', + } = overrides; + + const impAttr = + impuestosAttr ?? + [ + totalTrasladados ? `TotalImpuestosTrasladados="${totalTrasladados}"` : '', + totalRetenidos ? `TotalImpuestosRetenidos="${totalRetenidos}"` : '', + ] + .filter(Boolean) + .join(' '); + + const impContent = + impuestosContent ?? + ` + + `; + + const descAttr = descuento ? `Descuento="${descuento}"` : ''; + const ns = + version === '4.0' + ? 'http://www.sat.gob.mx/cfd/4' + : 'http://www.sat.gob.mx/cfd/3'; + + return ` + + + + + + + + + + + + + + ${impContent} + +`; +} + +describe('Reglas de montos - SubTotal', () => { + const validador = new Validador(); + + it('acepta SubTotal valido', () => { + const result = validador.validate(buildXml({})); + const subtotalErrors = result.errors.filter(e => + e.field?.includes('SubTotal') + ); + expect(subtotalErrors).toHaveLength(0); + }); + + it('rechaza SubTotal negativo', () => { + const xml = buildXml({ subtotal: '-100.00', total: '-100.00' }); + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI203')).toBe(true); + }); +}); + +describe('Reglas de montos - Total', () => { + const validador = new Validador(); + + it('rechaza Total negativo', () => { + const xml = buildXml({ total: '-500.00' }); + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI205')).toBe(true); + }); + + it('rechaza cuando Total no coincide con la formula', () => { + // SubTotal=1000, impuestos=160, total deberia ser 1160 pero ponemos 1000 + const xml = buildXml({ total: '1000.00' }); + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI208')).toBe(true); + }); + + it('acepta Total con tolerancia de 1 centavo', () => { + // Total correcto = 1000 + 160 = 1160, toleramos hasta 0.01 + const xml = buildXml({ total: '1160.005' }); + const result = validador.validate(xml); + const totalErrors = result.errors.filter(e => e.code === 'CFDI208'); + expect(totalErrors).toHaveLength(0); + }); +}); + +describe('Reglas de montos - Descuento', () => { + const validador = new Validador(); + + it('acepta descuento menor al subtotal', () => { + // SubTotal=1000, Descuento=100, Impuestos=144 (16% de 900), Total=1044 + const xml = buildXml({ + subtotal: '1000.00', + total: '1044.00', + descuento: '100.00', + conceptoImporte: '1000.00', + totalTrasladados: '144.00', + }); + const result = validador.validate(xml); + const descErrors = result.errors.filter(e => e.code === 'CFDI207'); + expect(descErrors).toHaveLength(0); + }); + + it('rechaza descuento mayor al subtotal', () => { + const xml = buildXml({ + subtotal: '100.00', + total: '116.00', + descuento: '200.00', + }); + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI207')).toBe(true); + }); +}); + +describe('Reglas de montos - Moneda y TipoCambio', () => { + const validador = new Validador(); + + it('rechaza TipoCambio cuando Moneda=XXX', () => { + const xml = ` + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI006')).toBe(true); + }); + + it('requiere TipoCambio cuando Moneda es distinta de MXN y XXX', () => { + const xml = ` + + + + + + + + + + + + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI007')).toBe(true); + }); + + it('acepta Moneda=MXN sin TipoCambio', () => { + const result = validador.validate(buildXml({})); + expect(result.errors.some(e => e.code === 'CFDI006')).toBe(false); + expect(result.errors.some(e => e.code === 'CFDI007')).toBe(false); + }); +}); + +describe('Reglas de montos - TipoDeComprobante Traslado', () => { + const validador = new Validador(); + + it('rechaza SubTotal != 0 en comprobante Traslado', () => { + const xml = ` + + + + + + +`; + const result = validador.validate(xml); + expect(result.errors.some(e => e.code === 'CFDI004')).toBe(true); + }); +}); diff --git a/packages/cfdi/validador/test/validador.test.ts b/packages/cfdi/validador/test/validador.test.ts new file mode 100644 index 00000000..b7f449c3 --- /dev/null +++ b/packages/cfdi/validador/test/validador.test.ts @@ -0,0 +1,176 @@ +import { describe, it, expect } from 'vitest'; +import path from 'path'; +import { Validador } from '../src/Validador'; + +const FILES_DIR = path.resolve( + __dirname, + '../../../files/xml/examples' +); + +const cfdi40Dir = path.join(FILES_DIR, 'test-cfdi40'); +const cfdi33Dir = path.join(FILES_DIR, 'test-cfdi33'); + +describe('Validador - XMLs validos CFDI 4.0', () => { + const validador = new Validador(); + + it('valida ingreso-basico.xml sin errores', () => { + const result = validador.validateFile( + path.join(cfdi40Dir, 'ingreso-basico.xml') + ); + expect(result.version).toBe('4.0'); + expect(result.errors).toHaveLength(0); + expect(result.valid).toBe(true); + }); + + it('valida ingreso-dolares.xml sin errores', () => { + const result = validador.validateFile( + path.join(cfdi40Dir, 'ingreso-dolares.xml') + ); + expect(result.version).toBe('4.0'); + expect(result.errors).toHaveLength(0); + expect(result.valid).toBe(true); + }); + + it('valida ingreso-exento.xml sin errores', () => { + const result = validador.validateFile( + path.join(cfdi40Dir, 'ingreso-exento.xml') + ); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); + + it('valida ingreso-iva-retencion.xml sin errores', () => { + const result = validador.validateFile( + path.join(cfdi40Dir, 'ingreso-iva-retencion.xml') + ); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); + + it('valida ingreso-ieps.xml sin errores', () => { + const result = validador.validateFile( + path.join(cfdi40Dir, 'ingreso-ieps.xml') + ); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); + + it('valida egreso-nota-credito.xml sin errores', () => { + const result = validador.validateFile( + path.join(cfdi40Dir, 'egreso-nota-credito.xml') + ); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); + + it('valida traslado.xml sin errores', () => { + const result = validador.validateFile( + path.join(cfdi40Dir, 'traslado.xml') + ); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); + + it('valida ingreso-sin-impuestos.xml sin errores', () => { + const result = validador.validateFile( + path.join(cfdi40Dir, 'ingreso-sin-impuestos.xml') + ); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); + + it('valida ingreso-multi-concepto.xml sin errores', () => { + const result = validador.validateFile( + path.join(cfdi40Dir, 'ingreso-multi-concepto.xml') + ); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); +}); + +describe('Validador - XMLs validos CFDI 3.3', () => { + const validador = new Validador(); + + it('valida ingreso-basico.xml CFDI 3.3 sin errores', () => { + const result = validador.validateFile( + path.join(cfdi33Dir, 'ingreso-basico.xml') + ); + expect(result.version).toBe('3.3'); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); + + it('valida ingreso-iva-retencion.xml CFDI 3.3 sin errores', () => { + const result = validador.validateFile( + path.join(cfdi33Dir, 'ingreso-iva-retencion.xml') + ); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); + + it('valida traslado.xml CFDI 3.3 sin errores', () => { + const result = validador.validateFile( + path.join(cfdi33Dir, 'traslado.xml') + ); + expect(result.valid).toBe(true); + expect(result.errors).toHaveLength(0); + }); +}); + +describe('Validador - version invalida', () => { + const validador = new Validador(); + + it('reporta error cuando la version es invalida', () => { + const xml = ` + + + + + + +`; + const result = validador.validate(xml); + expect(result.valid).toBe(false); + expect(result.errors.some(e => e.code === 'CFDI001')).toBe(true); + }); +}); + +describe('Validador - estructura de resultado', () => { + const validador = new Validador(); + + it('resultado tiene la estructura correcta', () => { + const result = validador.validateFile( + path.join(cfdi40Dir, 'ingreso-basico.xml') + ); + expect(result).toHaveProperty('valid'); + expect(result).toHaveProperty('errors'); + expect(result).toHaveProperty('warnings'); + expect(result).toHaveProperty('version'); + expect(Array.isArray(result.errors)).toBe(true); + expect(Array.isArray(result.warnings)).toBe(true); + }); + + it('cada issue tiene code, message y rule', () => { + const xml = ` + + + + + + +`; + const result = validador.validate(xml); + // Total 9999 vs expected 1000 - should have errors + for (const issue of result.errors) { + expect(issue).toHaveProperty('code'); + expect(issue).toHaveProperty('message'); + expect(issue).toHaveProperty('rule'); + } + }); +}); diff --git a/packages/cfdi/validador/tsconfig.json b/packages/cfdi/validador/tsconfig.json new file mode 100644 index 00000000..5bef343a --- /dev/null +++ b/packages/cfdi/validador/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "lib": ["dom", "esnext"], + "types": ["node"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "noUnusedLocals": false, + "strict": true, + "noUnusedParameters": false + } +} diff --git a/packages/cfdi/validador/vitest.config.mts b/packages/cfdi/validador/vitest.config.mts new file mode 100644 index 00000000..9152d739 --- /dev/null +++ b/packages/cfdi/validador/vitest.config.mts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; + +export default defineConfig({ + test: {}, + plugins: [tsconfigPaths()], +}); diff --git a/packages/cfdi/xml/README.md b/packages/cfdi/xml/README.md index c9da1fd2..472af9b1 100644 --- a/packages/cfdi/xml/README.md +++ b/packages/cfdi/xml/README.md @@ -1,272 +1,118 @@ -# CFDI +# @cfdi/xml -

- - Nest Logo - Nest Logo -

- -Documentacion -

- Este módulo genera un CFDI a partir de clases lo que facilita la creacion de XMl y sellarlo sin nigun problema de compatibilidad de las versiones 2.0 del xml de complementos. -

- -
- - - - -
- -Instala las dependencias and devDependencies y comienza a crear xml CFDI 4.0. -Para Windows Lea la Documentacion - -# Dependeces - -JDK - -```sh - sudo apt install default-jre - sudo apt install default-jdk +```bash +npm install @cfdi/xml ``` -Openssl - -```sh - Debian/Ubuntu: sudo apt-get install openssl - CentOS, Red Hat: yum install openssl - Archlinux: sudo pacman -S openssl -``` - -Saxon-HE >=9.9.1.6J - -```sh - - official: http://saxon.sourceforge.net/ - Archlinux: https://aur.archlinux.org/packages/saxon-he - - Automatic Installation Alternative - - https://github.com/MisaelMa/saxon-he - sudo chmod 777 saxon.sh - sudo ./saxon.sh - - ███████╗ █████╗ ██╗ ██╗ ██████╗ ███╗ ██╗ ██╗ ██╗███████╗ - ██╔════╝██╔══██╗╚██╗██╔╝██╔═══██╗████╗ ██║ ██║ ██║██╔════╝ - ███████╗███████║ ╚███╔╝ ██║ ██║██╔██╗ ██║ ███████║█████╗ - ╚════██║██╔══██║ ██╔██╗ ██║ ██║██║╚██╗██║ ██╔══██║██╔══╝ - ███████║██║ ██║██╔╝ ██╗╚██████╔╝██║ ╚████║ ██║ ██║███████╗ - ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝ -``` - -# Installation - -```sh -npm i --save @cfdi/xml -``` - -# Complementos - -## Información adicional para las Facturas - -- [x] :pushpin: Timbre fiscal digital (TFD). -- [ ] Estado de cuenta de combustibles de monederos electrónicos. -- [x] :pushpin: Donatarias. -- [x] :pushpin: Compra venta de divisas. -- [x] :pushpin: Otros derechos e impuestos. -- [x] :pushpin: Leyendas fiscales. -- [x] :pushpin: Persona física integrante de coordinado. -- [x] :pushpin: Turista pasajero extranjero. -- [x] :pushpin: Spei de tercero a tercero. -- [ ] Sector de ventas al detalle (Detallista). -- [x] :pushpin: CFDI Registro fiscal. -- [ ] Recibo de pago de nómina. -- [x] :pushpin: Pago en especie. -- [x] :pushpin: Vales de despensa. -- [x] :pushpin: Consumo de combustibles. versión 1.1 -- [x] :pushpin: Aerolíneas. -- [ ] Notarios Públicos. -- [x] :pushpin: Vehículo usado. -- [x] :pushpin: Servicios parciales de construcción. -- [x] :pushpin: Renovación y sustitución de vehículos. -- [x] :pushpin: Certificado de destrucción -- [x] :pushpin: Obras de arte plásticas y antigüedades -- [x] :pushpin: INE -- [x] :pushpin: Comercio Exterior versión 1.1 -- [x] :pushpin: Recepción de pagos -- [x] Hidrocarburos - - [x] :pushpin: IngresosHidrocarburos - - [x] :pushpin: GastosHidrocarburos10 - -## Complementos de Concepto - -- [x] :pushpin: Instituciones educativas privadas. -- [ ] Venta de vehículos. -- [ ] Terceros. -- [ ] Acreditamiento del IEPS - -# Informacion Oficial - -- Certificados de prueba - http://omawww.sat.gob.mx/tramitesyservicios/Paginas/certificado_sello_digital.htm -- Anexo 20 - http://omawww.sat.gob.mx/tramitesyservicios/Paginas/anexo_20_version3-3.htm -- Catálogo de productos y servicios - http://pys.sat.gob.mx/PyS/catPyS.aspx -- Catálogo de unidades de medida - http://pys.sat.gob.mx/PyS/catUnidades.aspx -- Consulta los complementos y complementos concepto de factura - -https://www.sat.gob.mx/consultas/49522/complementos-y-complementos-concepto-de-factura- - -https://www.sat.gob.mx/cs/Satellite?blobcol=urldata&blobkey=id&blobtable=MungoBlobs&blobwhere=1461173971924&ssbinary=true - -# Generar archivos .pem - -Lo primero que se necesita es tener instalada la librería OpenSSL (programa dedicado a la generación y tratado de claves, certificados y keyStore) para poder utilizar los comandos que nos ayudarán a crear las llaves de nuestros sellos digitales. - -## Linux - -Instalar librería: - -Debian/Ubuntu: #sudo apt-get install openssl - -CentOS, Red Hat: #yum install openssl - -Ejecutar las instrucciones: - -Archivo key.pem - -```sh -openssl pkcs8 -inform DER -in nombrearchivo.key -out nombrearchivo.key.pem -passin pass:contraseña +## Uso + +```typescript +import { CFDI, Emisor, Receptor, Concepto, Impuestos, Relacionado } from '@cfdi/xml'; + +// Crear instancia del CFDI con configuracion de XSLT y Saxon +const cfdi = new CFDI({ + xslt: { path: '/ruta/cadenaoriginal_4_0.xslt' }, + saxon: { binary: '/ruta/saxon-he' }, + debug: false, +}); + +// Certificar con el archivo .cer +cfdi.certificar('/ruta/certificado.cer'); + +// Configurar emisor +cfdi.setEmisor({ + Rfc: 'AAA010101AAA', + Nombre: 'Empresa SA de CV', + RegimenFiscal: '601', +}); + +// Configurar receptor +cfdi.setReceptor({ + Rfc: 'BBB020202BBB', + Nombre: 'Cliente SA de CV', + UsoCFDI: 'G03', + DomicilioFiscalReceptor: '12345', + RegimenFiscalReceptor: '601', +}); + +// Agregar conceptos +cfdi.addConcepto({ + ClaveProdServ: '01010101', + Cantidad: '1', + ClaveUnidad: 'E48', + Descripcion: 'Servicio de consultoria', + ValorUnitario: '1000.00', + Importe: '1000.00', + ObjetoImp: '02', +}); + +// Sellar con el archivo .key y contrasena +await cfdi.sellar('/ruta/llave.key', 'contrasena123'); + +// Obtener el XML generado +const xml = cfdi.getXmlCdfi(); + +// Obtener la representacion JSON +const json = cfdi.getJsonCdfi(); + +// Guardar archivo +cfdi.saveFile(xml, '/ruta/salida/', 'factura'); ``` -archivo cer.pem +### Agregar CFDI relacionados -```sh -openssl x509 -inform DER -outform PEM -in ruta/nombreArchivo.cer -pubkey -out ruta/nombreArchivo.cer.pem +```typescript +cfdi.addRelacionado('04', 'UUID-DEL-CFDI-RELACIONADO'); ``` -## Windows - -Descargar libreria: http://slproweb.com/products/Win32OpenSSL.html +### Acceder a la cadena original y sello -Deberán descargar la versión según su sistema operativo, e instalar. - -Ejecutar desde terminal - -Archivo key.pem - -```sh -openssl.exe pkcs8 -inform DER -in ruta/nombreArchivo.key -passin pass:contraseña -out ruta/nombreArchivo.key.pem +```typescript +const cadena = cfdi.cadenaOriginal; +const sello = cfdi.sello; ``` -archivo cer.pem - -```sh -openssl.exe x509 -inform DER -outform PEM -in ruta/nombreArchivo.cer -pubkey -out ruta/nombreArchivo.cer.pem +## API + +### Clase `CFDI` + +Extiende de `Comprobante`. Clase principal para generar facturas electronicas. + +| Metodo | Descripcion | +|--------|-------------| +| `certificar(cerpath)` | Carga el certificado .cer y establece NoCertificado y Certificado | +| `sellar(keyfile, password)` | Genera la cadena original y el sello digital | +| `getXmlCdfi()` | Retorna el XML del CFDI como string | +| `getJsonCdfi()` | Retorna la estructura JSON del CFDI | +| `saveFile(file, path, name)` | Guarda el XML en disco | +| `generarCadenaOriginal()` | Genera la cadena original usando XSLT | +| `generarSello(cadena, keyfile, password)` | Genera el sello digital a partir de la cadena original | +| `setDebug(debug)` | Activa o desactiva el modo debug | + +### Configuracion (`Config`) + +```typescript +interface Config { + debug?: boolean; + compact?: boolean; + xslt?: { path: string }; + saxon?: { binary: string }; + schema?: { path: string }; +} ``` -# Generar QR - -ESPECIFICACIÓN TÉCNICA DEL CÓDIGO DE BARRAS BIDIMENSIONAL A INCORPORAR EN LA REPRESENTACIÓN IMPRESA. - -Las representaciones impresas de los dos tipos de comprobantes fiscales digitales por Internet deben incluir un código de barras bidimensional conforme al formato de QR Code (Quick Response Code),usando la capacidad de corrección de error con nivel mínimo M, descrito en el estándar ISO/IEC18004, con base en los siguientes lineamientos. - -a) Debe contener los siguientes datos en la siguiente secuencia: - - *La URL del acceso al servicio que pueda mostrar los datos de la versión publica del comprobante. - *Numero de folio fiscal del comprobante (UUID). - *RFC del emisor. - *RFC del receptor. - *Ocho últimos caracteres del sello digital del emisor del comprobante. - -Donde se manejan / caracteres conformados de la siguiente manera: - -

- The house from the offer. -

- -De esta manera se generan los datos validos para realizar una consulta de un CFDI por medio de su expresión impresa. - -Ejemplo: +### Exports adicionales -https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=5803EB8D-81CD-4557-8719-26632D2FA434&re=XAXX010101000&rr=CARR861127SB0&tt=0000014300.000000&fe=rH8/bw== +- `Emisor` - Elemento del emisor +- `Receptor` - Elemento del receptor +- `Concepto` / `Concepts` - Elemento de conceptos +- `Impuestos` - Elemento de impuestos +- `Relacionado` - Elemento de CFDI relacionados -El código de barras bidimensional debe ser impreso en un cuadro con lados no menores a 2.75 centímetros. +## Licencia -

-The house from the offer. -

+[MIT](../../LICENSE) diff --git a/packages/cfdi/xml/config/index.js b/packages/cfdi/xml/config/index.js deleted file mode 100644 index a57ca179..00000000 --- a/packages/cfdi/xml/config/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict' -module.exports = require('./xml.cjs.production.min.js') diff --git a/packages/cfdi/xml/package.json b/packages/cfdi/xml/package.json index 1ce7a5e5..e7d23961 100644 --- a/packages/cfdi/xml/package.json +++ b/packages/cfdi/xml/package.json @@ -4,9 +4,9 @@ "description": "Libreria para crear y sellar xml cfdi V4.0", "homepage": "https://cfdi.recreando.dev", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/xml.esm.production.min.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "release": { "branches": [ @@ -27,42 +27,15 @@ "url": "https://github.com/MisaelMa/recreando" }, "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build --env production --minify && rimraf ./dist/index.js ./dist/xml.cjs.development.* && npm run cp", - "cp": "cp ./config/index.js ./dist", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", "test:coverage": "vitest run --coverage", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" + "test:ui": "vitest --ui" }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/xml.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/xml.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "@cfdi/catalogos": "workspace:*", "@cfdi/csd": "workspace:*", @@ -72,18 +45,11 @@ "xml-js": "^1.6.11" }, "devDependencies": { - "rimraf": "^6.0.1", "@recreando/vite": "workspace:*", "@recreando/eslint-settings": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@types/node": "^18.11.3", + "@types/node": "^22", "eslint": "^8.57.0", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/xml/vite.config.mts b/packages/cfdi/xml/vite.config.mts new file mode 100644 index 00000000..78f30cf9 --- /dev/null +++ b/packages/cfdi/xml/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xml-js'], + }, + }, +})); diff --git a/packages/cfdi/xml/vitest.config.mts b/packages/cfdi/xml/vitest.config.mts index 320bc897..31655450 100644 --- a/packages/cfdi/xml/vitest.config.mts +++ b/packages/cfdi/xml/vitest.config.mts @@ -18,6 +18,7 @@ export default defineConfig({ '@cfdi/complementos': resolve(__dirname, '../complementos/src'), '@cfdi/csd': resolve(__dirname, '../csd/src'), '@saxon-he/cli': resolve(__dirname, '../../clir/saxon-he/src'), + '@clir/openssl': resolve(__dirname, '../../clir/openssl/src'), }, }, }); diff --git a/packages/cfdi/xml2json/README.md b/packages/cfdi/xml2json/README.md index 9487075c..67232e83 100644 --- a/packages/cfdi/xml2json/README.md +++ b/packages/cfdi/xml2json/README.md @@ -1 +1,46 @@ -utils +# @cfdi/2json + +Conversion de XML de CFDI a JSON. Acepta una ruta de archivo o un string de XML y retorna un objeto JSON estructurado. + +## Instalacion + +```bash +npm install @cfdi/2json +``` + +## Uso + +```typescript +import { XmlToJson } from '@cfdi/2json'; + +// Desde archivo +const json = XmlToJson('/ruta/al/cfdi.xml'); + +// Desde string XML +const xml = '...'; +const json2 = XmlToJson(xml); + +// Mantener namespaces originales (por defecto se eliminan) +const jsonOriginal = XmlToJson('/ruta/al/cfdi.xml', { original: true }); +// Con namespaces: { 'cfdi:Comprobante': { ... } } +// Sin namespaces (default): { Comprobante: { ... } } + +// Modo compact +const jsonCompact = XmlToJson('/ruta/al/cfdi.xml', { compact: true }); +``` + +## API + +### `XmlToJson(xmlPath, config?)` + +| Parametro | Tipo | Descripcion | +|-----------|------|-------------| +| `xmlPath` | `string` | Ruta a un archivo XML o string con contenido XML | +| `config.original` | `boolean` | Si es `true`, mantiene los prefijos de namespace. Por defecto `false` | +| `config.compact` | `boolean` | Si es `true`, usa formato compacto. Por defecto `false` | + +**Retorna:** Objeto JSON con la estructura del CFDI. Los namespaces como `cfdi:` se eliminan por defecto para facilitar el acceso a los nodos. + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/xml2json/config/index.js b/packages/cfdi/xml2json/config/index.js deleted file mode 100644 index 5577fb55..00000000 --- a/packages/cfdi/xml2json/config/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict' -module.exports = require('./2json.cjs.production.min.js') diff --git a/packages/cfdi/xml2json/package.json b/packages/cfdi/xml2json/package.json index 128e5c97..5c8280a5 100644 --- a/packages/cfdi/xml2json/package.json +++ b/packages/cfdi/xml2json/package.json @@ -2,9 +2,9 @@ "name": "@cfdi/2json", "version": "4.0.13", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/2json.esm.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "release": { "branches": [ @@ -17,25 +17,14 @@ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build --env production --minify && rimraf ./dist/index.js ./dist/2json.cjs.development.* && npm run cp", - "cp": "cp ./config/index.js ./dist", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "publishConfig": { "registry": "https://registry.npmjs.org/", @@ -45,27 +34,11 @@ "type": "git", "url": "https://github.com/MisaelMa/recreando" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, "author": { "name": "Amir Misael Marin Coh, Signati", "email": "amisael.amir.misae@gmail.com, signatidev@gmail.com,", "url": "" }, - "size-limit": [ - { - "path": "dist/2json.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/2json.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "xml-js": "^1.6.11", "@cfdi/types": "workspace:*", @@ -73,28 +46,11 @@ "@cfdi/elements": "workspace:*" }, "devDependencies": { - "rimraf": "^6.0.1", "@recreando/vite": "workspace:*", "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", + "@types/node": "^22", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/xml2json/src/cfdi/catalogo.ts b/packages/cfdi/xml2json/src/cfdi/catalogo.ts new file mode 100644 index 00000000..0dacf83b --- /dev/null +++ b/packages/cfdi/xml2json/src/cfdi/catalogo.ts @@ -0,0 +1,12 @@ +export class Catalogo { + private data: Record = {} + constructor(value: T) {} + + get label(): string { + return '' + } + + get value(): string { + return '' + } +} \ No newline at end of file diff --git a/packages/cfdi/xml2json/src/cfdi/cfdi.factory.ts b/packages/cfdi/xml2json/src/cfdi/cfdi.factory.ts new file mode 100644 index 00000000..613d89b8 --- /dev/null +++ b/packages/cfdi/xml2json/src/cfdi/cfdi.factory.ts @@ -0,0 +1,15 @@ +import { Concepto } from "./concepto"; +import { XmlConceptoAttributes } from "@cfdi/types"; + +export class CFDIFactory { + data!: XmlConceptoAttributes; + constructor(data: XmlConceptoAttributes){ + this.data = data + } + + build(): Concepto { + const concepto = new Concepto(this.data) + return concepto + } + +} \ No newline at end of file diff --git a/packages/cfdi/xml2json/src/cfdi/concepto.factory.ts b/packages/cfdi/xml2json/src/cfdi/concepto.factory.ts new file mode 100644 index 00000000..895110be --- /dev/null +++ b/packages/cfdi/xml2json/src/cfdi/concepto.factory.ts @@ -0,0 +1,15 @@ +import { Concepto } from "./concepto"; +import { ObjetoImp, ObjetoImpEnum, XmlConceptoAttributes } from "@cfdi/types"; + +export class ConceptFactory { + data!: XmlConceptoAttributes; + constructor(data: XmlConceptoAttributes){ + this.data = data + } + + build(): Concepto { + const concepto = new Concepto(this.data) + return concepto + } + +} \ No newline at end of file diff --git a/packages/cfdi/xml2json/src/cfdi/concepto.ts b/packages/cfdi/xml2json/src/cfdi/concepto.ts new file mode 100644 index 00000000..d53dc8cd --- /dev/null +++ b/packages/cfdi/xml2json/src/cfdi/concepto.ts @@ -0,0 +1,36 @@ +import { ObjetoImp, ObjetoImpEnum, XmlConceptoAttributes, XmlImpuestosTrasladados } from "@cfdi/types"; +import { Impuestos } from "./impuestos"; +import { Catalogo } from "./catalogo"; + +export class Concepto { + claveProdServ: string; + noIdentificacion?: string; + cantidad: number | string; + claveUnidad: string; + unidad?: string; + descripcion: string; + valorUnitario: number | string; + importe: number | string; + descuento?: number | string; + objetoImp: Catalogo + impuestos?: Impuestos; + + constructor(data: XmlConceptoAttributes){ + this.claveProdServ = data.ClaveProdServ + this.noIdentificacion = data.NoIdentificacion + this.cantidad = data.Cantidad + this.claveUnidad = data.ClaveUnidad + this.unidad = data.Unidad + this.descripcion = data.Descripcion + this.valorUnitario = data.ValorUnitario + this.importe = data.Importe + this.descuento = data.Descuento + this.objetoImp = new Catalogo(data.ObjetoImp) + } + + + setImpuestos(impuestos: XmlImpuestosTrasladados) { + this.impuestos = new Impuestos(impuestos) + } + +} \ No newline at end of file diff --git a/packages/cfdi/xml2json/src/cfdi/impuestos.factory.ts b/packages/cfdi/xml2json/src/cfdi/impuestos.factory.ts new file mode 100644 index 00000000..15d0ebec --- /dev/null +++ b/packages/cfdi/xml2json/src/cfdi/impuestos.factory.ts @@ -0,0 +1,15 @@ +import { ObjetoImp, ObjetoImpEnum, XmlConceptoAttributes, XmlImpuestosTrasladados } from "@cfdi/types"; +import { Impuestos } from "./impuestos"; + +export class TaxesFactory { + data!: XmlImpuestosTrasladados; + constructor(data: XmlImpuestosTrasladados){ + this.data = data + } + + build() { + const impuestos = new Impuestos(this.data) + return impuestos + } + +} \ No newline at end of file diff --git a/packages/cfdi/xml2json/src/cfdi/impuestos.ts b/packages/cfdi/xml2json/src/cfdi/impuestos.ts new file mode 100644 index 00000000..667799b2 --- /dev/null +++ b/packages/cfdi/xml2json/src/cfdi/impuestos.ts @@ -0,0 +1,8 @@ +export class Impuestos { + constructor(data: any) { + Object.assign(this, data); + } + data() { + console.log(this, "impuestos data") + } +} \ No newline at end of file diff --git a/packages/cfdi/xml2json/src/cfdi/index.ts b/packages/cfdi/xml2json/src/cfdi/index.ts new file mode 100644 index 00000000..32bbeccd --- /dev/null +++ b/packages/cfdi/xml2json/src/cfdi/index.ts @@ -0,0 +1,41 @@ +import { Concepto } from './concepto'; +import { XmlToJson } from '../xmlToJson'; +import { + XmlConceptoAttributes, + XmlEmisorAttribute, + XmlReceptorAttribute, +} from '@cfdi/types'; +import { ConceptFactory } from './concepto.factory'; +export class CFDI { + json: Record = {}; + constructor(xml: string) { + this.json = XmlToJson(xml); + } + + get comprobante() { + return this.json.Comprobante; + } + + get emisor(): XmlEmisorAttribute { + return this.json.Comprobante; + } + + get receptor(): XmlReceptorAttribute { + return this.json.Comprobante?.Receptor; + } + + get conceptos(): Concepto[] { + const conceptos = this.json.Comprobante?.Conceptos || []; + return conceptos.map((concepto: XmlConceptoAttributes) => { + return new ConceptFactory(concepto).build(); + }); + } + + get impuestos() { + return this.json.Comprobante?.Impuestos; + } + + get complemento() { + return this.json.Comprobante?.Complemento; + } +} diff --git a/packages/cfdi/xml2json/src/xmlToJson.ts b/packages/cfdi/xml2json/src/xmlToJson.ts index 4a2aeca0..4e472484 100644 --- a/packages/cfdi/xml2json/src/xmlToJson.ts +++ b/packages/cfdi/xml2json/src/xmlToJson.ts @@ -3,67 +3,126 @@ import { readFileSync } from 'fs'; import { ElementCompact, Element, Options, xml2js } from 'xml-js'; import { isPath } from '@cfdi/utils'; -function extractAttributes(element: Element | ElementCompact) { - const attributes: any = { ...element.attributes }; +export function XmlToJson( + xmlPath: string, + config?: { original?: boolean; compact?: boolean } +): any { + const original = Boolean(config?.original); + const compact = Boolean(config?.compact); + const stringXml = isPath(xmlPath) ? readFileSync(xmlPath, 'utf8') : xmlPath; + const options: Options.XML2JS = { + ignoreComment: false, + compact: false, + ignoreDeclaration: false, + elementNameFn: (name: string) => { + return original ? name : name.replace(/^.*:/, '') + } + }; + const json = xml2js(stringXml, options); - if (element.elements) { - element.elements.forEach((child: any) => { - const childData = child.elements ? extractAttributes(child) : { ...child.attributes }; + const toCompacts = (elements: Element[], options: any) => { + const { parent = '', isPlural } = options || {}; + let result: any; + /* console.log('parent', parent); + console.log('isPlural', isPlural); */ - // Verificar si el nombre del padre es el plural del hijo (ej. Conceptos -> Concepto) - const isPluralParent = element.name.toLowerCase().endsWith(child.name.toLowerCase() + 's'); // Verifica si el padre es plural + //console.log('------------------') + elements.forEach((element, i) => { + const name = element.name as string; + const attributes = Boolean(element.attributes); + const res = parent.replace(name, ''); + const isElementPlural = ['s', 'es'].includes(res); - // Si el nombre del padre es el plural del hijo, aseguramos que el hijo sea tratado como un array - if (isPluralParent) { - if (attributes[child.name]) { - if (Array.isArray(attributes[child.name])) { - attributes[child.name].push(childData); - } else { - attributes[child.name] = [attributes[child.name], childData]; - } - } else { - attributes[child.name] = [childData]; // Forzar a que sea un array - } + if (attributes && !isPlural) { + if (isElementPlural) { + if (!result) { + result = []; + } + result[i] = element.attributes + } else { + if (!result) { + result = {}; + } + result[name] = element.attributes; + } + } + /* console.log(` + ============ + parent: ${parent} + name: ${name} + isPlural: ${isPlural} + isElementPlural: ${isElementPlural} + attributes: ${JSON.stringify(attributes)} + ===========`); */ + if (element.elements && element.elements.length > 0) { + if (isElementPlural) { + /* console.log('isElementPlural if ', isElementPlural); + console.log('element', element); */ + const compact = toCompacts(element.elements, { + parent: name, + isPlural: false, + }); + /* console.log('compact parent if', name); + console.log('compact --->', JSON.stringify(compact, null, 2)); + console.log("result", result) */ + result[i] = { + ...result[i], + ...compact + } + //result['amir'] = { + // compact + //...element.attributes, + //...result[name], + //...compact + //} + } else { + const compact = toCompacts(element.elements, { + parent: name, + isPlural: isElementPlural, + }); + /* console.log('compact parent else', name); + console.log('compact --->', compact); + console.log('isElementPlural', isElementPlural); + console.log('isPlural', isPlural); */ + if (!isPlural) { + if (!result) { + result = {}; + } + let r: any; + if (Array.isArray(compact)) { + r = { + [name]: compact, + }; + result ={ + ...result, + ...r, + } } else { - // Si no es plural, manejar como objeto único - if (attributes[child.name]) { - if (Array.isArray(attributes[child.name])) { - attributes[child.name].push(childData); - } else { - attributes[child.name] = [attributes[child.name], childData]; - } - } else { - attributes[child.name] = childData; - } + r = compact; + result[name] = { + ...result[name], + ...r, + }; } - }); - } + } else { + console.log('isPlural else', isPlural); + // result.push(compact); + } + } + } + }); - return attributes; -} + /* console.log('=============='); + console.log('result', JSON.stringify(result, null, 2)); + console.log('=============='); */ -export function XmlToJson(xmlPath: string, config?: {original: boolean}): XmlCdfi { - const original = Boolean(config?.original); - const stringXml = isPath(xmlPath) ? readFileSync(xmlPath, 'utf8') : xmlPath; - const options: Options.XML2JS = { - ignoreComment: false, - alwaysChildren: false, - compact: original, - ignoreDeclaration: false, - elementNameFn: (name: string) => original ? name : name.replace(/^.*:/, '') - }; - const json = xml2js(stringXml, options); - const onlyJson = () => { - const { declaration, elements } = json; - const comprobante_element = elements.find((el: any) => el.name === 'Comprobante'); - const comprobante = comprobante_element ? extractAttributes(comprobante_element) : {}; - return { - declaration: { - ...declaration.attributes - }, - 'Comprobante': comprobante - } - } - const result = original ? json : onlyJson(); - return result as XmlCdfi; + return result; + }; + + const compactJson = toCompacts(json.elements, { + isPlural: false, + parent: 'Comprobante', + }); + + return compactJson; } diff --git a/packages/cfdi/xml2json/test/cfdi-class.test.ts b/packages/cfdi/xml2json/test/cfdi-class.test.ts new file mode 100644 index 00000000..2448f5e6 --- /dev/null +++ b/packages/cfdi/xml2json/test/cfdi-class.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it, test } from 'vitest'; +import { XmlToJson } from '../src/xmlToJson'; +import { CFDI } from '../src/cfdi'; +import path from 'path'; +import { Concepto } from '../src/cfdi/Concepto'; + +const files_path = path.resolve(__dirname, '..', '..', '..', 'files', 'xml'); +const nameCFDI = '5E2D6AFF-2DD7-43D1-83D3-14C1ACA396D9.xml'; +const xml = path.resolve(files_path, nameCFDI); +const cfdi = new CFDI(xml); +describe('CFDI Class ', () => { + it('toObject', () => { + expect(cfdi).toBeDefined(); + expect(cfdi.receptor).toEqual({ + Nombre: 'AMIR MISAEL MARIN', + Rfc: 'XAXX010101000', + UsoCFDI: 'G03', + }); + }); + + it('conceptos', () => { + + const xml = path.resolve(files_path,'conceptos.xml') + const cfdi = new CFDI(xml); + + + }); +}); diff --git a/packages/cfdi/xml2json/test/cfdi.test.ts b/packages/cfdi/xml2json/test/cfdi.test.ts new file mode 100644 index 00000000..782c3922 --- /dev/null +++ b/packages/cfdi/xml2json/test/cfdi.test.ts @@ -0,0 +1,40 @@ +import { describe, expect, it, test } from 'vitest'; +import { XmlToJson } from '../src/xmlToJson'; +import path from 'path'; + +const files_path = path.resolve(__dirname, '..', '..', '..', 'files', 'xml'); + +describe('CFDI', () => { + it('json', () => { + const xml = path.resolve( + files_path, + '5E2D6AFF-2DD7-43D1-83D3-14C1ACA396D9.xml' + ); + const json = XmlToJson(xml, { original: false, compact: true }); + //console.log(JSON.stringify(json, null, 2)) + expect(json).toBeDefined(); + }); + + it('Emisor & Receptor', () => { + const xml = path.resolve(files_path, 'emisor-receptor.xml'); + const json = XmlToJson(xml, { original: false, compact: false }); + expect(json).toBeDefined(); + + expect(json).toEqual({ + Comprobante: { + Emisor: { + Nombre: 'ESCUELA KEMPER URGATE', + RegimenFiscal: '603', + Rfc: 'EKU9003173C9', + }, + Receptor: { + DomicilioFiscalReceptor: '36257', + Nombre: 'XOCHILT CASAS CHAVEZ', + RegimenFiscalReceptor: '612', + Rfc: 'CACX7605101P8', + UsoCFDI: "G03", + }, + }, + }); + }); +}); diff --git a/packages/cfdi/xml2json/test/conceptos-to-json.test.ts b/packages/cfdi/xml2json/test/conceptos-to-json.test.ts new file mode 100644 index 00000000..bd2b1335 --- /dev/null +++ b/packages/cfdi/xml2json/test/conceptos-to-json.test.ts @@ -0,0 +1,111 @@ +import { describe, expect, it, test } from 'vitest'; +import { XmlToJson } from '../src/xmlToJson' +import path from 'path'; + +const files_path = path.resolve(__dirname, '..', '..', '..', 'files','xml'); + +describe(' to json', () => { + + it('un concepto', () => { + const xml = path.resolve(files_path,'un-concepto.xml') + const json = XmlToJson(xml) + + expect(json).toBeDefined(); + + expect(json).toEqual({ + "Comprobante": { + "Conceptos": [ + { + "ClaveProdServ": "86121500", + "Cantidad": "1", + "ClaveUnidad": "E48", + "Unidad": "Pieza", + "Descripcion": "Mensualidad - diciembre", + "ValorUnitario": "5000", + "Importe": "5000", + "Descuento": "0" + } + ] + } + }); + }); + + it('dos conceptos', () => { + const xml = path.resolve(files_path,'dos-conceptos.xml') + const json = XmlToJson(xml) + + expect(json).toBeDefined(); + + expect(json).toEqual({ + "Comprobante": { + "Conceptos": [ + { + "ClaveProdServ": "86121500", + "Cantidad": "1", + "ClaveUnidad": "E48", + "Unidad": "Pieza", + "Descripcion": "Mensualidad - diciembre", + "ValorUnitario": "5000", + "Importe": "5000", + "Descuento": "0" + }, + { + "ClaveProdServ": "86121500", + "Cantidad": "1", + "ClaveUnidad": "E48", + "Unidad": "Pieza", + "Descripcion": "Mensualidad - diciembre", + "ValorUnitario": "5000", + "Importe": "5000", + "Descuento": "0" + } + ] + } + }); + }); + + it ('con complemento', () => { + const xml = path.resolve(files_path,'conceptos.xml') + const json = XmlToJson(xml) + // console.log(JSON.stringify(json, null, 2)); + expect(json).toBeDefined(); + expect(json).toEqual({ + "Comprobante": { + "Conceptos": [ + { + "ClaveProdServ": "86121500", + "Cantidad": "1", + "ClaveUnidad": "E48", + "Unidad": "Pieza", + "Descripcion": "Mensualidad - diciembre", + "ValorUnitario": "5000", + "Importe": "5000", + "Descuento": "0", + "Impuestos": { + "Traslados": [ + { + "Base": "1", + "Impuesto": "002", + "TipoFactor": "Exento" + } + ] + }, + "ComplementoConcepto": { + "instEducativas": { + "xmlns:iedu": "http://www.sat.gob.mx/iedu", + "rfcPago": "CACX7605101P8", + "autRVOE": "118141", + "nivelEducativo": "Primaria", + "CURP": "XEXX010101HNEXXXA4", + "nombreAlumno": "RUBINHO LOPEZ ADILENE", + "version": "1.0" + } + } + } + ] + } + }) + + }) + +}); diff --git a/packages/cfdi/xml2json/test/impuestos-to-json.test.ts b/packages/cfdi/xml2json/test/impuestos-to-json.test.ts new file mode 100644 index 00000000..eb68a68b --- /dev/null +++ b/packages/cfdi/xml2json/test/impuestos-to-json.test.ts @@ -0,0 +1,75 @@ +import { describe, expect, it, test } from 'vitest'; +import { XmlToJson } from '../src/xmlToJson'; +import path from 'path'; + +const files_path = path.resolve(__dirname, '..', '..', '..', 'files', 'xml'); + +describe('impuestos to json', () => { + it('traslados', () => { + const xml = path.resolve(files_path, 'un-impuesto.xml'); + const json = XmlToJson(xml); + //console.log('json', JSON.stringify(json, null, 2)); + expect(json).toBeDefined(); + + expect(json).toEqual({ + Comprobante: { + Impuestos: { + TotalImpuestosTrasladados: '31.72', + Traslados: [ + { + Impuesto: '002', + TipoFactor: 'Tasa', + TasaOCuota: '0.160000', + Importe: '31.72', + }, + ], + Retenciones: [ + { + Importe: '2.00', + Impuesto: '004', + }, + ], + }, + }, + }); + }); + + it('dos traslados', () => { + const xml = path.resolve(files_path, 'dos-impuestos.xml'); + const json = XmlToJson(xml); + + expect(json).toBeDefined(); + + expect(json).toEqual({ + Comprobante: { + Impuestos: { + TotalImpuestosTrasladados: '31.72', + Traslados: [ + { + Impuesto: '002', + TipoFactor: 'Tasa', + TasaOCuota: '0.160000', + Importe: '31.72', + }, + { + Impuesto: '002', + TipoFactor: 'Tasa', + TasaOCuota: '0.160000', + Importe: '31.72', + }, + ], + Retenciones: [ + { + Impuesto: '002', + Importe: '1.00', + }, + { + Impuesto: '002', + Importe: '1.00', + }, + ], + }, + }, + }); + }); +}); diff --git a/packages/cfdi/xml2json/test/xml-to-json.test.ts b/packages/cfdi/xml2json/test/xml-to-json.test.ts deleted file mode 100644 index 5f249dd8..00000000 --- a/packages/cfdi/xml2json/test/xml-to-json.test.ts +++ /dev/null @@ -1,252 +0,0 @@ -import { describe, expect, it, test } from 'vitest'; -import { XmlToJson } from '../src/xmlToJson' -import path from 'path'; - -const files_path = path.resolve(__dirname, '..', '..', '..', 'files','xml'); - -describe('xml to json', () => { - - it('json', () => { - const xml = path.resolve(files_path,'5E2D6AFF-2DD7-43D1-83D3-14C1ACA396D9.xml') - const json = XmlToJson(xml, {original: true}) - console.log(JSON.stringify(json, null, 2)) - - expect(json).toBeDefined(); - }); - it('json', () => { - const xml = path.resolve(files_path,'5E2D6AFF-2DD7-43D1-83D3-14C1ACA396D9.xml') - const json = XmlToJson(xml) - console.log(JSON.stringify(json, null, 2)) - - expect(json).toBeDefined(); - /* expect(json).toEqual({ - "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", - "xmlns:cfdi": "http://www.sat.gob.mx/cfd/3", - "xsi:schemaLocation": " http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd", - "Version": "3.3", - "Serie": "I", - "Folio": "ACAPDC-50", - "Fecha": "2021-02-17T02:12:14", - "Sello": "HGJg9lit0Gr54foL1tBT+h/HnpjO9WdqJJldQPKoRUYGgo27ImMBgMoyn31Kz0qOxZA2IbW7Hl5MmxKd5ImdT3nPCRlX7E7wKMUkUdLzb95DvUXl4y2jX33Cd1g65i/9YJB5ItGj8BMFq79K7Yyxm2U/Z+Txfv1zeSRkQk0HT4VyM7mCUnru55AH3OBe692c7X2AAna4eNViZBi+C7fA1zmA4NuI6qTpQdsFgEy+dkCZRFNJIBgZ6VHtcwolA5uBGPKjWyndADpiYuPLhzLWn2TQEkWXW0geGoNFfFnPukbXqQTlZyBCZiEcRfQKWCzqpv8SM4PBhnXbPR0lKTFD2g==", - "FormaPago": "04", - "NoCertificado": "30001000000400002326", - "Certificado": "MIIFijCCA3KgAwIBAgIUMzAwMDEwMDAwMDA0MDAwMDIzMjYwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWRpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMTkwNTI5MTgxMTQ4WhcNMjMwNTI5MTgxMTQ4WjCBsTEdMBsGA1UEAxMUQUxCQSBYS0FSQUpBTSBNRU5ERVoxHTAbBgNVBCkTFEFMQkEgWEtBUkFKQU0gTUVOREVaMR0wGwYDVQQKExRBTEJBIFhLQVJBSkFNIE1FTkRFWjEWMBQGA1UELRMNWEFNQTYyMDIxMERRNTEbMBkGA1UEBRMSWEFNQTYyMDIxME1TTEtOTDA0MR0wGwYDVQQLExRBTEJBIFhLQVJBSkFNIE1FTkRFWjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2HkPEtxQ+eUC6J428PU1OHXmr7cHtTlE5+Zk0eYykm1tVNivygT+kz7FTgw1b0yoFh96Xp3tXBSeAmsO+DShFFyYMB6x3lllIEmMZD5JbMaCpzyPMRzAq6850Am3/ShjigUPRorUhdLO1Yes2CyySzYlhA08fq3FmOCQ4eQmSPN7422T+Srhm6pFYaVjwS0MlskslCIi+ANqL5RWg75tNjpJzLQXPJyG0KU1AaqXgUT1e+aTn38AyNVQc30QAjiI50CTUq5MJFixoCB9vol421L7peEIAox3DRVw9H/wns9973XLedyuj5r8ZZfs4BinkVh+mykTyZE63rEv14uncCAwEAAaMdMBswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwDQYJKoZIhvcNAQELBQADggIBAAR/KOWy29oitYdYzuGe1o+JOx/AowEJuu9S4/thFE9ugvHiceFK3cUD8v4M4/AS9D+NVrcMpJocNwpUsW/GiGFqOHNcFVnoSsaeEUMSIW949/0lCeMusR10VnpUaXmYFVYZkFV0PsDYUHna+lqmHDLwzSpfyU20UapgpkPe7Ib6/5CmsPQ7GcF7HBrshO8MyLyYSi193MTDKO86thq5iBnTrt4qyCgI7+Hpk770C4wMskpitf0Z9BUUrBxAk+ZoH1fw1ysZtK+v4vS/wquib2SK+MpvlYEfam/613EE/PEAlBTXPDaWTxporKJJxnv/iOsm97FmvRuwAnB13r5cxc/UJFjD2bFm38/2wOUG1H3srG8xhVSTKUYQjvJU+V10dQe0O/QkWx9sPHlY67CdB5SlsCBl0mkB7mA2fsPyuP28EQtEenjm48wpBXgb4exOYq4flMPZ7LpO79SmnQPSeTIt8CIlc0HomkMCl30HQzGSMoItxGSO9Rrx3ogpNNcdhpD6p59TkYd2zM7argPP/lfbl7/3EbbN5miC1JgNgRfAq02CREdMEAK9Z6ErVWUUl8gd0Tva/C3ykCJdTdNgfEI8gONS2ky/axDNDHL8d4+I6tGItfM4drtukL9Trh8/5RPuPvKHg1tKonDp50mxu4ubXBDF2LAnsOshAB44fn+r", - "SubTotal": "5000", - "Descuento": "0", - "Moneda": "MXN", - "Total": "5000", - "TipoDeComprobante": "I", - "MetodoPago": "PUE", - "LugarExpedicion": "77728", - "Emisor": { - "Rfc": "XAMA620210DQ5", - "Nombre": "AMIR MISAEL MARIN COH", - "RegimenFiscal": "621" - }, - "Receptor": { - "Nombre": "AMIR MISAEL MARIN", - "Rfc": "XAXX010101000", - "UsoCFDI": "G03" - }, - "Conceptos": { - "Concepto": [ - { - "ClaveProdServ": "86121500", - "Cantidad": "1", - "ClaveUnidad": "E48", - "Unidad": "Pieza", - "Descripcion": "Mensualidad - diciembre", - "ValorUnitario": "5000", - "Importe": "5000", - "Descuento": "0" - }, - { - "ClaveProdServ": "86121500", - "Cantidad": "1", - "ClaveUnidad": "E48", - "Unidad": "Pieza", - "Descripcion": "Mensualidad - diciembre", - "ValorUnitario": "5000", - "Importe": "5000", - "Descuento": "0" - } - ] - }, - "Impuestos": { - "TotalImpuestosTrasladados": "0.16", - "Traslados": { - "Traslado": [ - { - "Base": "1", - "Impuesto": "002", - "TipoFactor": "Tasa", - "TasaOCuota": "0.160000", - "Importe": "0.16" - } - ] - } - }, - "Complemento": { - "ImpuestosLocales": { - "version": "1.0", - "TotaldeRetenciones": "0.000000", - "TotaldeTraslados": "48.000000", - "TrasladosLocales": { - "ImpLocTrasladado": "IMPUESTO DE HOSPEDAJE", - "TasadeTraslado": "4", - "Importe": "48.00" - } - }, - "CartaPorte": { - "RegistroISTMO": "Sí", - "UbicacionPoloOrigen": "01", - "UbicacionPoloDestino": "01", - "Version": "3.1", - "IdCCP": "CCCBCD94-870A-4332-A52A-A52AA52AA52A", - "TranspInternac": "No", - "TotalDistRec": "1", - "Ubicaciones": { - "Ubicacion": [ - { - "TipoUbicacion": "Origen", - "IDUbicacion": "OR101010", - "RFCRemitenteDestinatario": "URE180429TM6", - "NombreRemitenteDestinatario": "NombreRemitenteDestinatario1", - "FechaHoraSalidaLlegada": "2023-08-01T00:00:00", - "Domicilio": { - "Calle": "Calle1", - "NumeroExterior": "211", - "NumeroInterior": "212", - "Colonia": "1957", - "Localidad": "13", - "Referencia": "casa blanca", - "Municipio": "011", - "Estado": "CMX", - "Pais": "MEX", - "CodigoPostal": "13250" - } - }, - { - "TipoUbicacion": "Destino", - "IDUbicacion": "DE202020", - "RFCRemitenteDestinatario": "URE180429TM6", - "NombreRemitenteDestinatario": "NombreRemitenteDestinatario2", - "FechaHoraSalidaLlegada": "2023-08-01T00:00:01", - "DistanciaRecorrida": "1", - "Domicilio": { - "Calle": "Calle2", - "NumeroExterior": "214", - "NumeroInterior": "215", - "Colonia": "0347", - "Localidad": "23", - "Referencia": "casa negra", - "Municipio": "004", - "Estado": "COA", - "Pais": "MEX", - "CodigoPostal": "25350" - } - } - ] - }, - "Mercancias": { - "PesoBrutoTotal": "1.0", - "UnidadPeso": "XBX", - "NumTotalMercancias": "1", - "LogisticaInversaRecoleccionDevolucion": "Sí", - "Mercancia": [ - { - "FraccionArancelaria": "6309000100", - "BienesTransp": "11121900", - "Descripcion": "Accesorios de equipo de telefonía", - "Cantidad": "1.0", - "ClaveUnidad": "XBX", - "MaterialPeligroso": "No", - "PesoEnKg": "1", - "DenominacionGenericaProd": "DenominacionGenericaProd1", - "DenominacionDistintivaProd": "DenominacionDistintivaProd1", - "Fabricante": "Fabricante1", - "FechaCaducidad": "2003-04-02", - "LoteMedicamento": "LoteMedic1", - "FormaFarmaceutica": "01", - "CondicionesEspTransp": "01", - "RegistroSanitarioFolioAutorizacion": "RegistroSanita1", - "CantidadTransporta": { - "Cantidad": "1", - "IDOrigen": "OR101010", - "IDDestino": "DE202020" - } - } - ], - "Autotransporte": { - "PermSCT": "TPAF01", - "NumPermisoSCT": "NumPermisoSCT1", - "IdentificacionVehicular": { - "ConfigVehicular": "VL", - "PesoBrutoVehicular": "1", - "PlacaVM": "plac892", - "AnioModeloVM": "2020" - }, - "Seguros": { - "AseguraRespCivil": "AseguraRespCivil", - "PolizaRespCivil": "123456789" - }, - "Remolques": { - "Remolque": [ - { - "SubTipoRem": "CTR004", - "Placa": "VL45K98" - } - ] - } - } - }, - "FiguraTransporte": { - "TiposFigura": { - "TipoFigura": "01", - "RFCFigura": "URE180429TM6", - "NumLicencia": "NumLicencia1", - "NombreFigura": "NombreFigura1", - "Domicilio": { - "Calle": "Calle1", - "NumeroExterior": "NumeroExterior1", - "NumeroInterior": "NumeroInterior1", - "Colonia": "Colonia1", - "Localidad": "Localidad1", - "Referencia": "Referencia1", - "Municipio": "Municipio1", - "Estado": "Estado1", - "Pais": "AFG", - "CodigoPostal": "CodigoPosta1" - } - } - } - }, - "VehiculoUsado": { - "Version": "1.0", - "montoAdquisicion": "10000.00", - "montoEnajenacion": "0.00", - "claveVehicular": "AAAABBB", - "marca": "FORD", - "tipo": "Mustang", - "modelo": "1989", - "numeroMotor": "123123123", - "numeroSerie": "12312323", - "NIV": "1234ASD", - "valor": "5000.00" - }, - "TimbreFiscalDigital": { - "xsi:schemaLocation": "http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigitalv11.xsd", - "Version": "1.1", - "UUID": "5e2d6aff-2dd7-43d1-83d3-14c1aca396d9", - "FechaTimbrado": "2021-02-17T14:13:10", - "RfcProvCertif": "SPR190613I52", - "SelloCFD": "HGJg9lit0Gr54foL1tBT+h/HnpjO9WdqJJldQPKoRUYGgo27ImMBgMoyn31Kz0qOxZA2IbW7Hl5MmxKd5ImdT3nPCRlX7E7wKMUkUdLzb95DvUXl4y2jX33Cd1g65i/9YJB5ItGj8BMFq79K7Yyxm2U/Z+Txfv1zeSRkQk0HT4VyM7mCUnru55AH3OBe692c7X2AAna4eNViZBi+C7fA1zmA4NuI6qTpQdsFgEy+dkCZRFNJIBgZ6VHtcwolA5uBGPKjWyndADpiYuPLhzLWn2TQEkWXW0geGoNFfFnPukbXqQTlZyBCZiEcRfQKWCzqpv8SM4PBhnXbPR0lKTFD2g==", - "NoCertificadoSAT": "30001000000400002495", - "SelloSAT": "cftZzLlTrJFLWOV9hUqy7NvnTqcId5UwZxybaztZYVgFWF46rV3uCEtxN+ZPKAJOhuYZs2FJlz1e8pS1uxl4lyViSdBELqxeZMeuICf6GqwneLe0QEY39jYHvpaGFnF9AT1KyXWdO2JQIdbiH/dbX2XV498hnnUrEaJbQOl8ovb5ZebTueu4zMcj8QE9nqmEavb7PB3O0w9vvmNl4hoo6XkCvDArlW1FlJdpaFaHDnjfjt+SriyZAszwjaUFvgkgHU7MJCYh37HQd1qVLLbHeGlwiwGOhQ9vu4ziu6zZ9wpb1lPHWfVCymFTAM3LaWuUvA19cReTEgR9yHX1OcNlOg==", - "xmlns:tfd": "http://www.sat.gob.mx/TimbreFiscalDigital", - "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance" - } - } - }); */ - }); -}); diff --git a/packages/cfdi/xml2json/vite.config.mts b/packages/cfdi/xml2json/vite.config.mts new file mode 100644 index 00000000..78f30cf9 --- /dev/null +++ b/packages/cfdi/xml2json/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xml-js'], + }, + }, +})); diff --git a/packages/cfdi/xsd/README.md b/packages/cfdi/xsd/README.md index 9487075c..3b1975cf 100644 --- a/packages/cfdi/xsd/README.md +++ b/packages/cfdi/xsd/README.md @@ -1 +1,62 @@ -utils +# @cfdi/xsd + +Validacion de CFDI contra esquemas XSD del SAT usando JSON Schema (AJV). Proporciona validadores para cada seccion del comprobante fiscal digital. + +## Instalacion + +```bash +npm install @cfdi/xsd +``` + +## Uso + +```typescript +import Schema from '@cfdi/xsd'; + +// Obtener instancia singleton +const schema = Schema.of(); + +// Configurar ruta a los esquemas JSON +schema.setConfig({ + path: '/ruta/a/schemas', + debug: false, +}); + +// Validar secciones del comprobante +const validadorComprobante = schema.cfdi.comprobante; +const validadorEmisor = schema.cfdi.emisor; +const validadorReceptor = schema.cfdi.receptor; +const validadorImpuestos = schema.cfdi.impuestos; +const validadorTraslado = schema.cfdi.traslado; +const validadorRetencion = schema.cfdi.retencion; +const validadorInfoGlobal = schema.cfdi.informacionGlobal; +const validadorRelacionados = schema.cfdi.relacionados; +const validadorRelacionado = schema.cfdi.relacionado; + +// Validar conceptos +const validadorConcepto = schema.concepto.concepto; +const validadorParte = schema.concepto.parte; +const validadorPredial = schema.concepto.predial; +const validadorInfoAduanera = schema.concepto.informacionAduanera; +const validadorTrasladoConcepto = schema.concepto.traslado; +const validadorRetencionConcepto = schema.concepto.retencion; +``` + +## API + +### `Schema` + +Clase singleton que gestiona los esquemas de validacion. + +| Metodo/Propiedad | Descripcion | +|------------------|-------------| +| `Schema.of()` | Retorna la instancia singleton | +| `setConfig({ path, debug })` | Configura la ruta a los archivos de esquema JSON y modo debug | +| `cfdi` | Acceso a validadores del comprobante (comprobante, emisor, receptor, impuestos, etc.) | +| `concepto` | Acceso a validadores de conceptos (concepto, parte, predial, traslado, retencion, etc.) | + +Los archivos de esquema deben estar en formato JSON generados a partir de los XSD oficiales del SAT. + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/cfdi/xsd/config/index.js b/packages/cfdi/xsd/config/index.js deleted file mode 100644 index 50c75928..00000000 --- a/packages/cfdi/xsd/config/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict' -module.exports = require('./xsd.cjs.production.min.js') diff --git a/packages/cfdi/xsd/package.json b/packages/cfdi/xsd/package.json index 93ae339f..a4a65902 100644 --- a/packages/cfdi/xsd/package.json +++ b/packages/cfdi/xsd/package.json @@ -2,9 +2,9 @@ "name": "@cfdi/xsd", "version": "4.0.16", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/xsd.esm.production.min.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "release": { "branches": [ @@ -17,25 +17,14 @@ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build --env production --minify && rimraf ./dist/index.js ./dist/xsd.cjs.development.* && npm run cp", - "cp": "cp ./config/index.js ./dist", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "publishConfig": { "registry": "https://registry.npmjs.org/", @@ -45,56 +34,21 @@ "type": "git", "url": "https://github.com/MisaelMa/recreando" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, "author": { "name": "Amir Misael Marin Coh, Signati", "email": "amisael.amir.misae@gmail.com, signatidev@gmail.com,", "url": "" }, - "size-limit": [ - { - "path": "dist/xsd.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/xsd.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "xml-js": "^1.6.11", - "xslt-processor": "^0.11.7", - "ajv": "^8.12.0", - "xslt": "^0.9.1" + "ajv": "^8.12.0" }, "devDependencies": { - "rimraf": "^6.0.1", "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", "@recreando/vite": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", + "@types/node": "^22", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/cfdi/xsd/vite.config.mts b/packages/cfdi/xsd/vite.config.mts new file mode 100644 index 00000000..1411fcb8 --- /dev/null +++ b/packages/cfdi/xsd/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['xml-js', 'ajv'], + }, + }, +})); diff --git a/packages/clir/openssl/README.md b/packages/clir/openssl/README.md index fa963ae1..35878fc3 100644 --- a/packages/clir/openssl/README.md +++ b/packages/clir/openssl/README.md @@ -1 +1,102 @@ -openssl +# @clir/openssl + +Wrapper de la CLI de OpenSSL para operaciones con certificados digitales. Proporciona una interfaz fluida (builder pattern) para construir y ejecutar comandos `x509` y `pkcs8`. + +## Instalacion + +```bash +npm install @clir/openssl +``` + +## Uso + +### x509 - Operaciones con certificados + +```typescript +import { x509 } from '@clir/openssl'; + +// Convertir certificado DER a PEM +const pem = x509.inform('DER').in('certificado.cer').outform('PEM').run(); + +// Obtener informacion del certificado +const texto = x509.inform('DER').in('certificado.cer').noout().text().run(); + +// Obtener llave publica +const pubkey = x509.inform('DER').in('certificado.cer').noout().pubkey().run(); + +// Obtener numero de serie +const serial = x509.inform('DER').in('certificado.cer').noout().serial().run(); + +// Obtener huella digital +const fingerprint = x509.inform('DER').in('certificado.cer').noout().fingerprint().run(); + +// Verificar si expira en N segundos +const check = x509.inform('DER').in('certificado.cer').noout().checkend(86400).run(); + +// Obtener solo el comando como string (sin ejecutar) +const cmd = x509.inform('DER').in('certificado.cer').noout().text().cli(); +``` + +### pkcs8 - Operaciones con llaves privadas + +```typescript +import { pkcs8 } from '@clir/openssl'; + +// Convertir llave privada DER a PEM con contrasena +const pem = pkcs8 + .inform('DER') + .in('llave.key') + .outform('PEM') + .passin('pass:contrasena123') + .run(); + +// Convertir a formato tradicional sin cifrado +const trad = pkcs8.topk8().traditional().nocrypt().run(); + +// Obtener el comando sin ejecutar +const cmd = pkcs8.inform('DER').in('llave.key').cli(); +``` + +## API + +### `x509` + +Instancia con interfaz fluida para comandos OpenSSL x509. + +| Metodo | Descripcion | +|--------|-------------| +| `inform(format)` | Formato de entrada: `'DER'`, `'PEM'` | +| `in(file)` | Archivo de entrada | +| `outform(format)` | Formato de salida: `'DER'`, `'PEM'` | +| `noout()` | No imprimir el certificado | +| `text()` | Imprimir certificado en texto legible | +| `pubkey()` | Extraer llave publica | +| `serial()` | Obtener numero de serie | +| `fingerprint()` | Obtener huella digital | +| `checkend(seconds)` | Verificar expiracion | +| `subject()` | Obtener subject del certificado | +| `issuer()` | Obtener issuer del certificado | +| `startdate()` | Fecha de inicio de validez | +| `enddate()` | Fecha de fin de validez | +| `run()` | Ejecutar el comando y retornar resultado | +| `cli()` | Retornar el comando como string sin ejecutar | + +### `pkcs8` + +Instancia con interfaz fluida para comandos OpenSSL pkcs8. + +| Metodo | Descripcion | +|--------|-------------| +| `inform(format)` | Formato de entrada | +| `in(file)` | Archivo de entrada | +| `outform(format)` | Formato de salida | +| `passin(pass)` | Contrasena de entrada (ej: `'pass:123'`) | +| `topk8()` | Convertir a formato PKCS#8 | +| `traditional()` | Usar formato tradicional | +| `nocrypt()` | Sin cifrado | +| `run()` | Ejecutar el comando y retornar resultado | +| `cli()` | Retornar el comando como string sin ejecutar | + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/clir/openssl/package.json b/packages/clir/openssl/package.json index 17eafe08..7a485ccf 100644 --- a/packages/clir/openssl/package.json +++ b/packages/clir/openssl/package.json @@ -2,81 +2,39 @@ "name": "@clir/openssl", "version": "0.0.16", "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/openssl.esm.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "files": [ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "author": "MisaelMa", - "size-limit": [ - { - "path": "dist/openssl.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/openssl.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "moment": "^2.29.4", "node-forge": "^1.3.1", "@esm2cjs/execa": "^6.1.1-cjs.1" }, "devDependencies": { "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", + "@recreando/vite": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@testing-library/dom": "^8.19.0", - "@testing-library/jest-dom": "^5.16.1", - "@types/deep-freeze": "^0.1.2", - "@types/jest": "^27.5.0", - "@types/node": "^18.11.3", + "@types/node": "^22", "@types/node-forge": "^1.0.4", - "@types/testing-library__jest-dom": "^5.9.1", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", "eslint": "^8.57.0", - "husky": "^8.0.1", - "jest": "^28.1.2", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", "@vitest/coverage-v8": "2.1.3", "@vitest/ui": "2.1.3" } -} \ No newline at end of file +} diff --git a/packages/clir/openssl/vite.config.mts b/packages/clir/openssl/vite.config.mts new file mode 100644 index 00000000..aece34e7 --- /dev/null +++ b/packages/clir/openssl/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['node-forge', '@esm2cjs/execa'], + }, + }, +})); diff --git a/packages/clir/saxon-he/README.md b/packages/clir/saxon-he/README.md index e69de29b..a777b51b 100644 --- a/packages/clir/saxon-he/README.md +++ b/packages/clir/saxon-he/README.md @@ -0,0 +1,117 @@ +# @saxon-he/cli + +Wrapper de Saxon-HE para ejecutar transformaciones XSLT y consultas XPath desde Node.js. Proporciona una API fluida (builder pattern) que construye y ejecuta comandos Saxon-HE. + +## Instalacion + +```bash +npm install @saxon-he/cli +``` + +Requiere tener el binario de Saxon-HE instalado en el sistema. + +## Uso + +### Transformacion XSLT + +```typescript +import { Transform } from '@saxon-he/cli'; + +const transform = new Transform({ binary: '/ruta/saxon-he' }); + +const resultado = transform + .s('/ruta/archivo.xml') // Archivo XML de entrada + .xsl('/ruta/estilos.xslt') // Hoja de estilos XSLT + .warnings('silent') // Silenciar advertencias + .run(); // Ejecutar y obtener resultado + +console.log(resultado); +``` + +### Transformacion con salida a archivo + +```typescript +const transform = new Transform({ binary: '/ruta/saxon-he' }); + +transform + .s('/ruta/entrada.xml') + .xsl('/ruta/transformacion.xslt') + .o('/ruta/salida.html') // Archivo de salida + .run(); +``` + +### Consulta XQuery + +```typescript +import { Query } from '@saxon-he/cli'; + +const query = new Query({ binary: '/ruta/saxon-he' }); + +const resultado = query + .s('/ruta/archivo.xml') + .qs('//elemento/@atributo') // Consulta XQuery inline + .run(); +``` + +### Consulta desde archivo + +```typescript +const query = new Query({ binary: '/ruta/saxon-he' }); + +const resultado = query + .s('/ruta/datos.xml') + .q('/ruta/consulta.xq') // Archivo de consulta XQuery + .projection('on') + .run(); +``` + +## API + +### Clase `Transform` + +Metodos principales para transformaciones XSLT: + +| Metodo | Descripcion | +|--------|-------------| +| `s(filename)` | Archivo XML de entrada | +| `xsl(filename)` | Hoja de estilos XSLT | +| `o(filename)` | Archivo de salida | +| `im(modename)` | Modo inicial de la transformacion | +| `it(template)` | Template inicial | +| `warnings(level)` | Nivel de advertencias: `'silent'`, `'recover'`, `'fatal'` | +| `a(option)` | Activar/desactivar resolvedores: `'on'`, `'off'` | +| `run()` | Ejecutar el comando y retornar el resultado como string | + +### Clase `Query` + +Metodos principales para consultas XQuery/XPath: + +| Metodo | Descripcion | +|--------|-------------| +| `s(filename)` | Archivo XML de entrada | +| `q(queryfile)` | Archivo de consulta XQuery | +| `qs(querystring)` | Consulta XQuery inline | +| `backup(option)` | Activar/desactivar backup: `'on'`, `'off'` | +| `projection(option)` | Activar/desactivar proyeccion: `'on'`, `'off'` | +| `stream(option)` | Activar/desactivar streaming: `'on'`, `'off'` | +| `run()` | Ejecutar el comando y retornar el resultado como string | + +### Metodos compartidos (Transform y Query) + +Ambas clases heredan de `CliShare` y comparten estos metodos: + +| Metodo | Descripcion | +|--------|-------------| +| `o(filename)` | Archivo de salida | +| `s(filename)` | Archivo XML de entrada | +| `val(validation)` | Validacion: `'strict'`, `'lax'` | +| `dtd(option)` | Procesamiento DTD | +| `expand(option)` | Expansion de atributos | +| `xsd(file)` | Archivo de esquema XSD | +| `strip(option)` | Eliminacion de espacios en blanco | +| `catalog(filenames)` | Catalogos XML | +| `run()` | Ejecutar el comando | + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/clir/saxon-he/package.json b/packages/clir/saxon-he/package.json index 1212ac7f..ee020d7b 100644 --- a/packages/clir/saxon-he/package.json +++ b/packages/clir/saxon-he/package.json @@ -2,65 +2,33 @@ "version": "12.5.1", "license": "MIT", "name": "@saxon-he/cli", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/saxon-he.esm.js", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "source": "./src/index.ts", "files": [ "dist" ], "engines": { - "node": ">=10" + "node": ">=22" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build", + "build": "vite build", "test": "vitest", "test:ci": "vitest run", - "test:coverage": "vitest --coverage run", - "test:ui": "vitest --ui", - "lint": "tsdx lint", - "prepare": "npm run build", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" }, "author": "MisaelMa", - "size-limit": [ - { - "path": "dist/saxon-he.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/saxon-he.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "@esm2cjs/execa": "^6.1.1-cjs.1" }, "devDependencies": { "@recreando/eslint-settings": "workspace:*", - "@recreando/jest": "workspace:*", + "@recreando/vite": "workspace:*", "@recreando/typescript-settings": "workspace:*", - "@rushstack/eslint-config": "^4.0.2", - "@rushstack/heft": "^0.68.6", - "@size-limit/preset-small-lib": "^7.0.8", - "@types/node": "^18.11.3", + "@types/node": "^22", "eslint": "^8.57.0", - "size-limit": "^7.0.8", - "tsdx": "^0.14.1", - "tslib": "^2.4.0", "typescript": "^5.6.3", "vitest": "2.1.3", "vite-tsconfig-paths": "~4.2.1", diff --git a/packages/clir/saxon-he/vite.config.mts b/packages/clir/saxon-he/vite.config.mts new file mode 100644 index 00000000..33048890 --- /dev/null +++ b/packages/clir/saxon-he/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['@esm2cjs/execa'], + }, + }, +})); diff --git a/packages/files/3.3/ComercioExterior11.xslt b/packages/files/3.3/ComercioExterior11.xslt new file mode 100644 index 00000000..3f8bb3a6 --- /dev/null +++ b/packages/files/3.3/ComercioExterior11.xslt @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/3.3/Pagos10.xslt b/packages/files/3.3/Pagos10.xslt new file mode 100644 index 00000000..31e45488 --- /dev/null +++ b/packages/files/3.3/Pagos10.xslt @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/3.3/TuristaPasajeroExtranjero.xslt b/packages/files/3.3/TuristaPasajeroExtranjero.xslt new file mode 100644 index 00000000..d2b8c150 --- /dev/null +++ b/packages/files/3.3/TuristaPasajeroExtranjero.xslt @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/aerolineas.xslt b/packages/files/3.3/aerolineas.xslt new file mode 100644 index 00000000..f7beebd6 --- /dev/null +++ b/packages/files/3.3/aerolineas.xslt @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/cadenaoriginal-3.3.xslt b/packages/files/3.3/cadenaoriginal-3.3.xslt new file mode 100644 index 00000000..3604276c --- /dev/null +++ b/packages/files/3.3/cadenaoriginal-3.3.xslt @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ||| + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/cadenaoriginal_TFD_1_1.xslt b/packages/files/3.3/cadenaoriginal_TFD_1_1.xslt new file mode 100644 index 00000000..1c734792 --- /dev/null +++ b/packages/files/3.3/cadenaoriginal_TFD_1_1.xslt @@ -0,0 +1,47 @@ + + + + + + | + + + + + + | + + + + + + + + + ||| + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/certificadodedestruccion.xslt b/packages/files/3.3/certificadodedestruccion.xslt new file mode 100644 index 00000000..fed91851 --- /dev/null +++ b/packages/files/3.3/certificadodedestruccion.xslt @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/cfdiregistrofiscal.xslt b/packages/files/3.3/cfdiregistrofiscal.xslt new file mode 100644 index 00000000..7d06913d --- /dev/null +++ b/packages/files/3.3/cfdiregistrofiscal.xslt @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/consumodeCombustibles11.xslt b/packages/files/3.3/consumodeCombustibles11.xslt new file mode 100644 index 00000000..d6c63d16 --- /dev/null +++ b/packages/files/3.3/consumodeCombustibles11.xslt @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/3.3/detallista.xslt b/packages/files/3.3/detallista.xslt new file mode 100644 index 00000000..7051f19c --- /dev/null +++ b/packages/files/3.3/detallista.xslt @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/divisas.xslt b/packages/files/3.3/divisas.xslt new file mode 100644 index 00000000..36fabbee --- /dev/null +++ b/packages/files/3.3/divisas.xslt @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/packages/files/3.3/donat11.xslt b/packages/files/3.3/donat11.xslt new file mode 100644 index 00000000..ead3e700 --- /dev/null +++ b/packages/files/3.3/donat11.xslt @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/packages/files/3.3/ecc11.xslt b/packages/files/3.3/ecc11.xslt new file mode 100644 index 00000000..e0e7fe6e --- /dev/null +++ b/packages/files/3.3/ecc11.xslt @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/3.3/gceh.xslt b/packages/files/3.3/gceh.xslt new file mode 100644 index 00000000..79f90c56 --- /dev/null +++ b/packages/files/3.3/gceh.xslt @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/3.3/iedu.xslt b/packages/files/3.3/iedu.xslt new file mode 100644 index 00000000..c0e9014f --- /dev/null +++ b/packages/files/3.3/iedu.xslt @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/ieeh.xslt b/packages/files/3.3/ieeh.xslt new file mode 100644 index 00000000..3d635d28 --- /dev/null +++ b/packages/files/3.3/ieeh.xslt @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/3.3/implocal.xslt b/packages/files/3.3/implocal.xslt new file mode 100644 index 00000000..f17a6eff --- /dev/null +++ b/packages/files/3.3/implocal.xslt @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/ine11.xslt b/packages/files/3.3/ine11.xslt new file mode 100644 index 00000000..820c1c5e --- /dev/null +++ b/packages/files/3.3/ine11.xslt @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/3.3/leyendasFisc.xslt b/packages/files/3.3/leyendasFisc.xslt new file mode 100644 index 00000000..948e360c --- /dev/null +++ b/packages/files/3.3/leyendasFisc.xslt @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/nomina12.xslt b/packages/files/3.3/nomina12.xslt new file mode 100644 index 00000000..98f6ff52 --- /dev/null +++ b/packages/files/3.3/nomina12.xslt @@ -0,0 +1,412 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/3.3/notariospublicos.xslt b/packages/files/3.3/notariospublicos.xslt new file mode 100644 index 00000000..fc0696f6 --- /dev/null +++ b/packages/files/3.3/notariospublicos.xslt @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/obrasarteantiguedades.xslt b/packages/files/3.3/obrasarteantiguedades.xslt new file mode 100644 index 00000000..6d4542bd --- /dev/null +++ b/packages/files/3.3/obrasarteantiguedades.xslt @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/pagoenespecie.xslt b/packages/files/3.3/pagoenespecie.xslt new file mode 100644 index 00000000..aa721bfc --- /dev/null +++ b/packages/files/3.3/pagoenespecie.xslt @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/pfic.xslt b/packages/files/3.3/pfic.xslt new file mode 100644 index 00000000..2aa9c5bc --- /dev/null +++ b/packages/files/3.3/pfic.xslt @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/renovacionysustitucionvehiculos.xslt b/packages/files/3.3/renovacionysustitucionvehiculos.xslt new file mode 100644 index 00000000..c7345ac4 --- /dev/null +++ b/packages/files/3.3/renovacionysustitucionvehiculos.xslt @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/3.3/servicioparcialconstruccion.xslt b/packages/files/3.3/servicioparcialconstruccion.xslt new file mode 100644 index 00000000..3bf16c82 --- /dev/null +++ b/packages/files/3.3/servicioparcialconstruccion.xslt @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/terceros11.xslt b/packages/files/3.3/terceros11.xslt new file mode 100644 index 00000000..2f3e141b --- /dev/null +++ b/packages/files/3.3/terceros11.xslt @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/utilerias.xslt b/packages/files/3.3/utilerias.xslt new file mode 100644 index 00000000..12a9fbed --- /dev/null +++ b/packages/files/3.3/utilerias.xslt @@ -0,0 +1,22 @@ + + + + + + | + + + + + + + + | + + + + + + + + diff --git a/packages/files/3.3/valesdedespensa.xslt b/packages/files/3.3/valesdedespensa.xslt new file mode 100644 index 00000000..2d278a63 --- /dev/null +++ b/packages/files/3.3/valesdedespensa.xslt @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/vehiculousado.xslt b/packages/files/3.3/vehiculousado.xslt new file mode 100644 index 00000000..b647dcc9 --- /dev/null +++ b/packages/files/3.3/vehiculousado.xslt @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/3.3/ventavehiculos11.xslt b/packages/files/3.3/ventavehiculos11.xslt new file mode 100644 index 00000000..776a7a71 --- /dev/null +++ b/packages/files/3.3/ventavehiculos11.xslt @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/4.0/Anexo20_2022.pdf b/packages/files/4.0/Anexo20_2022.pdf new file mode 100644 index 00000000..5be44397 Binary files /dev/null and b/packages/files/4.0/Anexo20_2022.pdf differ diff --git a/packages/files/4.0/Anexo_20_Guia_de_llenado_CFDI.pdf b/packages/files/4.0/Anexo_20_Guia_de_llenado_CFDI.pdf new file mode 100644 index 00000000..0b5ab4ec Binary files /dev/null and b/packages/files/4.0/Anexo_20_Guia_de_llenado_CFDI.pdf differ diff --git a/packages/files/4.0/Guia_llenado_CFDI_global.pdf b/packages/files/4.0/Guia_llenado_CFDI_global.pdf new file mode 100644 index 00000000..224fdb12 Binary files /dev/null and b/packages/files/4.0/Guia_llenado_CFDI_global.pdf differ diff --git a/packages/files/4.0/MatrizDeErrores_CFDI_v40_20241213.xls b/packages/files/4.0/MatrizDeErrores_CFDI_v40_20241213.xls new file mode 100644 index 00000000..523950a8 Binary files /dev/null and b/packages/files/4.0/MatrizDeErrores_CFDI_v40_20241213.xls differ diff --git a/packages/files/4.0/cadenaoriginal.xslt b/packages/files/4.0/cadenaoriginal.xslt index 2094a9b1..5bc6737c 100644 --- a/packages/files/4.0/cadenaoriginal.xslt +++ b/packages/files/4.0/cadenaoriginal.xslt @@ -1,409 +1,408 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ||| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ||| + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/4.0/cadenaoriginal_4_0.xslt b/packages/files/4.0/cadenaoriginal_4_0.xslt new file mode 100644 index 00000000..69d889b8 --- /dev/null +++ b/packages/files/4.0/cadenaoriginal_4_0.xslt @@ -0,0 +1,388 @@ +This XML file does not appear to have any style information associated with it. The document tree is shown below. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +| + +|| + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/4.0/catCFDI.xsd b/packages/files/4.0/catCFDI.xsd new file mode 100644 index 00000000..a61484f5 --- /dev/null +++ b/packages/files/4.0/catCFDI.xsd @@ -0,0 +1,162341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/4.0/cfdv40.xsd b/packages/files/4.0/cfdv40.xsd new file mode 100644 index 00000000..f93a2738 --- /dev/null +++ b/packages/files/4.0/cfdv40.xsd @@ -0,0 +1,850 @@ + + + + + + + Estándar de Comprobante Fiscal Digital por Internet. + + + + + + Nodo condicional para precisar la información relacionada con el comprobante global. + + + + + Atributo requerido para expresar el período al que corresponde la información del comprobante global. + + + + + Atributo requerido para expresar el mes o los meses al que corresponde la información del comprobante global. + + + + + Atributo requerido para expresar el año al que corresponde la información del comprobante global. + + + + + + + + + + + + + Nodo opcional para precisar la información de los comprobantes relacionados. + + + + + + Nodo requerido para precisar la información de los comprobantes relacionados. + + + + + Atributo requerido para registrar el folio fiscal (UUID) de un CFDI relacionado con el presente comprobante, por ejemplo: Si el CFDI relacionado es un comprobante de traslado que sirve para registrar el movimiento de la mercancía. Si este comprobante se usa como nota de crédito o nota de débito del comprobante relacionado. Si este comprobante es una devolución sobre el comprobante relacionado. Si éste sustituye a una factura cancelada. + + + + + + + + + + + + + + + Atributo requerido para indicar la clave de la relación que existe entre éste que se está generando y el o los CFDI previos. + + + + + + + Nodo requerido para expresar la información del contribuyente emisor del comprobante. + + + + + Atributo requerido para registrar la Clave del Registro Federal de Contribuyentes correspondiente al contribuyente emisor del comprobante. + + + + + Atributo requerido para registrar el nombre, denominación o razón social del contribuyente inscrito en el RFC, del emisor del comprobante. + + + + + + + + + + + + + Atributo requerido para incorporar la clave del régimen del contribuyente emisor al que aplicará el efecto fiscal de este comprobante. + + + + + Atributo condicional para expresar el número de operación proporcionado por el SAT cuando se trate de un comprobante a través de un PCECFDI o un PCGCFDISP. + + + + + + + + + + + + + + Nodo requerido para precisar la información del contribuyente receptor del comprobante. + + + + + Atributo requerido para registrar la Clave del Registro Federal de Contribuyentes correspondiente al contribuyente receptor del comprobante. + + + + + Atributo requerido para registrar el nombre(s), primer apellido, segundo apellido, según corresponda, denominación o razón social del contribuyente, inscrito en el RFC, del receptor del comprobante. + + + + + + + + + + + + + Atributo requerido para registrar el código postal del domicilio fiscal del receptor del comprobante. + + + + + + + + + + + + Atributo condicional para registrar la clave del país de residencia para efectos fiscales del receptor del comprobante, cuando se trate de un extranjero, y que es conforme con la especificación ISO 3166-1 alpha-3. Es requerido cuando se incluya el complemento de comercio exterior o se registre el atributo NumRegIdTrib. + + + + + Atributo condicional para expresar el número de registro de identidad fiscal del receptor cuando sea residente en el extranjero. Es requerido cuando se incluya el complemento de comercio exterior. + + + + + + + + + + + + Atributo requerido para incorporar la clave del régimen fiscal del contribuyente receptor al que aplicará el efecto fiscal de este comprobante. + + + + + Atributo requerido para expresar la clave del uso que dará a esta factura el receptor del CFDI. + + + + + + + Nodo requerido para listar los conceptos cubiertos por el comprobante. + + + + + + Nodo requerido para registrar la información detallada de un bien o servicio amparado en el comprobante. + + + + + + Nodo condicional para capturar los impuestos aplicables al presente concepto. + + + + + + Nodo opcional para asentar los impuestos trasladados aplicables al presente concepto. + + + + + + Nodo requerido para asentar la información detallada de un traslado de impuestos aplicable al presente concepto. + + + + + Atributo requerido para señalar la base para el cálculo del impuesto, la determinación de la base se realiza de acuerdo con las disposiciones fiscales vigentes. No se permiten valores negativos. + + + + + + + + + + + + Atributo requerido para señalar la clave del tipo de impuesto trasladado aplicable al concepto. + + + + + Atributo requerido para señalar la clave del tipo de factor que se aplica a la base del impuesto. + + + + + Atributo condicional para señalar el valor de la tasa o cuota del impuesto que se traslada para el presente concepto. Es requerido cuando el atributo TipoFactor tenga una clave que corresponda a Tasa o Cuota. + + + + + + + + + + + + Atributo condicional para señalar el importe del impuesto trasladado que aplica al concepto. No se permiten valores negativos. Es requerido cuando TipoFactor sea Tasa o Cuota. + + + + + + + + + + Nodo opcional para asentar los impuestos retenidos aplicables al presente concepto. + + + + + + Nodo requerido para asentar la información detallada de una retención de impuestos aplicable al presente concepto. + + + + + Atributo requerido para señalar la base para el cálculo de la retención, la determinación de la base se realiza de acuerdo con las disposiciones fiscales vigentes. No se permiten valores negativos. + + + + + + + + + + + + Atributo requerido para señalar la clave del tipo de impuesto retenido aplicable al concepto. + + + + + Atributo requerido para señalar la clave del tipo de factor que se aplica a la base del impuesto. + + + + + Atributo requerido para señalar la tasa o cuota del impuesto que se retiene para el presente concepto. + + + + + + + + + + + + Atributo requerido para señalar el importe del impuesto retenido que aplica al concepto. No se permiten valores negativos. + + + + + + + + + + + + + Nodo opcional para registrar información del contribuyente Tercero, a cuenta del que se realiza la operación. + + + + + Atributo requerido para registrar la Clave del Registro Federal de Contribuyentes del contribuyente Tercero, a cuenta del que se realiza la operación. + + + + + Atributo requerido para registrar el nombre, denominación o razón social del contribuyente Tercero correspondiente con el Rfc, a cuenta del que se realiza la operación. + + + + + + + + + + + + + Atributo requerido para incorporar la clave del régimen del contribuyente Tercero, a cuenta del que se realiza la operación. + + + + + Atributo requerido para incorporar el código postal del domicilio fiscal del Tercero, a cuenta del que se realiza la operación. + + + + + + + + + + + + + + Nodo opcional para introducir la información aduanera aplicable cuando se trate de ventas de primera mano de mercancías importadas o se trate de operaciones de comercio exterior con bienes o servicios. + + + + + Atributo requerido para expresar el número del pedimento que ampara la importación del bien que se expresa en el siguiente formato: últimos 2 dígitos del año de validación seguidos por dos espacios, 2 dígitos de la aduana de despacho seguidos por dos espacios, 4 dígitos del número de la patente seguidos por dos espacios, 1 dígito que corresponde al último dígito del año en curso, salvo que se trate de un pedimento consolidado iniciado en el año inmediato anterior o del pedimento original de una rectificación, seguido de 6 dígitos de la numeración progresiva por aduana. + + + + + + + + + + + + + Nodo opcional para asentar el número de cuenta predial con el que fue registrado el inmueble, en el sistema catastral de la entidad federativa de que trate, o bien para incorporar los datos de identificación del certificado de participación inmobiliaria no amortizable. + + + + + Atributo requerido para precisar el número de la cuenta predial del inmueble cubierto por el presente concepto, o bien para incorporar los datos de identificación del certificado de participación inmobiliaria no amortizable, tratándose de arrendamiento. + + + + + + + + + + + + + + + Nodo opcional donde se incluyen los nodos complementarios de extensión al concepto definidos por el SAT, de acuerdo con las disposiciones particulares para un sector o actividad específica. + + + + + + + + + + Nodo opcional para expresar las partes o componentes que integran la totalidad del concepto expresado en el comprobante fiscal digital por Internet. + + + + + + Nodo opcional para introducir la información aduanera aplicable cuando se trate de ventas de primera mano de mercancías importadas o se trate de operaciones de comercio exterior con bienes o servicios. + + + + + Atributo requerido para expresar el número del pedimento que ampara la importación del bien que se expresa en el siguiente formato: últimos 2 dígitos del año de validación seguidos por dos espacios, 2 dígitos de la aduana de despacho seguidos por dos espacios, 4 dígitos del número de la patente seguidos por dos espacios, 1 dígito que corresponde al último dígito del año en curso, salvo que se trate de un pedimento consolidado iniciado en el año inmediato anterior o del pedimento original de una rectificación, seguido de 6 dígitos de la numeración progresiva por aduana. + + + + + + + + + + + + + + Atributo requerido para expresar la clave del producto o del servicio amparado por la presente parte. Es requerido y deben utilizar las claves del catálogo de productos y servicios, cuando los conceptos que registren por sus actividades correspondan con dichos conceptos. + + + + + Atributo opcional para expresar el número de serie, número de parte del bien o identificador del producto o del servicio amparado por la presente parte. Opcionalmente se puede utilizar claves del estándar GTIN. + + + + + + + + + + + + + Atributo requerido para precisar la cantidad de bienes o servicios del tipo particular definido por la presente parte. + + + + + + + + + + + + Atributo opcional para precisar la unidad de medida propia de la operación del emisor, aplicable para la cantidad expresada en la parte. La unidad debe corresponder con la descripción de la parte. + + + + + + + + + + + + + Atributo requerido para precisar la descripción del bien o servicio cubierto por la presente parte. + + + + + + + + + + + + + Atributo opcional para precisar el valor o precio unitario del bien o servicio cubierto por la presente parte. No se permiten valores negativos. + + + + + Atributo opcional para precisar el importe total de los bienes o servicios de la presente parte. Debe ser equivalente al resultado de multiplicar la cantidad por el valor unitario expresado en la parte. No se permiten valores negativos. + + + + + + + + Atributo requerido para expresar la clave del producto o del servicio amparado por el presente concepto. Es requerido y deben utilizar las claves del catálogo de productos y servicios, cuando los conceptos que registren por sus actividades correspondan con dichos conceptos. + + + + + Atributo opcional para expresar el número de parte, identificador del producto o del servicio, la clave de producto o servicio, SKU o equivalente, propia de la operación del emisor, amparado por el presente concepto. Opcionalmente se puede utilizar claves del estándar GTIN. + + + + + + + + + + + + + Atributo requerido para precisar la cantidad de bienes o servicios del tipo particular definido por el presente concepto. + + + + + + + + + + + + Atributo requerido para precisar la clave de unidad de medida estandarizada aplicable para la cantidad expresada en el concepto. La unidad debe corresponder con la descripción del concepto. + + + + + Atributo opcional para precisar la unidad de medida propia de la operación del emisor, aplicable para la cantidad expresada en el concepto. La unidad debe corresponder con la descripción del concepto. + + + + + + + + + + + + + Atributo requerido para precisar la descripción del bien o servicio cubierto por el presente concepto. + + + + + + + + + + + + + Atributo requerido para precisar el valor o precio unitario del bien o servicio cubierto por el presente concepto. + + + + + Atributo requerido para precisar el importe total de los bienes o servicios del presente concepto. Debe ser equivalente al resultado de multiplicar la cantidad por el valor unitario expresado en el concepto. No se permiten valores negativos. + + + + + Atributo opcional para representar el importe de los descuentos aplicables al concepto. No se permiten valores negativos. + + + + + Atributo requerido para expresar si la operación comercial es objeto o no de impuesto. + + + + + + + + + + Nodo condicional para expresar el resumen de los impuestos aplicables. + + + + + + Nodo condicional para capturar los impuestos retenidos aplicables. Es requerido cuando en los conceptos se registre algún impuesto retenido. + + + + + + Nodo requerido para la información detallada de una retención de impuesto específico. + + + + + Atributo requerido para señalar la clave del tipo de impuesto retenido. + + + + + Atributo requerido para señalar el monto del impuesto retenido. No se permiten valores negativos. + + + + + + + + + + Nodo condicional para capturar los impuestos trasladados aplicables. Es requerido cuando en los conceptos se registre un impuesto trasladado. + + + + + + Nodo requerido para la información detallada de un traslado de impuesto específico. + + + + + Atributo requerido para señalar la suma de los atributos Base de los conceptos del impuesto trasladado. No se permiten valores negativos. + + + + + Atributo requerido para señalar la clave del tipo de impuesto trasladado. + + + + + Atributo requerido para señalar la clave del tipo de factor que se aplica a la base del impuesto. + + + + + Atributo condicional para señalar el valor de la tasa o cuota del impuesto que se traslada por los conceptos amparados en el comprobante. + + + + + + + + + + + + Atributo condicional para señalar la suma del importe del impuesto trasladado, agrupado por impuesto, TipoFactor y TasaOCuota. No se permiten valores negativos. + + + + + + + + + + + Atributo condicional para expresar el total de los impuestos retenidos que se desprenden de los conceptos expresados en el comprobante fiscal digital por Internet. No se permiten valores negativos. Es requerido cuando en los conceptos se registren impuestos retenidos. + + + + + Atributo condicional para expresar el total de los impuestos trasladados que se desprenden de los conceptos expresados en el comprobante fiscal digital por Internet. No se permiten valores negativos. Es requerido cuando en los conceptos se registren impuestos trasladados. + + + + + + + Nodo opcional donde se incluye el complemento Timbre Fiscal Digital de manera obligatoria y los nodos complementarios determinados por el SAT, de acuerdo con las disposiciones particulares para un sector o actividad específica. + + + + + + + + + + Nodo opcional para recibir las extensiones al presente formato que sean de utilidad al contribuyente. Para las reglas de uso del mismo, referirse al formato origen. + + + + + + + + + + + Atributo requerido con valor prefijado a 4.0 que indica la versión del estándar bajo el que se encuentra expresado el comprobante. + + + + + + + + + + Atributo opcional para precisar la serie para control interno del contribuyente. Este atributo acepta una cadena de caracteres. + + + + + + + + + + + + + Atributo opcional para control interno del contribuyente que expresa el folio del comprobante, acepta una cadena de caracteres. + + + + + + + + + + + + + Atributo requerido para la expresión de la fecha y hora de expedición del Comprobante Fiscal Digital por Internet. Se expresa en la forma AAAA-MM-DDThh:mm:ss y debe corresponder con la hora local donde se expide el comprobante. + + + + + Atributo requerido para contener el sello digital del comprobante fiscal, al que hacen referencia las reglas de resolución miscelánea vigente. El sello debe ser expresado como una cadena de texto en formato Base 64. + + + + + + + + + + Atributo condicional para expresar la clave de la forma de pago de los bienes o servicios amparados por el comprobante. + + + + + Atributo requerido para expresar el número de serie del certificado de sello digital que ampara al comprobante, de acuerdo con el acuse correspondiente a 20 posiciones otorgado por el sistema del SAT. + + + + + + + + + + + + Atributo requerido que sirve para incorporar el certificado de sello digital que ampara al comprobante, como texto en formato base 64. + + + + + + + + + + Atributo condicional para expresar las condiciones comerciales aplicables para el pago del comprobante fiscal digital por Internet. Este atributo puede ser condicionado mediante atributos o complementos. + + + + + + + + + + + + + Atributo requerido para representar la suma de los importes de los conceptos antes de descuentos e impuesto. No se permiten valores negativos. + + + + + Atributo condicional para representar el importe total de los descuentos aplicables antes de impuestos. No se permiten valores negativos. Se debe registrar cuando existan conceptos con descuento. + + + + + Atributo requerido para identificar la clave de la moneda utilizada para expresar los montos, cuando se usa moneda nacional se registra MXN. Conforme con la especificación ISO 4217. + + + + + Atributo condicional para representar el tipo de cambio FIX conforme con la moneda usada. Es requerido cuando la clave de moneda es distinta de MXN y de XXX. El valor debe reflejar el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo moneda. Si el valor está fuera del porcentaje aplicable a la moneda tomado del catálogo c_Moneda, el emisor debe obtener del PAC que vaya a timbrar el CFDI, de manera no automática, una clave de confirmación para ratificar que el valor es correcto e integrar dicha clave en el atributo Confirmacion. + + + + + + + + + + + + Atributo requerido para representar la suma del subtotal, menos los descuentos aplicables, más las contribuciones recibidas (impuestos trasladados - federales y/o locales, derechos, productos, aprovechamientos, aportaciones de seguridad social, contribuciones de mejoras) menos los impuestos retenidos federales y/o locales. Si el valor es superior al límite que establezca el SAT en la Resolución Miscelánea Fiscal vigente, el emisor debe obtener del PAC que vaya a timbrar el CFDI, de manera no automática, una clave de confirmación para ratificar que el valor es correcto e integrar dicha clave en el atributo Confirmacion. No se permiten valores negativos. + + + + + Atributo requerido para expresar la clave del efecto del comprobante fiscal para el contribuyente emisor. + + + + + Atributo requerido para expresar si el comprobante ampara una operación de exportación. + + + + + Atributo condicional para precisar la clave del método de pago que aplica para este comprobante fiscal digital por Internet, conforme al Artículo 29-A fracción VII incisos a y b del CFF. + + + + + Atributo requerido para incorporar el código postal del lugar de expedición del comprobante (domicilio de la matriz o de la sucursal). + + + + + Atributo condicional para registrar la clave de confirmación que entregue el PAC para expedir el comprobante con importes grandes, con un tipo de cambio fuera del rango establecido o con ambos casos. Es requerido cuando se registra un tipo de cambio o un total fuera del rango establecido. + + + + + + + + + + + + diff --git a/packages/files/4.0/complementos/CartaPorte20.xslt b/packages/files/4.0/complementos/CartaPorte20.xslt index 95c3c472..5aefbf25 100644 --- a/packages/files/4.0/complementos/CartaPorte20.xslt +++ b/packages/files/4.0/complementos/CartaPorte20.xslt @@ -1,617 +1,615 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/4.0/complementos/CartaPorte30.xslt b/packages/files/4.0/complementos/CartaPorte30.xslt new file mode 100644 index 00000000..d5fe39b8 --- /dev/null +++ b/packages/files/4.0/complementos/CartaPorte30.xslt @@ -0,0 +1,744 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/4.0/complementos/CartaPorte31.xslt b/packages/files/4.0/complementos/CartaPorte31.xslt new file mode 100644 index 00000000..c465334b --- /dev/null +++ b/packages/files/4.0/complementos/CartaPorte31.xslt @@ -0,0 +1,762 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/4.0/complementos/ComercioExterior11.xslt b/packages/files/4.0/complementos/ComercioExterior11.xslt index f405fa04..d98e6aeb 100644 --- a/packages/files/4.0/complementos/ComercioExterior11.xslt +++ b/packages/files/4.0/complementos/ComercioExterior11.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/ComercioExterior20.xslt b/packages/files/4.0/complementos/ComercioExterior20.xslt new file mode 100644 index 00000000..4d37ba93 --- /dev/null +++ b/packages/files/4.0/complementos/ComercioExterior20.xslt @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/4.0/complementos/GastosHidrocarburos10.xslt b/packages/files/4.0/complementos/GastosHidrocarburos10.xslt index 79f90c56..85ad2785 100644 --- a/packages/files/4.0/complementos/GastosHidrocarburos10.xslt +++ b/packages/files/4.0/complementos/GastosHidrocarburos10.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/IngresosHidrocarburos.xslt b/packages/files/4.0/complementos/IngresosHidrocarburos.xslt index 3d635d28..6db5c5cc 100644 --- a/packages/files/4.0/complementos/IngresosHidrocarburos.xslt +++ b/packages/files/4.0/complementos/IngresosHidrocarburos.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/certificadodedestruccion.xslt b/packages/files/4.0/complementos/certificadodedestruccion.xslt index fed91851..18f42fc0 100644 --- a/packages/files/4.0/complementos/certificadodedestruccion.xslt +++ b/packages/files/4.0/complementos/certificadodedestruccion.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/consumodeCombustibles11.xslt b/packages/files/4.0/complementos/consumodeCombustibles11.xslt index d6c63d16..6249645c 100644 --- a/packages/files/4.0/complementos/consumodeCombustibles11.xslt +++ b/packages/files/4.0/complementos/consumodeCombustibles11.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/ecc12.xslt b/packages/files/4.0/complementos/ecc12.xslt index 925aa7c6..acb96c3a 100644 --- a/packages/files/4.0/complementos/ecc12.xslt +++ b/packages/files/4.0/complementos/ecc12.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/ine11.xslt b/packages/files/4.0/complementos/ine11.xslt index 06def84b..c1baa6b0 100644 --- a/packages/files/4.0/complementos/ine11.xslt +++ b/packages/files/4.0/complementos/ine11.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/nomina12.xslt b/packages/files/4.0/complementos/nomina12.xslt index 8982ea23..d350def0 100644 --- a/packages/files/4.0/complementos/nomina12.xslt +++ b/packages/files/4.0/complementos/nomina12.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/obrasarteantiguedades.xslt b/packages/files/4.0/complementos/obrasarteantiguedades.xslt index d7868932..ce8899f0 100644 --- a/packages/files/4.0/complementos/obrasarteantiguedades.xslt +++ b/packages/files/4.0/complementos/obrasarteantiguedades.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/pagoenespecie.xslt b/packages/files/4.0/complementos/pagoenespecie.xslt index c8051061..2f7412f4 100644 --- a/packages/files/4.0/complementos/pagoenespecie.xslt +++ b/packages/files/4.0/complementos/pagoenespecie.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/renovacionysustitucionvehiculos.xslt b/packages/files/4.0/complementos/renovacionysustitucionvehiculos.xslt index c7345ac4..b1e50fac 100644 --- a/packages/files/4.0/complementos/renovacionysustitucionvehiculos.xslt +++ b/packages/files/4.0/complementos/renovacionysustitucionvehiculos.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/servicioparcialconstruccion.xslt b/packages/files/4.0/complementos/servicioparcialconstruccion.xslt index 4abc2d57..b8012b68 100644 --- a/packages/files/4.0/complementos/servicioparcialconstruccion.xslt +++ b/packages/files/4.0/complementos/servicioparcialconstruccion.xslt @@ -1,4 +1,4 @@ - + diff --git a/packages/files/4.0/complementos/vehiculousado.xslt b/packages/files/4.0/complementos/vehiculousado.xslt index 352643be..1447e9d6 100644 --- a/packages/files/4.0/complementos/vehiculousado.xslt +++ b/packages/files/4.0/complementos/vehiculousado.xslt @@ -3,6 +3,9 @@ + + + ||| diff --git a/packages/files/4.0/tdCFDI.xsd b/packages/files/4.0/tdCFDI.xsd new file mode 100644 index 00000000..6eea7487 --- /dev/null +++ b/packages/files/4.0/tdCFDI.xsd @@ -0,0 +1,157 @@ + + + + + Tipo definido para expresar la Clave Única de Registro de Población (CURP) + + + + + + + + + + Tipo definido para expresar importes numéricos con fracción hasta seis decimales. No se permiten valores negativos. + + + + + + + + + + + Tipo definido para la expresión de la fecha. Se expresa en la forma AAAA-MM-DD. + + + + + + + + + Tipo definido para expresar importes monetarios en moneda nacional MXN con fracción hasta dos decimales. No se permiten valores negativos. + + + + + + + + + + + Tipo definido para expresar la cuenta bancarizada. + + + + + + + + + Tipo definido para expresar claves del Registro Federal de Contribuyentes + + + + + + + + + + + Tipo definido para la expresión de un Registro Federal de Contribuyentes de persona moral. + + + + + + + + + + Tipo definido para la expresión de un Registro Federal de Contribuyentes de persona física. + + + + + + + + + + Tipo definido para la expresión de la fecha y hora. Se expresa en la forma AAAA-MM-DDThh:mm:ss + + + + + + + + + Tipo definido para la expresión de la fecha y hora. Se expresa en la forma AAAA-MM-DDThh:mm:ss + + + + + + + + + Tipo definido para expresar la calle en que está ubicado el domicilio del emisor del comprobante o del destinatario de la mercancía. + + + + + + + + + + + Tipo definido para expresar el número interior o el número exterior en donde se ubica el domicilio del emisor del comprobante o del destinatario de la mercancía. + + + + + + + + + + + Tipo definido para expresar la referencia geográfica adicional que permita una fácil o precisa ubicación del domicilio del emisor del comprobante o del destinatario de la mercancía, por ejemplo las coordenadas GPS. + + + + + + + + + + + Tipo definido para expresar la colonia, localidad o municipio en que está ubicado el domicilio del emisor del comprobante o del destinatario de la mercancía. + + + + + + + + + + + Tipo definido para expresar el tipo de cambio. No se permiten valores negativos. + + + + + + + + + diff --git a/packages/files/xml/conceptos.xml b/packages/files/xml/conceptos.xml new file mode 100644 index 00000000..1619d847 --- /dev/null +++ b/packages/files/xml/conceptos.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/xml/dos-conceptos.xml b/packages/files/xml/dos-conceptos.xml new file mode 100644 index 00000000..98fa6e19 --- /dev/null +++ b/packages/files/xml/dos-conceptos.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/packages/files/xml/dos-impuestos.xml b/packages/files/xml/dos-impuestos.xml new file mode 100644 index 00000000..8ece1ac7 --- /dev/null +++ b/packages/files/xml/dos-impuestos.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/packages/files/xml/emisor-receptor.xml b/packages/files/xml/emisor-receptor.xml new file mode 100644 index 00000000..ff34efad --- /dev/null +++ b/packages/files/xml/emisor-receptor.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/files/xml/examples/cfdi33/CfdiUtils-cfdi33-real.xml b/packages/files/xml/examples/cfdi33/CfdiUtils-cfdi33-real.xml new file mode 100644 index 00000000..5b6daaa3 --- /dev/null +++ b/packages/files/xml/examples/cfdi33/CfdiUtils-cfdi33-real.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/CfdiUtils-cfdi33-valid.xml b/packages/files/xml/examples/cfdi33/CfdiUtils-cfdi33-valid.xml new file mode 100644 index 00000000..1422ac2f --- /dev/null +++ b/packages/files/xml/examples/cfdi33/CfdiUtils-cfdi33-valid.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/buzoncfdi-cfdireader-v33-valid-without-timbre.xml b/packages/files/xml/examples/cfdi33/buzoncfdi-cfdireader-v33-valid-without-timbre.xml new file mode 100644 index 00000000..afd4f503 --- /dev/null +++ b/packages/files/xml/examples/cfdi33/buzoncfdi-cfdireader-v33-valid-without-timbre.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/buzoncfdi-cfdireader-v33-valid.xml b/packages/files/xml/examples/cfdi33/buzoncfdi-cfdireader-v33-valid.xml new file mode 100644 index 00000000..17aa1816 --- /dev/null +++ b/packages/files/xml/examples/cfdi33/buzoncfdi-cfdireader-v33-valid.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-core-cfdi33.xml b/packages/files/xml/examples/cfdi33/cfdi-core-cfdi33.xml new file mode 100644 index 00000000..35a54a8c --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-core-cfdi33.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-expresiones-cfdi33-real.xml b/packages/files/xml/examples/cfdi33/cfdi-expresiones-cfdi33-real.xml new file mode 100644 index 00000000..e543f80b --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-expresiones-cfdi33-real.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-to-json-cfdi-example.xml b/packages/files/xml/examples/cfdi33/cfdi-to-json-cfdi-example.xml new file mode 100644 index 00000000..5b6daaa3 --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-to-json-cfdi-example.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-to-json-detallista-example.xml b/packages/files/xml/examples/cfdi33/cfdi-to-json-detallista-example.xml new file mode 100644 index 00000000..3a4fd57f --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-to-json-detallista-example.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + INVOICE + + + + Un mil ciento sesenta pesos 00/100 m.n. + + + + 3 + 2017-01-01 + + + 2 + + + 1 + 2017-01-01 + + + 7504000107903 + + + 0101 + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-to-pdf-cfdi33-payment-valid.xml b/packages/files/xml/examples/cfdi33/cfdi-to-pdf-cfdi33-payment-valid.xml new file mode 100644 index 00000000..b6489c12 --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-to-pdf-cfdi33-payment-valid.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-to-pdf-cfdi33-valid.xml b/packages/files/xml/examples/cfdi33/cfdi-to-pdf-cfdi33-valid.xml new file mode 100644 index 00000000..2447fb77 --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-to-pdf-cfdi33-valid.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-validator-cfdi33-real.xml b/packages/files/xml/examples/cfdi33/cfdi-validator-cfdi33-real.xml new file mode 100644 index 00000000..5b6daaa3 --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-validator-cfdi33-real.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-validator-cfdi33-valid.xml b/packages/files/xml/examples/cfdi33/cfdi-validator-cfdi33-valid.xml new file mode 100644 index 00000000..1422ac2f --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-validator-cfdi33-valid.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-validator-created-pago-with-ns-at-root-33.xml b/packages/files/xml/examples/cfdi33/cfdi-validator-created-pago-with-ns-at-root-33.xml new file mode 100644 index 00000000..b296aacf --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-validator-created-pago-with-ns-at-root-33.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-validator-created-with-discounts-33.xml b/packages/files/xml/examples/cfdi33/cfdi-validator-created-with-discounts-33.xml new file mode 100644 index 00000000..558993af --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-validator-created-with-discounts-33.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-validator-pagos10-sample-factura123.xml b/packages/files/xml/examples/cfdi33/cfdi-validator-pagos10-sample-factura123.xml new file mode 100644 index 00000000..88bd9faa --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-validator-pagos10-sample-factura123.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-validator-pagos10-sample-facturador01.xml b/packages/files/xml/examples/cfdi33/cfdi-validator-pagos10-sample-facturador01.xml new file mode 100644 index 00000000..6f1d64cc --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-validator-pagos10-sample-facturador01.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/cfdi-validator-pagos10-sample-validacfd01.xml b/packages/files/xml/examples/cfdi33/cfdi-validator-pagos10-sample-validacfd01.xml new file mode 100644 index 00000000..40cb398f --- /dev/null +++ b/packages/files/xml/examples/cfdi33/cfdi-validator-pagos10-sample-validacfd01.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi33/sat-ws-descarga-masiva-zip-cfdi.xml b/packages/files/xml/examples/cfdi33/sat-ws-descarga-masiva-zip-cfdi.xml new file mode 100644 index 00000000..ec430b91 --- /dev/null +++ b/packages/files/xml/examples/cfdi33/sat-ws-descarga-masiva-zip-cfdi.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/CfdiUtils-cfdi40-real.xml b/packages/files/xml/examples/cfdi40/CfdiUtils-cfdi40-real.xml new file mode 100644 index 00000000..881ab80a --- /dev/null +++ b/packages/files/xml/examples/cfdi40/CfdiUtils-cfdi40-real.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/CfdiUtils-cfdi40-valid.xml b/packages/files/xml/examples/cfdi40/CfdiUtils-cfdi40-valid.xml new file mode 100644 index 00000000..3d2d38e3 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/CfdiUtils-cfdi40-valid.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/CfdiUtils-created-cfdi40-pago20-valid.xml b/packages/files/xml/examples/cfdi40/CfdiUtils-created-cfdi40-pago20-valid.xml new file mode 100644 index 00000000..d820b646 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/CfdiUtils-created-cfdi40-pago20-valid.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/cfdi-expresiones-cfdi40-real.xml b/packages/files/xml/examples/cfdi40/cfdi-expresiones-cfdi40-real.xml new file mode 100644 index 00000000..cdf208aa --- /dev/null +++ b/packages/files/xml/examples/cfdi40/cfdi-expresiones-cfdi40-real.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/cfdi-validator-cfdi40-real.xml b/packages/files/xml/examples/cfdi40/cfdi-validator-cfdi40-real.xml new file mode 100644 index 00000000..b21e3d4e --- /dev/null +++ b/packages/files/xml/examples/cfdi40/cfdi-validator-cfdi40-real.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/cfdi-validator-cfdi40-valid.xml b/packages/files/xml/examples/cfdi40/cfdi-validator-cfdi40-valid.xml new file mode 100644 index 00000000..1dda5791 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/cfdi-validator-cfdi40-valid.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/cfdi-validator-created-with-discounts-40.xml b/packages/files/xml/examples/cfdi40/cfdi-validator-created-with-discounts-40.xml new file mode 100644 index 00000000..6f182fbf --- /dev/null +++ b/packages/files/xml/examples/cfdi40/cfdi-validator-created-with-discounts-40.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-credit-note.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-credit-note.xml new file mode 100644 index 00000000..e9f83f1c --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-credit-note.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-food-vouchers.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-food-vouchers.xml new file mode 100644 index 00000000..1db1978f --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-food-vouchers.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-fuel-account-balance.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-fuel-account-balance.xml new file mode 100644 index 00000000..0dcec892 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-fuel-account-balance.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2b-bare.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2b-bare.xml new file mode 100644 index 00000000..7451878d --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2b-bare.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2b-full-round.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2b-full-round.xml new file mode 100644 index 00000000..e0b074e7 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2b-full-round.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2b-full.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2b-full.xml new file mode 100644 index 00000000..c556143d --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2b-full.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c-inc-disc.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c-inc-disc.xml new file mode 100644 index 00000000..d3828a53 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c-inc-disc.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c-inc.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c-inc.xml new file mode 100644 index 00000000..b41b56e9 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c-inc.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c-third-party.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c-third-party.xml new file mode 100644 index 00000000..32983c64 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c-third-party.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c.xml new file mode 100644 index 00000000..7ed91dca --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-b2c.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-export-notax.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-export-notax.xml new file mode 100644 index 00000000..4d4479ca --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-export-notax.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-export.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-export.xml new file mode 100644 index 00000000..ff578310 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-export.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-global.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-global.xml new file mode 100644 index 00000000..ab3b1bc6 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-global.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-ieps-2.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-ieps-2.xml new file mode 100644 index 00000000..41025ef7 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-ieps-2.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-ieps.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-ieps.xml new file mode 100644 index 00000000..ab7023e5 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-ieps.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-multi-currency.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-multi-currency.xml new file mode 100644 index 00000000..481a14c5 --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-multi-currency.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-timbre.xml b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-timbre.xml new file mode 100644 index 00000000..2877812b --- /dev/null +++ b/packages/files/xml/examples/cfdi40/gobl.cfdi-invoice-timbre.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi33/egreso-nota-credito.xml b/packages/files/xml/examples/test-cfdi33/egreso-nota-credito.xml new file mode 100644 index 00000000..ae912198 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi33/egreso-nota-credito.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi33/ingreso-basico.xml b/packages/files/xml/examples/test-cfdi33/ingreso-basico.xml new file mode 100644 index 00000000..76ccf9cd --- /dev/null +++ b/packages/files/xml/examples/test-cfdi33/ingreso-basico.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi33/ingreso-dolares.xml b/packages/files/xml/examples/test-cfdi33/ingreso-dolares.xml new file mode 100644 index 00000000..ed416f29 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi33/ingreso-dolares.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi33/ingreso-exento.xml b/packages/files/xml/examples/test-cfdi33/ingreso-exento.xml new file mode 100644 index 00000000..ff5b26ee --- /dev/null +++ b/packages/files/xml/examples/test-cfdi33/ingreso-exento.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi33/ingreso-ieps.xml b/packages/files/xml/examples/test-cfdi33/ingreso-ieps.xml new file mode 100644 index 00000000..9215be5f --- /dev/null +++ b/packages/files/xml/examples/test-cfdi33/ingreso-ieps.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi33/ingreso-iva-retencion.xml b/packages/files/xml/examples/test-cfdi33/ingreso-iva-retencion.xml new file mode 100644 index 00000000..d23ffd11 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi33/ingreso-iva-retencion.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi33/ingreso-multi-concepto.xml b/packages/files/xml/examples/test-cfdi33/ingreso-multi-concepto.xml new file mode 100644 index 00000000..faedfa45 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi33/ingreso-multi-concepto.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi33/ingreso-parcialidades.xml b/packages/files/xml/examples/test-cfdi33/ingreso-parcialidades.xml new file mode 100644 index 00000000..7007f68b --- /dev/null +++ b/packages/files/xml/examples/test-cfdi33/ingreso-parcialidades.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi33/ingreso-sin-impuestos.xml b/packages/files/xml/examples/test-cfdi33/ingreso-sin-impuestos.xml new file mode 100644 index 00000000..2386a1d9 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi33/ingreso-sin-impuestos.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi33/traslado.xml b/packages/files/xml/examples/test-cfdi33/traslado.xml new file mode 100644 index 00000000..ffb9d1de --- /dev/null +++ b/packages/files/xml/examples/test-cfdi33/traslado.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi40/egreso-nota-credito.xml b/packages/files/xml/examples/test-cfdi40/egreso-nota-credito.xml new file mode 100644 index 00000000..e5fa8c26 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi40/egreso-nota-credito.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi40/ingreso-basico.xml b/packages/files/xml/examples/test-cfdi40/ingreso-basico.xml new file mode 100644 index 00000000..da2b772e --- /dev/null +++ b/packages/files/xml/examples/test-cfdi40/ingreso-basico.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi40/ingreso-dolares.xml b/packages/files/xml/examples/test-cfdi40/ingreso-dolares.xml new file mode 100644 index 00000000..4241733f --- /dev/null +++ b/packages/files/xml/examples/test-cfdi40/ingreso-dolares.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi40/ingreso-exento.xml b/packages/files/xml/examples/test-cfdi40/ingreso-exento.xml new file mode 100644 index 00000000..0b1a9e62 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi40/ingreso-exento.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi40/ingreso-ieps.xml b/packages/files/xml/examples/test-cfdi40/ingreso-ieps.xml new file mode 100644 index 00000000..26a47c3c --- /dev/null +++ b/packages/files/xml/examples/test-cfdi40/ingreso-ieps.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi40/ingreso-iva-retencion.xml b/packages/files/xml/examples/test-cfdi40/ingreso-iva-retencion.xml new file mode 100644 index 00000000..a08efd10 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi40/ingreso-iva-retencion.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi40/ingreso-multi-concepto.xml b/packages/files/xml/examples/test-cfdi40/ingreso-multi-concepto.xml new file mode 100644 index 00000000..d1efc9d1 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi40/ingreso-multi-concepto.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi40/ingreso-parcialidades.xml b/packages/files/xml/examples/test-cfdi40/ingreso-parcialidades.xml new file mode 100644 index 00000000..55e6c78c --- /dev/null +++ b/packages/files/xml/examples/test-cfdi40/ingreso-parcialidades.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi40/ingreso-sin-impuestos.xml b/packages/files/xml/examples/test-cfdi40/ingreso-sin-impuestos.xml new file mode 100644 index 00000000..b720bed4 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi40/ingreso-sin-impuestos.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/files/xml/examples/test-cfdi40/traslado.xml b/packages/files/xml/examples/test-cfdi40/traslado.xml new file mode 100644 index 00000000..c1a6a292 --- /dev/null +++ b/packages/files/xml/examples/test-cfdi40/traslado.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/files/xml/un-concepto.xml b/packages/files/xml/un-concepto.xml new file mode 100644 index 00000000..6eea5a12 --- /dev/null +++ b/packages/files/xml/un-concepto.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/packages/files/xml/un-impuesto.xml b/packages/files/xml/un-impuesto.xml new file mode 100644 index 00000000..1a89d306 --- /dev/null +++ b/packages/files/xml/un-impuesto.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/packages/renapo/curp/.eslintrc.js b/packages/renapo/curp/.eslintrc.js new file mode 100644 index 00000000..1c7b1395 --- /dev/null +++ b/packages/renapo/curp/.eslintrc.js @@ -0,0 +1,30 @@ +// This is a workaround for https://github.com/eslint/eslint/issues/3458 +require("@rushstack/eslint-config/patch/modern-module-resolution"); + +module.exports = { + extends: [ + "./node_modules/@recreando/eslint-settings/react", + ], + parserOptions: { tsconfigRootDir: __dirname, }, + rules: { + "no-unused-expressions": "off", + "sort-imports": "off", + "no-unused-vars": "off", + "import/no-cycle": "off", + "@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "React" }], + "@typescript-eslint/no-unused-expressions": "off", + "@typescript-eslint/no-unsafe-assignment": "off", + "@typescript-eslint/no-unsafe-argument":"off", + "@typescript-eslint/await-thenable": "off", + "@typescript-eslint/no-misused-promises": "off", + "no-async-promise-executor":"off", + "noUnusedLocals": "off", + "no-unused-vars": "off", + "noUnusedParameters": "off", + "no-unused-variable":1, + "class-methods-use-this":"off", + "react/no-multi-comp": "off", + "guard-for-in": "off", + "no-restricted-syntax":"off" + }, +}; diff --git a/packages/renapo/curp/.gitignore b/packages/renapo/curp/.gitignore new file mode 100644 index 00000000..4c9d7c35 --- /dev/null +++ b/packages/renapo/curp/.gitignore @@ -0,0 +1,4 @@ +*.log +.DS_Store +node_modules +dist diff --git a/packages/renapo/curp/.npmignore b/packages/renapo/curp/.npmignore new file mode 100644 index 00000000..956a7450 --- /dev/null +++ b/packages/renapo/curp/.npmignore @@ -0,0 +1,8 @@ +src +tsconfig.json +tslint.json +.prettierrc +test +resources +jest.config.js +.eslintrc.js diff --git a/packages/cfdi/curp/CHANGELOG.json b/packages/renapo/curp/CHANGELOG.json similarity index 67% rename from packages/cfdi/curp/CHANGELOG.json rename to packages/renapo/curp/CHANGELOG.json index 4aa9dfcb..04e67d18 100644 --- a/packages/cfdi/curp/CHANGELOG.json +++ b/packages/renapo/curp/CHANGELOG.json @@ -1,9 +1,9 @@ { - "name": "@cfdi/curp", + "name": "@renapo/curp", "entries": [ { "version": "0.0.10", - "tag": "@cfdi/curp_v0.0.10", + "tag": "@renapo/curp_v0.0.10", "date": "Tue, 09 Aug 2022 17:08:57 GMT", "comments": {} } diff --git a/packages/cfdi/curp/CHANGELOG.md b/packages/renapo/curp/CHANGELOG.md similarity index 85% rename from packages/cfdi/curp/CHANGELOG.md rename to packages/renapo/curp/CHANGELOG.md index 40dfd7df..e34baa6d 100644 --- a/packages/cfdi/curp/CHANGELOG.md +++ b/packages/renapo/curp/CHANGELOG.md @@ -1,4 +1,4 @@ -# Change Log - @cfdi/curp +# Change Log - @renapo/curp This log was last generated on Tue, 09 Aug 2022 17:08:57 GMT and should not be manually modified. diff --git a/packages/renapo/curp/LICENSE b/packages/renapo/curp/LICENSE new file mode 100644 index 00000000..5d5ce6d3 --- /dev/null +++ b/packages/renapo/curp/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 MisaelMa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/packages/renapo/curp/README.md b/packages/renapo/curp/README.md new file mode 100644 index 00000000..5dbfb756 --- /dev/null +++ b/packages/renapo/curp/README.md @@ -0,0 +1,79 @@ +# @renapo/curp + +Validacion local y consulta en linea de CURP (Clave Unica de Registro de Poblacion). Permite validar el formato de una CURP y consultar datos en el servicio RENAPO del gobierno de Mexico. + +## Instalacion + +```bash +npm install @renapo/curp +``` + +## Uso + +### Validacion local + +```typescript +import { curp } from '@renapo/curp'; + +// Validacion basica (solo formato y regex) +const resultado = curp.validateLocal('GARC850101HDFRRL09'); +// { isValid: true, rfc: 'GARC850101HDFRRL09', error: [] } + +// Validacion completa (formato, fecha, estado, digito verificador) +const resultado2 = curp.validate('GARC850101HDFRRL09'); + +// Obtener estado de nacimiento +const estado = curp.getState('GARC850101HDFRRL09'); // 'DF' +``` + +### Consulta en RENAPO (gobierno) + +```typescript +import { gob } from '@renapo/curp'; + +// Buscar por CURP +const persona = await gob.findByCurp('GARC850101HDFRRL09'); + +// Buscar por datos personales +const persona2 = await gob.findByData({ + nombre: 'JUAN', + primerApellido: 'GARCIA', + segundoApellido: 'LOPEZ', + diaNacimiento: '01', + mesNacimiento: '01', + selectedYear: '1985', + claveEntidad: 'DF', + sexo: 'H', +}); + +// Guardar PDF de la CURP +gob.savePDF({ + file: base64String, + fullPath: '/ruta/destino/curp.pdf', +}); +``` + +## API + +### Modulo `curp` + +| Funcion | Descripcion | +|---------|-------------| +| `validateLocal(input)` | Validacion basica de formato con regex | +| `validate(input)` | Validacion completa (formato, fecha, estado, digito verificador) | +| `getState(curp)` | Retorna la clave del estado de nacimiento | + +### Modulo `gob` + +| Funcion | Descripcion | +|---------|-------------| +| `findByCurp(curp)` | Consulta datos de una persona por su CURP en RENAPO | +| `findByData(data)` | Busca CURP por datos personales (nombre, apellidos, fecha, etc.) | +| `getBase64Pdf(params)` | Obtiene el PDF de la CURP en base64 | +| `savePDF({ file, fullPath })` | Guarda un PDF de CURP en base64 a un archivo | + +**Nota:** Las consultas al servicio de gobierno (`gob`) requieren resolver un captcha mediante el servicio 2captcha. + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/renapo/curp/jest.config.js b/packages/renapo/curp/jest.config.js new file mode 100644 index 00000000..e9a29ce4 --- /dev/null +++ b/packages/renapo/curp/jest.config.js @@ -0,0 +1,5 @@ +const baseConfig = require('@recreando/jest/jestConfig'); + +module.exports = { + ...baseConfig, +}; diff --git a/packages/cfdi/curp/package.index.json b/packages/renapo/curp/package.index.json similarity index 100% rename from packages/cfdi/curp/package.index.json rename to packages/renapo/curp/package.index.json diff --git a/packages/renapo/curp/package.json b/packages/renapo/curp/package.json new file mode 100644 index 00000000..451f3b61 --- /dev/null +++ b/packages/renapo/curp/package.json @@ -0,0 +1,39 @@ +{ + "name": "@renapo/curp", + "version": "0.0.10-beta.2", + "license": "MIT", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "source": "./src/index.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "dependencies": { + "2captcha": "^3.0.5", + "axios": "^0.27.2" + }, + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/cfdi/curp/src/common/constants.ts b/packages/renapo/curp/src/common/constants.ts similarity index 100% rename from packages/cfdi/curp/src/common/constants.ts rename to packages/renapo/curp/src/common/constants.ts diff --git a/packages/cfdi/curp/src/curp.ts b/packages/renapo/curp/src/curp.ts similarity index 100% rename from packages/cfdi/curp/src/curp.ts rename to packages/renapo/curp/src/curp.ts diff --git a/packages/cfdi/curp/src/index.ts b/packages/renapo/curp/src/index.ts similarity index 100% rename from packages/cfdi/curp/src/index.ts rename to packages/renapo/curp/src/index.ts diff --git a/packages/cfdi/curp/src/service/api.ts b/packages/renapo/curp/src/service/api.ts similarity index 100% rename from packages/cfdi/curp/src/service/api.ts rename to packages/renapo/curp/src/service/api.ts diff --git a/packages/cfdi/curp/src/service/gob.service.ts b/packages/renapo/curp/src/service/gob.service.ts similarity index 100% rename from packages/cfdi/curp/src/service/gob.service.ts rename to packages/renapo/curp/src/service/gob.service.ts diff --git a/packages/cfdi/curp/src/types/gob.types.ts b/packages/renapo/curp/src/types/gob.types.ts similarity index 100% rename from packages/cfdi/curp/src/types/gob.types.ts rename to packages/renapo/curp/src/types/gob.types.ts diff --git a/packages/cfdi/curp/src/types/index.ts b/packages/renapo/curp/src/types/index.ts similarity index 100% rename from packages/cfdi/curp/src/types/index.ts rename to packages/renapo/curp/src/types/index.ts diff --git a/packages/cfdi/curp/src/types/mexican.types.ts b/packages/renapo/curp/src/types/mexican.types.ts similarity index 100% rename from packages/cfdi/curp/src/types/mexican.types.ts rename to packages/renapo/curp/src/types/mexican.types.ts diff --git a/packages/cfdi/curp/src/utils/getCheckDigit.ts b/packages/renapo/curp/src/utils/getCheckDigit.ts similarity index 100% rename from packages/cfdi/curp/src/utils/getCheckDigit.ts rename to packages/renapo/curp/src/utils/getCheckDigit.ts diff --git a/packages/cfdi/curp/src/utils/parse.reponse.ts b/packages/renapo/curp/src/utils/parse.reponse.ts similarity index 100% rename from packages/cfdi/curp/src/utils/parse.reponse.ts rename to packages/renapo/curp/src/utils/parse.reponse.ts diff --git a/packages/cfdi/curp/src/utils/recaptach.ts b/packages/renapo/curp/src/utils/recaptach.ts similarity index 100% rename from packages/cfdi/curp/src/utils/recaptach.ts rename to packages/renapo/curp/src/utils/recaptach.ts diff --git a/packages/cfdi/curp/test/blah.test.ts b/packages/renapo/curp/test/blah.test.ts similarity index 100% rename from packages/cfdi/curp/test/blah.test.ts rename to packages/renapo/curp/test/blah.test.ts diff --git a/packages/cfdi/curp/tsconfig.json b/packages/renapo/curp/tsconfig.json similarity index 100% rename from packages/cfdi/curp/tsconfig.json rename to packages/renapo/curp/tsconfig.json diff --git a/packages/renapo/curp/vite.config.mts b/packages/renapo/curp/vite.config.mts new file mode 100644 index 00000000..54ebb4b4 --- /dev/null +++ b/packages/renapo/curp/vite.config.mts @@ -0,0 +1,10 @@ +import { defineConfig, mergeConfig } from 'vite'; +import baseConfig from '@recreando/vite/lib'; + +export default mergeConfig(baseConfig, defineConfig({ + build: { + rollupOptions: { + external: ['2captcha', 'axios'], + }, + }, +})); diff --git a/packages/renapo/curp/vitest.config.mts b/packages/renapo/curp/vitest.config.mts new file mode 100644 index 00000000..f2a4ec65 --- /dev/null +++ b/packages/renapo/curp/vitest.config.mts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; // only if you are using custom tsconfig paths + +export default defineConfig({ + test: {}, + plugins: [tsconfigPaths()], // only if you are using custom tsconfig paths +}); diff --git a/packages/sat/auth/CHANGELOG.json b/packages/sat/auth/CHANGELOG.json new file mode 100644 index 00000000..5e8d9876 --- /dev/null +++ b/packages/sat/auth/CHANGELOG.json @@ -0,0 +1,11 @@ +{ + "name": "@sat/auth", + "entries": [ + { + "version": "1.0.1", + "tag": "@sat/auth_v1.0.1", + "date": "Sun, 15 Mar 2026 22:26:50 GMT", + "comments": {} + } + ] +} diff --git a/packages/sat/auth/CHANGELOG.md b/packages/sat/auth/CHANGELOG.md new file mode 100644 index 00000000..17c86e2b --- /dev/null +++ b/packages/sat/auth/CHANGELOG.md @@ -0,0 +1,9 @@ +# Change Log - @sat/auth + +This log was last generated on Sun, 15 Mar 2026 22:26:50 GMT and should not be manually modified. + +## 1.0.1 + +Sun, 15 Mar 2026 22:26:50 GMT + +_Initial release_ diff --git a/packages/sat/auth/dist/index.cjs b/packages/sat/auth/dist/index.cjs new file mode 100644 index 00000000..83737434 --- /dev/null +++ b/packages/sat/auth/dist/index.cjs @@ -0,0 +1,3 @@ +"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("crypto");function g(t){let e=t.replace(/<\?xml[^?]*\?>\s*/g,"");return e=e.replace(/\r\n/g,` +`).replace(/\r/g,` +`),e=e.replace(/<([a-zA-Z][^\s/>]*)((?:\s+[^>]*)?)(\/?)>/g,(n,s,o,r)=>{if(!o||!o.trim())return`<${s}${r}>`;const i=I(o),u=Object.keys(i).sort().map(a=>`${a}="${i[a]}"`).join(" ");return`<${s} ${u}${r}>`}),e}function I(t){const e={},n=/([a-zA-Z_:][\w:.-]*)=["']([^"']*)["']/g;let s;for(;(s=n.exec(t))!==null;)e[s[1]]=s[2];return e}function d(t){return l.createHash("sha256").update(t,"utf8").digest("base64")}function $(t,e){const n=l.createSign("RSA-SHA256");return n.update(t,"utf8"),n.sign(e,"base64")}function m(t){const{certificateBase64:e,created:n,expires:s,digest:o,signature:r,tokenId:i}=t;return`${n}${s}${e}${o}${r}`}function h(t,e){return`${t}${e}`}function p(t){return`${t}`}const b="https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/Autenticacion/Autenticacion.svc",R="http://DescargaMasivaTerceros.gob.mx/IAutenticacion/Autentica";class k{constructor(e){this._credential=e}async authenticate(){const e=new Date,n=new Date(e.getTime()+300*1e3),s=this._toIsoString(e),o=this._toIsoString(n),r=`uuid-${l.randomUUID()}`,i=h(s,o),u=g(i),a=d(u),w=p(a),x=g(w),f=this._credential.sign(x),S=this._credential.certificate.toDer().toString("base64"),T=m({certificateBase64:S,created:s,expires:o,digest:a,signature:f,tokenId:r}),c=await fetch(b,{method:"POST",headers:{"Content-Type":"text/xml; charset=utf-8",SOAPAction:R},body:T});if(!c.ok){const y=await c.text().catch(()=>"");throw new Error(`SAT auth request failed: HTTP ${c.status} ${c.statusText}. Body: ${y}`)}const A=await c.text();return this._parseToken(A,e,n)}_parseToken(e,n,s){const o=e.match(/([^<]+)<\/AutenticaResult>/)??e.match(/<[^:]*:?AutenticaResult[^>]*>([^<]+)<\/[^:]*:?AutenticaResult>/);if(!o?.[1])throw new Error(`No se pudo extraer el token de la respuesta del SAT. Respuesta: ${e.slice(0,500)}`);const r=o[1].trim();if(!r)throw new Error("El token retornado por el SAT esta vacio.");return{value:r,created:n,expires:s}}_toIsoString(e){return e.toISOString()}}exports.SatAuth=k;exports.buildAuthToken=m;exports.buildSignedInfoFragment=p;exports.buildTimestampFragment=h;exports.canonicalize=g;exports.sha256Digest=d;exports.signRsaSha256=$; diff --git a/packages/sat/auth/dist/index.d.ts b/packages/sat/auth/dist/index.d.ts new file mode 100644 index 00000000..42ab8f0c --- /dev/null +++ b/packages/sat/auth/dist/index.d.ts @@ -0,0 +1,46 @@ +import { default as default_2 } from 'crypto'; + +export declare function buildAuthToken(params: BuildAuthTokenParams): string; + +export declare interface BuildAuthTokenParams { + certificateBase64: string; + created: string; + expires: string; + digest: string; + signature: string; + tokenId: string; +} + +export declare function buildSignedInfoFragment(digest: string): string; + +export declare function buildTimestampFragment(created: string, expires: string): string; + +export declare function canonicalize(xmlFragment: string): string; + +export declare interface CredentialLike { + certificate: { + toDer(): Buffer; + toPem(): string; + }; + sign(data: string): string; +} + +export declare class SatAuth { + private readonly _credential; + constructor(_credential: CredentialLike); + authenticate(): Promise; + private _parseToken; + private _toIsoString; +} + +export declare interface SatToken { + value: string; + created: Date; + expires: Date; +} + +export declare function sha256Digest(data: string): string; + +export declare function signRsaSha256(data: string, privateKey: default_2.KeyObject): string; + +export { } diff --git a/packages/sat/auth/dist/index.mjs b/packages/sat/auth/dist/index.mjs new file mode 100644 index 00000000..6dc68303 --- /dev/null +++ b/packages/sat/auth/dist/index.mjs @@ -0,0 +1,109 @@ +import l, { randomUUID as T } from "crypto"; +function g(t) { + let e = t.replace(/<\?xml[^?]*\?>\s*/g, ""); + return e = e.replace(/\r\n/g, ` +`).replace(/\r/g, ` +`), e = e.replace(/<([a-zA-Z][^\s/>]*)((?:\s+[^>]*)?)(\/?)>/g, (n, s, o, r) => { + if (!o || !o.trim()) + return `<${s}${r}>`; + const i = S(o), u = Object.keys(i).sort().map((a) => `${a}="${i[a]}"`).join(" "); + return `<${s} ${u}${r}>`; + }), e; +} +function S(t) { + const e = {}, n = /([a-zA-Z_:][\w:.-]*)=["']([^"']*)["']/g; + let s; + for (; (s = n.exec(t)) !== null; ) + e[s[1]] = s[2]; + return e; +} +function A(t) { + return l.createHash("sha256").update(t, "utf8").digest("base64"); +} +function b(t, e) { + const n = l.createSign("RSA-SHA256"); + return n.update(t, "utf8"), n.sign(e, "base64"); +} +function y(t) { + const { + certificateBase64: e, + created: n, + expires: s, + digest: o, + signature: r, + tokenId: i + } = t; + return `${n}${s}${e}${o}${r}`; +} +function I(t, e) { + return `${t}${e}`; +} +function $(t) { + return `${t}`; +} +const R = "https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/Autenticacion/Autenticacion.svc", _ = "http://DescargaMasivaTerceros.gob.mx/IAutenticacion/Autentica"; +class v { + constructor(e) { + this._credential = e; + } + /** + * Realiza la autenticacion contra el SAT y retorna el token de sesion. + * + * @throws {Error} Si la respuesta del SAT no es exitosa o no contiene token. + */ + async authenticate() { + const e = /* @__PURE__ */ new Date(), n = new Date(e.getTime() + 300 * 1e3), s = this._toIsoString(e), o = this._toIsoString(n), r = `uuid-${T()}`, i = I(s, o), u = g(i), a = A(u), d = $(a), m = g(d), p = this._credential.sign(m), w = this._credential.certificate.toDer().toString("base64"), h = y({ + certificateBase64: w, + created: s, + expires: o, + digest: a, + signature: p, + tokenId: r + }), c = await fetch(R, { + method: "POST", + headers: { + "Content-Type": "text/xml; charset=utf-8", + SOAPAction: _ + }, + body: h + }); + if (!c.ok) { + const f = await c.text().catch(() => ""); + throw new Error( + `SAT auth request failed: HTTP ${c.status} ${c.statusText}. Body: ${f}` + ); + } + const x = await c.text(); + return this._parseToken(x, e, n); + } + /** + * Parsea la respuesta SOAP del SAT y extrae el token de sesion. + */ + _parseToken(e, n, s) { + const o = e.match(/([^<]+)<\/AutenticaResult>/) ?? e.match(/<[^:]*:?AutenticaResult[^>]*>([^<]+)<\/[^:]*:?AutenticaResult>/); + if (!o?.[1]) + throw new Error( + `No se pudo extraer el token de la respuesta del SAT. Respuesta: ${e.slice(0, 500)}` + ); + const r = o[1].trim(); + if (!r) + throw new Error("El token retornado por el SAT esta vacio."); + return { value: r, created: n, expires: s }; + } + /** + * Convierte una fecha a formato ISO 8601 con milisegundos y sufijo Z, + * tal como lo requiere el SAT. + */ + _toIsoString(e) { + return e.toISOString(); + } +} +export { + v as SatAuth, + y as buildAuthToken, + $ as buildSignedInfoFragment, + I as buildTimestampFragment, + g as canonicalize, + A as sha256Digest, + b as signRsaSha256 +}; diff --git a/packages/sat/auth/package.json b/packages/sat/auth/package.json new file mode 100644 index 00000000..8804525a --- /dev/null +++ b/packages/sat/auth/package.json @@ -0,0 +1,37 @@ +{ + "name": "@sat/auth", + "version": "1.0.1", + "license": "MIT", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "source": "./src/index.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build --config node_modules/@recreando/vite/vite.config.lib.mts", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "dependencies": {}, + "devDependencies": { + "@cfdi/csd": "workspace:*", + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/sat/auth/src/SatAuth.ts b/packages/sat/auth/src/SatAuth.ts new file mode 100644 index 00000000..36d4ee81 --- /dev/null +++ b/packages/sat/auth/src/SatAuth.ts @@ -0,0 +1,130 @@ +import { randomUUID } from 'crypto'; +import type { SatToken, CredentialLike } from './types'; +import { + canonicalize, + sha256Digest, +} from './xml-signer'; +import { + buildAuthToken, + buildTimestampFragment, + buildSignedInfoFragment, +} from './token-builder'; + +const AUTH_URL = + 'https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/Autenticacion/Autenticacion.svc'; + +const SOAP_ACTION = + 'http://DescargaMasivaTerceros.gob.mx/IAutenticacion/Autentica'; + +/** + * Realiza autenticacion en los webservices del SAT usando FIEL (eFirma). + * + * El proceso genera un token SOAP firmado con la FIEL del contribuyente, + * lo envia al servicio de autenticacion del SAT y retorna el token de sesion + * necesario para las solicitudes de descarga masiva. + * + * @example + * ```typescript + * const fiel = await Credential.create('fiel.cer', 'fiel.key', 'password'); + * const auth = new SatAuth(fiel); + * const token = await auth.authenticate(); + * console.log(token.value); // token SOAP + * ``` + */ +export class SatAuth { + constructor(private readonly _credential: CredentialLike) {} + + /** + * Realiza la autenticacion contra el SAT y retorna el token de sesion. + * + * @throws {Error} Si la respuesta del SAT no es exitosa o no contiene token. + */ + async authenticate(): Promise { + const now = new Date(); + const expires = new Date(now.getTime() + 5 * 60 * 1000); + + const created = this._toIsoString(now); + const expiresStr = this._toIsoString(expires); + const tokenId = `uuid-${randomUUID()}`; + + // Paso 1: Calcular digest del Timestamp canonicalizado + const timestampFragment = buildTimestampFragment(created, expiresStr); + const canonicalTimestamp = canonicalize(timestampFragment); + const digest = sha256Digest(canonicalTimestamp); + + // Paso 2: Construir y firmar el SignedInfo canonicalizado + const signedInfoFragment = buildSignedInfoFragment(digest); + const canonicalSignedInfo = canonicalize(signedInfoFragment); + const signature = this._credential.sign(canonicalSignedInfo); + + // Paso 3: Obtener el certificado en base64 + const certDer = this._credential.certificate.toDer(); + const certificateBase64 = certDer.toString('base64'); + + // Paso 4: Construir el envelope SOAP completo + const envelope = buildAuthToken({ + certificateBase64, + created, + expires: expiresStr, + digest, + signature, + tokenId, + }); + + // Paso 5: Enviar la peticion al SAT + const response = await fetch(AUTH_URL, { + method: 'POST', + headers: { + 'Content-Type': 'text/xml; charset=utf-8', + SOAPAction: SOAP_ACTION, + }, + body: envelope, + }); + + if (!response.ok) { + const body = await response.text().catch(() => ''); + throw new Error( + `SAT auth request failed: HTTP ${response.status} ${response.statusText}. Body: ${body}` + ); + } + + const responseText = await response.text(); + return this._parseToken(responseText, now, expires); + } + + /** + * Parsea la respuesta SOAP del SAT y extrae el token de sesion. + */ + private _parseToken( + soapResponse: string, + created: Date, + expires: Date + ): SatToken { + // El token viene en el elemento AutenticaResult + const tokenMatch = + soapResponse.match(/([^<]+)<\/AutenticaResult>/) ?? + soapResponse.match(/<[^:]*:?AutenticaResult[^>]*>([^<]+)<\/[^:]*:?AutenticaResult>/); + + if (!tokenMatch?.[1]) { + throw new Error( + `No se pudo extraer el token de la respuesta del SAT. Respuesta: ${soapResponse.slice(0, 500)}` + ); + } + + const value = tokenMatch[1].trim(); + + if (!value) { + throw new Error('El token retornado por el SAT esta vacio.'); + } + + return { value, created, expires }; + } + + /** + * Convierte una fecha a formato ISO 8601 con milisegundos y sufijo Z, + * tal como lo requiere el SAT. + */ + private _toIsoString(date: Date): string { + return date.toISOString(); + } +} diff --git a/packages/sat/auth/src/index.ts b/packages/sat/auth/src/index.ts new file mode 100644 index 00000000..d83e5e0a --- /dev/null +++ b/packages/sat/auth/src/index.ts @@ -0,0 +1,4 @@ +export * from './types'; +export * from './xml-signer'; +export * from './token-builder'; +export * from './SatAuth'; diff --git a/packages/sat/auth/src/token-builder.ts b/packages/sat/auth/src/token-builder.ts new file mode 100644 index 00000000..75fb1d5b --- /dev/null +++ b/packages/sat/auth/src/token-builder.ts @@ -0,0 +1,98 @@ +/** + * Parametros necesarios para construir el envelope SOAP de autenticacion. + */ +export interface BuildAuthTokenParams { + /** Certificado en base64 (DER) */ + certificateBase64: string; + /** Fecha/hora de creacion en ISO 8601 */ + created: string; + /** Fecha/hora de expiracion en ISO 8601 */ + expires: string; + /** Digest SHA-256 del Timestamp canonicalizado, en base64 */ + digest: string; + /** Firma RSA-SHA256 del SignedInfo canonicalizado, en base64 */ + signature: string; + /** UUID que identifica el BinarySecurityToken */ + tokenId: string; +} + +/** + * Construye el envelope SOAP completo para la peticion de autenticacion + * al servicio de descarga masiva del SAT. + */ +export function buildAuthToken(params: BuildAuthTokenParams): string { + const { + certificateBase64, + created, + expires, + digest, + signature, + tokenId, + } = params; + + return `` + + `` + + `` + + `` + + `${created}` + + `${expires}` + + `` + + `${certificateBase64}` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + `${digest}` + + `` + + `` + + `${signature}` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + ``; +} + +/** + * Construye el fragmento XML del elemento Timestamp usado para calcular + * el digest de la firma. + */ +export function buildTimestampFragment(created: string, expires: string): string { + return ( + `` + + `${created}` + + `${expires}` + + `` + ); +} + +/** + * Construye el fragmento XML del SignedInfo usado para calcular la firma. + */ +export function buildSignedInfoFragment(digest: string): string { + return ( + `` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + `${digest}` + + `` + + `` + ); +} diff --git a/packages/sat/auth/src/types.ts b/packages/sat/auth/src/types.ts new file mode 100644 index 00000000..03ed0fd1 --- /dev/null +++ b/packages/sat/auth/src/types.ts @@ -0,0 +1,29 @@ +/** + * Token de sesion devuelto por el servicio de autenticacion del SAT. + */ +export interface SatToken { + /** Valor del token SOAP (Bearer) */ + value: string; + /** Fecha y hora de creacion */ + created: Date; + /** Fecha y hora de expiracion */ + expires: Date; +} + +/** + * Interfaz de duck typing para usar un Credential de @cfdi/csd sin + * importarlo como dependencia de produccion. + */ +export interface CredentialLike { + certificate: { + /** Retorna el certificado en formato DER (Buffer) */ + toDer(): Buffer; + /** Retorna el certificado en formato PEM */ + toPem(): string; + }; + /** + * Firma la cadena `data` con la llave privada usando RSA-SHA256. + * Retorna la firma en base64. + */ + sign(data: string): string; +} diff --git a/packages/sat/auth/src/xml-signer.ts b/packages/sat/auth/src/xml-signer.ts new file mode 100644 index 00000000..5d9af837 --- /dev/null +++ b/packages/sat/auth/src/xml-signer.ts @@ -0,0 +1,71 @@ +import crypto from 'crypto'; + +/** + * Canonicalizacion XML Exclusiva (C14N exc) simplificada para el Timestamp + * del token SOAP de autenticacion del SAT. + * + * Esta implementacion cubre unicamente lo necesario para el elemento Timestamp: + * - Elimina la declaracion XML + * - Ordena los atributos alfabeticamente por nombre + * - Normaliza saltos de linea a LF + * - Elimina espacios innecesarios entre tags de apertura y cierre + * + * No es una implementacion completa de C14N, pero es suficiente para el + * caso de uso de autenticacion con el SAT. + */ +export function canonicalize(xmlFragment: string): string { + // Eliminar declaracion XML si existe + let result = xmlFragment.replace(/<\?xml[^?]*\?>\s*/g, ''); + + // Normalizar saltos de linea + result = result.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); + + // Ordenar atributos dentro de cada tag de apertura + result = result.replace(/<([a-zA-Z][^\s/>]*)((?:\s+[^>]*)?)(\/?)>/g, (_match, tagName: string, attrsStr: string, selfClose: string) => { + if (!attrsStr || !attrsStr.trim()) { + return `<${tagName}${selfClose}>`; + } + const attrs = _parseAttributes(attrsStr); + const sortedAttrs = Object.keys(attrs) + .sort() + .map(name => `${name}="${attrs[name]}"`) + .join(' '); + return `<${tagName} ${sortedAttrs}${selfClose}>`; + }); + + return result; +} + +/** + * Parsea un string de atributos XML y retorna un objeto nombre -> valor. + */ +function _parseAttributes(attrsStr: string): Record { + const attrs: Record = {}; + // Patron: nombre="valor" o nombre='valor' + const attrRegex = /([a-zA-Z_:][\w:.-]*)=["']([^"']*)["']/g; + let match: RegExpExecArray | null; + while ((match = attrRegex.exec(attrsStr)) !== null) { + attrs[match[1]] = match[2]; + } + return attrs; +} + +/** + * Calcula el digest SHA-256 del string dado y lo retorna en base64. + */ +export function sha256Digest(data: string): string { + return crypto.createHash('sha256').update(data, 'utf8').digest('base64'); +} + +/** + * Firma el string `data` con la llave privada RSA usando SHA-256. + * Retorna la firma en base64. + */ +export function signRsaSha256( + data: string, + privateKey: crypto.KeyObject +): string { + const sign = crypto.createSign('RSA-SHA256'); + sign.update(data, 'utf8'); + return sign.sign(privateKey, 'base64'); +} diff --git a/packages/sat/auth/test/auth.test.ts b/packages/sat/auth/test/auth.test.ts new file mode 100644 index 00000000..44913b02 --- /dev/null +++ b/packages/sat/auth/test/auth.test.ts @@ -0,0 +1,215 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import crypto from 'crypto'; +import { SatAuth } from '../src/SatAuth'; +import type { CredentialLike } from '../src/types'; + +/** + * Crea un mock de CredentialLike con un par de llaves RSA de prueba. + */ +function createMockCredential(): CredentialLike { + const { privateKey } = crypto.generateKeyPairSync('rsa', { + modulusLength: 2048, + }); + + // Certificado DER simulado (contenido arbitrario para tests) + const fakeDer = Buffer.from('fakecertificate', 'utf8'); + + return { + certificate: { + toDer: () => fakeDer, + toPem: () => '-----BEGIN CERTIFICATE-----\nFAKE\n-----END CERTIFICATE-----', + }, + sign: (data: string) => { + const signer = crypto.createSign('RSA-SHA256'); + signer.update(data, 'utf8'); + return signer.sign(privateKey, 'base64'); + }, + }; +} + +const SAT_TOKEN_VALUE = 'TOKENVALUEFROMSAT123456789'; + +const MOCK_SOAP_RESPONSE = ` + + + + ${SAT_TOKEN_VALUE} + + +`; + +describe('SatAuth', () => { + let fetchSpy: ReturnType; + + beforeEach(() => { + fetchSpy = vi.spyOn(global, 'fetch').mockResolvedValue( + new Response(MOCK_SOAP_RESPONSE, { + status: 200, + headers: { 'Content-Type': 'text/xml; charset=utf-8' }, + }) + ); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('llama a la URL de autenticacion del SAT', async () => { + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + await auth.authenticate(); + + expect(fetchSpy).toHaveBeenCalledOnce(); + const [url] = fetchSpy.mock.calls[0] as [string, RequestInit]; + expect(url).toBe( + 'https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/Autenticacion/Autenticacion.svc' + ); + }); + + it('usa metodo POST', async () => { + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + await auth.authenticate(); + + const [, options] = fetchSpy.mock.calls[0] as [string, RequestInit]; + expect(options.method).toBe('POST'); + }); + + it('envia el SOAPAction correcto', async () => { + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + await auth.authenticate(); + + const [, options] = fetchSpy.mock.calls[0] as [string, RequestInit]; + const headers = options.headers as Record; + expect(headers['SOAPAction']).toBe( + 'http://DescargaMasivaTerceros.gob.mx/IAutenticacion/Autentica' + ); + }); + + it('envia Content-Type text/xml', async () => { + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + await auth.authenticate(); + + const [, options] = fetchSpy.mock.calls[0] as [string, RequestInit]; + const headers = options.headers as Record; + expect(headers['Content-Type']).toContain('text/xml'); + }); + + it('retorna el token con el valor correcto', async () => { + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + const token = await auth.authenticate(); + + expect(token.value).toBe(SAT_TOKEN_VALUE); + }); + + it('retorna fechas created y expires validas', async () => { + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + const before = new Date(); + const token = await auth.authenticate(); + const after = new Date(); + + expect(token.created.getTime()).toBeGreaterThanOrEqual(before.getTime() - 1000); + expect(token.created.getTime()).toBeLessThanOrEqual(after.getTime() + 1000); + + // expires debe ser ~5 minutos despues de created + const diffMs = token.expires.getTime() - token.created.getTime(); + expect(diffMs).toBe(5 * 60 * 1000); + }); + + it('el body SOAP enviado contiene el elemento Autentica', async () => { + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + await auth.authenticate(); + + const [, options] = fetchSpy.mock.calls[0] as [string, RequestInit]; + const body = options.body as string; + expect(body).toContain('Autentica'); + expect(body).toContain('http://DescargaMasivaTerceros.gob.mx'); + }); + + it('el body SOAP contiene el certificado en base64', async () => { + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + await auth.authenticate(); + + const [, options] = fetchSpy.mock.calls[0] as [string, RequestInit]; + const body = options.body as string; + // El certificado fake "fakecertificate" en base64 + const expectedBase64 = Buffer.from('fakecertificate', 'utf8').toString('base64'); + expect(body).toContain(expectedBase64); + }); + + it('el body SOAP contiene BinarySecurityToken', async () => { + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + await auth.authenticate(); + + const [, options] = fetchSpy.mock.calls[0] as [string, RequestInit]; + const body = options.body as string; + expect(body).toContain('BinarySecurityToken'); + }); + + it('lanza error si el SAT responde con status de error', async () => { + fetchSpy.mockResolvedValueOnce( + new Response('Internal Server Error', { status: 500 }) + ); + + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + await expect(auth.authenticate()).rejects.toThrow('SAT auth request failed'); + }); + + it('lanza error si la respuesta no contiene AutenticaResult', async () => { + fetchSpy.mockResolvedValueOnce( + new Response('', { + status: 200, + headers: { 'Content-Type': 'text/xml' }, + }) + ); + + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + await expect(auth.authenticate()).rejects.toThrow( + 'No se pudo extraer el token' + ); + }); + + it('maneja namespace en AutenticaResult (prefijo)', async () => { + const responseWithPrefix = ` + + + + TOKEN_CON_PREFIJO + + +`; + + fetchSpy.mockResolvedValueOnce( + new Response(responseWithPrefix, { + status: 200, + headers: { 'Content-Type': 'text/xml' }, + }) + ); + + const credential = createMockCredential(); + const auth = new SatAuth(credential); + + const token = await auth.authenticate(); + expect(token.value).toBe('TOKEN_CON_PREFIJO'); + }); +}); diff --git a/packages/sat/auth/test/token-builder.test.ts b/packages/sat/auth/test/token-builder.test.ts new file mode 100644 index 00000000..8ad6af87 --- /dev/null +++ b/packages/sat/auth/test/token-builder.test.ts @@ -0,0 +1,151 @@ +import { describe, it, expect } from 'vitest'; +import { + buildAuthToken, + buildTimestampFragment, + buildSignedInfoFragment, +} from '../src/token-builder'; + +const SAMPLE_PARAMS = { + certificateBase64: 'CERTBASE64==', + created: '2024-01-01T00:00:00.000Z', + expires: '2024-01-01T00:05:00.000Z', + digest: 'DIGESTBASE64==', + signature: 'SIGNATUREBASE64==', + tokenId: 'uuid-1234-5678', +}; + +describe('buildAuthToken', () => { + it('contiene el namespace SOAP correcto', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain('xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"'); + }); + + it('contiene el namespace WSS utility', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain( + 'xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"' + ); + }); + + it('contiene el namespace WSS secext', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain( + 'xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"' + ); + }); + + it('incluye las fechas de Created y Expires', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain('2024-01-01T00:00:00.000Z'); + expect(xml).toContain('2024-01-01T00:05:00.000Z'); + }); + + it('incluye el BinarySecurityToken con el certificado', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain('CERTBASE64=='); + expect(xml).toContain('o:BinarySecurityToken'); + }); + + it('incluye el tokenId en el BinarySecurityToken', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain('u:Id="uuid-1234-5678"'); + }); + + it('incluye el DigestValue', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain('DIGESTBASE64=='); + }); + + it('incluye el SignatureValue', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain('SIGNATUREBASE64=='); + }); + + it('incluye el algoritmo de canonicalizacion C14N', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain( + 'Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"' + ); + }); + + it('incluye el algoritmo de firma RSA-SHA256', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain( + 'Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"' + ); + }); + + it('incluye el algoritmo de digest SHA-256', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain( + 'Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"' + ); + }); + + it('incluye la referencia al Timestamp con URI #_0', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain('URI="#_0"'); + }); + + it('incluye el elemento Autentica en el Body', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain( + '' + ); + }); + + it('incluye SecurityTokenReference apuntando al tokenId', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toContain('URI="#uuid-1234-5678"'); + }); + + it('produce XML bien formado (apertura y cierre de Envelope)', () => { + const xml = buildAuthToken(SAMPLE_PARAMS); + expect(xml).toMatch(/^$/); + }); +}); + +describe('buildTimestampFragment', () => { + it('incluye el elemento Timestamp con Id _0', () => { + const result = buildTimestampFragment( + '2024-01-01T00:00:00.000Z', + '2024-01-01T00:05:00.000Z' + ); + expect(result).toContain('u:Id="_0"'); + }); + + it('incluye el namespace WSS utility en el Timestamp', () => { + const result = buildTimestampFragment( + '2024-01-01T00:00:00.000Z', + '2024-01-01T00:05:00.000Z' + ); + expect(result).toContain('xmlns:u='); + }); + + it('incluye Created y Expires con los valores correctos', () => { + const result = buildTimestampFragment( + '2024-06-15T12:00:00.000Z', + '2024-06-15T12:05:00.000Z' + ); + expect(result).toContain('2024-06-15T12:00:00.000Z'); + expect(result).toContain('2024-06-15T12:05:00.000Z'); + }); +}); + +describe('buildSignedInfoFragment', () => { + it('incluye el DigestValue proporcionado', () => { + const result = buildSignedInfoFragment('miDigest=='); + expect(result).toContain('miDigest=='); + }); + + it('incluye el namespace xmldsig', () => { + const result = buildSignedInfoFragment('digest'); + expect(result).toContain('xmlns="http://www.w3.org/2000/09/xmldsig#"'); + }); + + it('incluye la referencia a _0', () => { + const result = buildSignedInfoFragment('digest'); + expect(result).toContain('URI="#_0"'); + }); +}); diff --git a/packages/sat/auth/test/xml-signer.test.ts b/packages/sat/auth/test/xml-signer.test.ts new file mode 100644 index 00000000..aede1ccd --- /dev/null +++ b/packages/sat/auth/test/xml-signer.test.ts @@ -0,0 +1,123 @@ +import { describe, it, expect } from 'vitest'; +import crypto from 'crypto'; +import { canonicalize, sha256Digest, signRsaSha256 } from '../src/xml-signer'; + +describe('canonicalize', () => { + it('elimina la declaracion XML', () => { + const input = ''; + const result = canonicalize(input); + expect(result).not.toContain(' { + const input = ''; + const result = canonicalize(input); + const aIdx = result.indexOf('a='); + const mIdx = result.indexOf('m='); + const zIdx = result.indexOf('z='); + expect(aIdx).toBeLessThan(mIdx); + expect(mIdx).toBeLessThan(zIdx); + }); + + it('conserva el contenido de texto', () => { + const input = + '' + + '2024-01-01T00:00:00.000Z' + + '2024-01-01T00:05:00.000Z' + + ''; + const result = canonicalize(input); + expect(result).toContain('2024-01-01T00:00:00.000Z'); + expect(result).toContain('2024-01-01T00:05:00.000Z'); + }); + + it('normaliza saltos de linea CRLF a LF', () => { + const input = '\r\n\r\n'; + const result = canonicalize(input); + expect(result).not.toContain('\r\n'); + expect(result).toContain('\n'); + }); + + it('maneja XML sin atributos', () => { + const input = 'texto'; + const result = canonicalize(input); + expect(result).toBe('texto'); + }); + + it('ordena atributos del Timestamp alfabeticamente (u:Id antes que xmlns:u)', () => { + const input = + '' + + '2024-01-01T00:00:00.000Z' + + ''; + const result = canonicalize(input); + // Orden alfabetico: 'u' < 'x', por lo que u:Id aparece antes que xmlns:u + const idIdx = result.indexOf('u:Id='); + const xmlnsIdx = result.indexOf('xmlns:u='); + expect(idIdx).toBeLessThan(xmlnsIdx); + }); +}); + +describe('sha256Digest', () => { + it('retorna base64 valido', () => { + const result = sha256Digest('hello world'); + // Base64 valido: solo caracteres base64 + expect(result).toMatch(/^[A-Za-z0-9+/]+=*$/); + }); + + it('retorna el hash correcto para string conocido', () => { + // SHA-256 de "hello world" en base64 + const expected = 'uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek='; + const result = sha256Digest('hello world'); + expect(result).toBe(expected); + }); + + it('retorna resultados distintos para strings distintos', () => { + const a = sha256Digest('abc'); + const b = sha256Digest('xyz'); + expect(a).not.toBe(b); + }); + + it('es determinista', () => { + const a = sha256Digest('test-data'); + const b = sha256Digest('test-data'); + expect(a).toBe(b); + }); +}); + +describe('signRsaSha256', () => { + it('produce una firma verificable con la llave publica correspondiente', () => { + // Generar un par de llaves RSA para la prueba + const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', { + modulusLength: 2048, + }); + + const data = 'datos de prueba para firma'; + const signature = signRsaSha256(data, privateKey); + + // Verificar que la firma sea base64 valido + expect(signature).toMatch(/^[A-Za-z0-9+/]+=*$/); + + // Verificar la firma con la llave publica + const verifier = crypto.createVerify('RSA-SHA256'); + verifier.update(data, 'utf8'); + const isValid = verifier.verify(publicKey, signature, 'base64'); + expect(isValid).toBe(true); + }); + + it('retorna base64 no vacio', () => { + const { privateKey } = crypto.generateKeyPairSync('rsa', { + modulusLength: 2048, + }); + const result = signRsaSha256('test', privateKey); + expect(result.length).toBeGreaterThan(0); + }); + + it('firmas distintas para datos distintos', () => { + const { privateKey } = crypto.generateKeyPairSync('rsa', { + modulusLength: 2048, + }); + const a = signRsaSha256('datos A', privateKey); + const b = signRsaSha256('datos B', privateKey); + expect(a).not.toBe(b); + }); +}); diff --git a/packages/sat/auth/tsconfig.json b/packages/sat/auth/tsconfig.json new file mode 100644 index 00000000..0aff00ce --- /dev/null +++ b/packages/sat/auth/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "types": [ + "node" + ], + "outDir": "./dist", + "declaration": true, + "sourceMap": true, + "noUnusedLocals": false, + "resolveJsonModule": true, + "noUnusedParameters": false + } +} diff --git a/packages/sat/auth/vitest.config.mts b/packages/sat/auth/vitest.config.mts new file mode 100644 index 00000000..d262afe6 --- /dev/null +++ b/packages/sat/auth/vitest.config.mts @@ -0,0 +1,22 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; +import { resolve } from 'path'; + +export default defineConfig({ + test: { + reporters: ['default'], + coverage: { + include: ['src/**/*.ts'], + exclude: ['**/node_modules/**', '**/test/**'], + }, + alias: { + '@cfdi/csd': resolve(__dirname, '../csd/src'), + }, + }, + plugins: [tsconfigPaths()], + resolve: { + alias: { + '@cfdi/csd': resolve(__dirname, '../csd/src'), + }, + }, +}); diff --git a/packages/sat/captcha/package.json b/packages/sat/captcha/package.json new file mode 100644 index 00000000..e0fe0ad4 --- /dev/null +++ b/packages/sat/captcha/package.json @@ -0,0 +1,36 @@ +{ + "name": "@sat/captcha", + "version": "0.0.1", + "license": "MIT", + "main": "src/index.ts", + "module": "src/index.ts", + "types": "src/index.ts", + "source": "src/index.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "dependencies": {}, + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/sat/captcha/src/index.ts b/packages/sat/captcha/src/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/sat/captcha/src/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/sat/captcha/tsconfig.json b/packages/sat/captcha/tsconfig.json new file mode 100644 index 00000000..0aff00ce --- /dev/null +++ b/packages/sat/captcha/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "types": [ + "node" + ], + "outDir": "./dist", + "declaration": true, + "sourceMap": true, + "noUnusedLocals": false, + "resolveJsonModule": true, + "noUnusedParameters": false + } +} diff --git a/packages/sat/captcha/vitest.config.mts b/packages/sat/captcha/vitest.config.mts new file mode 100644 index 00000000..9152d739 --- /dev/null +++ b/packages/sat/captcha/vitest.config.mts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; + +export default defineConfig({ + test: {}, + plugins: [tsconfigPaths()], +}); diff --git a/packages/sat/contabilidad/package.json b/packages/sat/contabilidad/package.json new file mode 100644 index 00000000..f4be38be --- /dev/null +++ b/packages/sat/contabilidad/package.json @@ -0,0 +1,36 @@ +{ + "name": "@sat/contabilidad", + "version": "0.0.1", + "license": "MIT", + "main": "src/index.ts", + "module": "src/index.ts", + "types": "src/index.ts", + "source": "src/index.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "dependencies": {}, + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/sat/contabilidad/src/index.ts b/packages/sat/contabilidad/src/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/sat/contabilidad/src/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/sat/contabilidad/tsconfig.json b/packages/sat/contabilidad/tsconfig.json new file mode 100644 index 00000000..0aff00ce --- /dev/null +++ b/packages/sat/contabilidad/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "types": [ + "node" + ], + "outDir": "./dist", + "declaration": true, + "sourceMap": true, + "noUnusedLocals": false, + "resolveJsonModule": true, + "noUnusedParameters": false + } +} diff --git a/packages/sat/contabilidad/vitest.config.mts b/packages/sat/contabilidad/vitest.config.mts new file mode 100644 index 00000000..9152d739 --- /dev/null +++ b/packages/sat/contabilidad/vitest.config.mts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; + +export default defineConfig({ + test: {}, + plugins: [tsconfigPaths()], +}); diff --git a/packages/sat/opinion/package.json b/packages/sat/opinion/package.json new file mode 100644 index 00000000..f1fa9844 --- /dev/null +++ b/packages/sat/opinion/package.json @@ -0,0 +1,36 @@ +{ + "name": "@sat/opinion", + "version": "0.0.1", + "license": "MIT", + "main": "src/index.ts", + "module": "src/index.ts", + "types": "src/index.ts", + "source": "src/index.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "dependencies": {}, + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/sat/opinion/src/index.ts b/packages/sat/opinion/src/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/sat/opinion/src/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/sat/opinion/tsconfig.json b/packages/sat/opinion/tsconfig.json new file mode 100644 index 00000000..0aff00ce --- /dev/null +++ b/packages/sat/opinion/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "types": [ + "node" + ], + "outDir": "./dist", + "declaration": true, + "sourceMap": true, + "noUnusedLocals": false, + "resolveJsonModule": true, + "noUnusedParameters": false + } +} diff --git a/packages/sat/opinion/vitest.config.mts b/packages/sat/opinion/vitest.config.mts new file mode 100644 index 00000000..9152d739 --- /dev/null +++ b/packages/sat/opinion/vitest.config.mts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; + +export default defineConfig({ + test: {}, + plugins: [tsconfigPaths()], +}); diff --git a/packages/sat/recursos/dist/SatResources.d.ts b/packages/sat/recursos/dist/SatResources.d.ts new file mode 100644 index 00000000..4c5f04f1 --- /dev/null +++ b/packages/sat/recursos/dist/SatResources.d.ts @@ -0,0 +1,27 @@ +export type SatVersion = '4.0' | '3.3'; +export interface SatResourcesOptions { + version: SatVersion; + outputDir: string; +} +export interface DownloadResult { + schema: string; + xslt: string; + catalogSchema: string | null; + tipoDatosSchema: string | null; + complementos: string[]; + unused: string[]; + added: string[]; +} +export declare class SatResources { + private readonly version; + private readonly outputDir; + constructor(options: SatResourcesOptions); + download(): Promise; + private _fetchText; + private _cleanXml; + private _extractSchemaImports; + private _extractXslIncludes; + private _diffComplementos; + private _rewriteIncludes; +} +//# sourceMappingURL=SatResources.d.ts.map \ No newline at end of file diff --git a/packages/sat/recursos/dist/SatResources.d.ts.map b/packages/sat/recursos/dist/SatResources.d.ts.map new file mode 100644 index 00000000..ea783bbc --- /dev/null +++ b/packages/sat/recursos/dist/SatResources.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"SatResources.d.ts","sourceRoot":"","sources":["../src/SatResources.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,KAAK,CAAC;AAEvC,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AA2BD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,EAAE,mBAAmB;IAQlC,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;YA+F3B,UAAU;IAexB,OAAO,CAAC,SAAS;IAqCjB,OAAO,CAAC,qBAAqB;IA+B7B,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,gBAAgB;CAezB"} \ No newline at end of file diff --git a/packages/sat/recursos/dist/cli.d.ts b/packages/sat/recursos/dist/cli.d.ts new file mode 100644 index 00000000..d9ae1944 --- /dev/null +++ b/packages/sat/recursos/dist/cli.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=cli.d.ts.map \ No newline at end of file diff --git a/packages/sat/recursos/dist/cli.d.ts.map b/packages/sat/recursos/dist/cli.d.ts.map new file mode 100644 index 00000000..f022439b --- /dev/null +++ b/packages/sat/recursos/dist/cli.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/sat/recursos/dist/index.d.ts b/packages/sat/recursos/dist/index.d.ts new file mode 100644 index 00000000..f0de626c --- /dev/null +++ b/packages/sat/recursos/dist/index.d.ts @@ -0,0 +1,2 @@ +export * from './SatResources'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/sat/recursos/dist/index.d.ts.map b/packages/sat/recursos/dist/index.d.ts.map new file mode 100644 index 00000000..7b421cf3 --- /dev/null +++ b/packages/sat/recursos/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"} \ No newline at end of file diff --git a/packages/sat/recursos/dist/index.mjs b/packages/sat/recursos/dist/index.mjs new file mode 100644 index 00000000..394f3393 --- /dev/null +++ b/packages/sat/recursos/dist/index.mjs @@ -0,0 +1,150 @@ +const e = {}, v = { + "4.0": { + schema: "https://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd", + xslt: "https://www.sat.gob.mx/sitio_internet/cfd/4/cadenaoriginal_4_0/cadenaoriginal_4_0.xslt" + }, + "3.3": { + schema: "https://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd", + xslt: "https://www.sat.gob.mx/sitio_internet/cfd/3/cadenaoriginal_3_3/cadenaoriginal_3_3.xslt" + } +}; +class C { + version; + outputDir; + constructor(t) { + this.version = t.version, this.outputDir = t.outputDir; + } + /** + * Descarga todos los recursos del SAT al directorio de salida. + */ + async download() { + const t = v[this.version], s = e.join(this.outputDir, "complementos"); + e.mkdirSync(this.outputDir, { recursive: !0 }), e.mkdirSync(s, { recursive: !0 }); + const n = await this._fetchText(t.schema), i = this.version === "4.0" ? "cfdv40.xsd" : "cfdv33.xsd", o = e.join(this.outputDir, i); + e.writeFileSync(o, n, "utf-8"); + const { catalogUrl: c, tipoDatosUrl: a } = this._extractSchemaImports(n); + let l = null; + if (c) + try { + const r = await this._fetchText(c), u = e.basename(c).split("?")[0]; + l = e.join(this.outputDir, u), e.writeFileSync(l, r, "utf-8"); + } catch { + l = null; + } + let h = null; + if (a) + try { + const r = await this._fetchText(a), u = e.basename(a).split("?")[0]; + h = e.join(this.outputDir, u), e.writeFileSync(h, r, "utf-8"); + } catch { + h = null; + } + const w = await this._fetchText(t.xslt), d = this._cleanXml(w), x = this._extractXslIncludes(d), m = []; + for (const r of x) + try { + const u = await this._fetchText(r), y = this._cleanXml(u), I = e.basename(r).split("?")[0], p = e.join(s, I); + e.writeFileSync(p, y, "utf-8"), m.push(p); + } catch { + } + const _ = this._rewriteIncludes(d, x), f = e.join(this.outputDir, "cadenaoriginal.xslt"); + e.writeFileSync(f, _, "utf-8"); + const S = new Set( + m.map((r) => e.basename(r)) + ), { unused: g, added: D } = this._diffComplementos( + s, + S + ); + return { + schema: o, + xslt: f, + catalogSchema: l, + tipoDatosSchema: h, + complementos: m, + unused: g, + added: D + }; + } + /** + * Descarga texto desde una URL usando fetch nativo de Node 22. + */ + async _fetchText(t) { + const s = await fetch(t); + if (!s.ok) + throw new Error( + `Error al descargar ${t}: ${s.status} ${s.statusText}` + ); + return s.text(); + } + /** + * Limpia el texto descargado del SAT eliminando basura antes del XML. + * Los archivos del SAT a veces incluyen texto como: + * "This XML file does not appear to have any style information..." + */ + _cleanXml(t) { + const s = t.indexOf(" h >= 0); + if (c.length === 0) + return t; + const a = Math.min(...c), l = t.slice(a); + return !l.startsWith(" +` + l : l; + } + /** + * Extrae las URLs de los xs:import del esquema XSD. + * Busca especificamente los catalogos (catCFDI) y tipoDatos (tdCFDI). + */ + _extractSchemaImports(t) { + const s = /]*schemaLocation=["']([^"']+)["'][^>]*>/gi; + let n = null, i = null, o; + for (; (o = s.exec(t)) !== null; ) { + const c = o[1]; + c.includes("catCFDI") || c.includes("catalogos") ? n = c : (c.includes("tdCFDI") || c.includes("tipoDatos")) && (i = c); + } + return { catalogUrl: n, tipoDatosUrl: i }; + } + /** + * Extrae las URLs de xsl:include del XSLT. + */ + _extractXslIncludes(t) { + const s = /]*href=["']([^"']+)["'][^>]*\/?>/gi, n = []; + let i; + for (; (i = s.exec(t)) !== null; ) { + const o = i[1]; + (o.startsWith("http://") || o.startsWith("https://")) && n.push(o); + } + return n; + } + /** + * Reescribe los href de xsl:include del XSLT principal para que + * apunten a rutas locales dentro de la carpeta complementos/. + * + * Ejemplo: + * href="http://www.sat.gob.mx/sitio_internet/cfd/donat/donat11.xslt" + * -> href="./complementos/donat11.xslt" + */ + /** + * Compara los archivos .xslt existentes en el directorio de complementos + * contra los que se descargaron del SAT. + * - unused: archivos locales que ya no estan en el XSLT del SAT + * - added: archivos nuevos del SAT que no existian localmente + */ + _diffComplementos(t, s) { + const n = e.existsSync(t) ? e.readdirSync(t).filter((a) => a.endsWith(".xslt")) : [], i = new Set(n), o = n.filter((a) => !s.has(a)), c = [...s].filter((a) => !i.has(a)); + return { unused: o, added: c }; + } + _rewriteIncludes(t, s) { + let n = t; + for (const i of s) { + const c = `./complementos/${e.basename(i).split("?")[0]}`; + n = n.split(i).join(c); + } + return n; + } +} +export { + C as SatResources +}; diff --git a/packages/sat/recursos/package.json b/packages/sat/recursos/package.json new file mode 100644 index 00000000..c933fb91 --- /dev/null +++ b/packages/sat/recursos/package.json @@ -0,0 +1,37 @@ +{ + "name": "@sat/recursos", + "version": "0.0.1", + "license": "MIT", + "main": "src/index.ts", + "module": "src/index.ts", + "types": "src/index.ts", + "source": "src/index.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=22" + }, + "scripts": { + "build": "vite build --config node_modules/@recreando/vite/vite.config.lib.mts", + "test": "vitest", + "test:ci": "vitest run", + "sat:download": "tsx src/cli.ts", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3", + "tsx": "^4.7.0" + } +} diff --git a/packages/sat/recursos/src/SatResources.ts b/packages/sat/recursos/src/SatResources.ts new file mode 100644 index 00000000..271b1462 --- /dev/null +++ b/packages/sat/recursos/src/SatResources.ts @@ -0,0 +1,298 @@ +import fs from 'fs'; +import path from 'path'; + +export type SatVersion = '4.0' | '3.3'; + +export interface SatResourcesOptions { + version: SatVersion; + outputDir: string; +} + +export interface DownloadResult { + schema: string; + xslt: string; + catalogSchema: string | null; + tipoDatosSchema: string | null; + complementos: string[]; + unused: string[]; + added: string[]; +} + +interface VersionUrls { + schema: string; + xslt: string; +} + +const SAT_URLS: Record = { + '4.0': { + schema: + 'https://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd', + xslt: 'https://www.sat.gob.mx/sitio_internet/cfd/4/cadenaoriginal_4_0/cadenaoriginal_4_0.xslt', + }, + '3.3': { + schema: + 'https://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd', + xslt: 'https://www.sat.gob.mx/sitio_internet/cfd/3/cadenaoriginal_3_3/cadenaoriginal_3_3.xslt', + }, +}; + +/** + * Descarga los recursos del SAT necesarios para procesar CFDI. + * + * Descarga el esquema XSD, el XSLT de cadena original y todos los + * complementos referenciados via xsl:include. Reescribe los hrefs + * del XSLT principal para apuntar a rutas locales. + */ +export class SatResources { + private readonly version: SatVersion; + private readonly outputDir: string; + + constructor(options: SatResourcesOptions) { + this.version = options.version; + this.outputDir = options.outputDir; + } + + /** + * Descarga todos los recursos del SAT al directorio de salida. + */ + async download(): Promise { + const urls = SAT_URLS[this.version]; + const complementosDir = path.join(this.outputDir, 'complementos'); + + fs.mkdirSync(this.outputDir, { recursive: true }); + fs.mkdirSync(complementosDir, { recursive: true }); + + // 1. Descargar esquema XSD principal + const schemaContent = await this._fetchText(urls.schema); + const schemaFileName = + this.version === '4.0' ? 'cfdv40.xsd' : 'cfdv33.xsd'; + const schemaPath = path.join(this.outputDir, schemaFileName); + fs.writeFileSync(schemaPath, schemaContent, 'utf-8'); + + // 2. Extraer URLs opcionales del schema (xs:import) + const { catalogUrl, tipoDatosUrl } = + this._extractSchemaImports(schemaContent); + + // 3. Descargar catalogo XSD (opcional) + let catalogSchemaPath: string | null = null; + if (catalogUrl) { + try { + const catalogContent = await this._fetchText(catalogUrl); + const catalogFileName = path.basename(catalogUrl).split('?')[0]; + catalogSchemaPath = path.join(this.outputDir, catalogFileName); + fs.writeFileSync(catalogSchemaPath, catalogContent, 'utf-8'); + } catch { + catalogSchemaPath = null; + } + } + + // 4. Descargar tipoDatos XSD (opcional) + let tipoDatosSchemaPath: string | null = null; + if (tipoDatosUrl) { + try { + const tipoDatosContent = await this._fetchText(tipoDatosUrl); + const tipoDatosFileName = path.basename(tipoDatosUrl).split('?')[0]; + tipoDatosSchemaPath = path.join(this.outputDir, tipoDatosFileName); + fs.writeFileSync(tipoDatosSchemaPath, tipoDatosContent, 'utf-8'); + } catch { + tipoDatosSchemaPath = null; + } + } + + // 5. Descargar XSLT principal + const rawXslt = await this._fetchText(urls.xslt); + const cleanXslt = this._cleanXml(rawXslt); + + // 6. Extraer URLs de xsl:include del XSLT principal + const includeUrls = this._extractXslIncludes(cleanXslt); + + // 7. Descargar cada complemento y guardar en complementos/ + const downloadedComplementos: string[] = []; + for (const includeUrl of includeUrls) { + try { + const complementoContent = await this._fetchText(includeUrl); + const cleanComplemento = this._cleanXml(complementoContent); + const fileName = path.basename(includeUrl).split('?')[0]; + const complementoPath = path.join(complementosDir, fileName); + fs.writeFileSync(complementoPath, cleanComplemento, 'utf-8'); + downloadedComplementos.push(complementoPath); + } catch { + // Ignorar complementos que no se puedan descargar + } + } + + // 8. Reescribir hrefs del XSLT principal a rutas locales + const localXslt = this._rewriteIncludes(cleanXslt, includeUrls); + + const xsltPath = path.join(this.outputDir, 'cadenaoriginal.xslt'); + fs.writeFileSync(xsltPath, localXslt, 'utf-8'); + + // 9. Comparar complementos locales vs los del SAT + const downloadedFileNames = new Set( + downloadedComplementos.map(p => path.basename(p)) + ); + const { unused, added } = this._diffComplementos( + complementosDir, + downloadedFileNames + ); + + return { + schema: schemaPath, + xslt: xsltPath, + catalogSchema: catalogSchemaPath, + tipoDatosSchema: tipoDatosSchemaPath, + complementos: downloadedComplementos, + unused, + added, + }; + } + + /** + * Descarga texto desde una URL usando fetch nativo de Node 22. + */ + private async _fetchText(url: string): Promise { + const response = await fetch(url); + if (!response.ok) { + throw new Error( + `Error al descargar ${url}: ${response.status} ${response.statusText}` + ); + } + return response.text(); + } + + /** + * Limpia el texto descargado del SAT eliminando basura antes del XML. + * Los archivos del SAT a veces incluyen texto como: + * "This XML file does not appear to have any style information..." + */ + private _cleanXml(content: string): string { + // Encontrar el inicio del XML valido + const xmlDeclarationIndex = content.indexOf(' i >= 0); + + if (candidates.length === 0) { + return content; + } + + const startIndex = Math.min(...candidates); + const cleaned = content.slice(startIndex); + + // Asegurar que el XSLT tenga declaracion XML al inicio + if ( + !cleaned.startsWith('\n' + cleaned; + } + + return cleaned; + } + + /** + * Extrae las URLs de los xs:import del esquema XSD. + * Busca especificamente los catalogos (catCFDI) y tipoDatos (tdCFDI). + */ + private _extractSchemaImports(schemaContent: string): { + catalogUrl: string | null; + tipoDatosUrl: string | null; + } { + const importRegex = + /]*schemaLocation=["']([^"']+)["'][^>]*>/gi; + let catalogUrl: string | null = null; + let tipoDatosUrl: string | null = null; + + let match: RegExpExecArray | null; + while ((match = importRegex.exec(schemaContent)) !== null) { + const schemaLocation = match[1]; + if ( + schemaLocation.includes('catCFDI') || + schemaLocation.includes('catalogos') + ) { + catalogUrl = schemaLocation; + } else if ( + schemaLocation.includes('tdCFDI') || + schemaLocation.includes('tipoDatos') + ) { + tipoDatosUrl = schemaLocation; + } + } + + return { catalogUrl, tipoDatosUrl }; + } + + /** + * Extrae las URLs de xsl:include del XSLT. + */ + private _extractXslIncludes(xsltContent: string): string[] { + const includeRegex = /]*href=["']([^"']+)["'][^>]*\/?>/gi; + const urls: string[] = []; + + let match: RegExpExecArray | null; + while ((match = includeRegex.exec(xsltContent)) !== null) { + const href = match[1]; + if (href.startsWith('http://') || href.startsWith('https://')) { + urls.push(href); + } + } + + return urls; + } + + /** + * Reescribe los href de xsl:include del XSLT principal para que + * apunten a rutas locales dentro de la carpeta complementos/. + * + * Ejemplo: + * href="http://www.sat.gob.mx/sitio_internet/cfd/donat/donat11.xslt" + * -> href="./complementos/donat11.xslt" + */ + /** + * Compara los archivos .xslt existentes en el directorio de complementos + * contra los que se descargaron del SAT. + * - unused: archivos locales que ya no estan en el XSLT del SAT + * - added: archivos nuevos del SAT que no existian localmente + */ + private _diffComplementos( + complementosDir: string, + downloadedFileNames: Set + ): { unused: string[]; added: string[] } { + const localFiles: string[] = fs.existsSync(complementosDir) + ? fs + .readdirSync(complementosDir) + .filter((f: string) => f.endsWith('.xslt')) + : []; + + const localSet = new Set(localFiles); + + const unused = localFiles.filter((f: string) => !downloadedFileNames.has(f)); + const added = [...downloadedFileNames].filter((f: string) => !localSet.has(f)); + + return { unused, added }; + } + + private _rewriteIncludes( + xsltContent: string, + includeUrls: string[] + ): string { + let result = xsltContent; + + for (const url of includeUrls) { + const fileName = path.basename(url).split('?')[0]; + const localHref = `./complementos/${fileName}`; + // Reemplazar el href exacto con la ruta local + result = result.split(url).join(localHref); + } + + return result; + } +} diff --git a/packages/sat/recursos/src/cli.ts b/packages/sat/recursos/src/cli.ts new file mode 100644 index 00000000..2fdb1d6e --- /dev/null +++ b/packages/sat/recursos/src/cli.ts @@ -0,0 +1,50 @@ +import path from 'path'; +import { SatResources } from './SatResources'; +import type { SatVersion } from './SatResources'; + +const args = process.argv.slice(2); +const version = (args.find(a => a === '3.3' || a === '4.0') || + '4.0') as SatVersion; + +const filesDir = path.resolve(__dirname, '..', '..', '..', 'files'); +const outputDir = path.join(filesDir, version === '4.0' ? '4.0' : '3.3'); + +console.log(`Descargando recursos del SAT v${version}...`); +console.log(`Directorio: ${outputDir}`); + +const sat = new SatResources({ version, outputDir }); + +sat + .download() + .then(result => { + console.log('\nRecursos descargados:'); + console.log(` Schema: ${result.schema}`); + console.log(` XSLT: ${result.xslt}`); + if (result.catalogSchema) { + console.log(` Catalogo: ${result.catalogSchema}`); + } + if (result.tipoDatosSchema) { + console.log(` TipoDatos: ${result.tipoDatosSchema}`); + } + console.log(` Complementos: ${result.complementos.length} archivos`); + + if (result.added.length > 0) { + console.log(`\n Nuevos complementos (no existian localmente):`); + result.added.forEach(f => console.log(` + ${f}`)); + } + + if (result.unused.length > 0) { + console.log(`\n Complementos sin uso (ya no estan en el XSLT del SAT):`); + result.unused.forEach(f => console.log(` - ${f}`)); + } + + if (result.unused.length === 0 && result.added.length === 0) { + console.log('\n Complementos al dia, sin cambios.'); + } + + console.log('\nListo!'); + }) + .catch(err => { + console.error('Error descargando recursos:', err.message); + process.exit(1); + }); diff --git a/packages/sat/recursos/src/index.ts b/packages/sat/recursos/src/index.ts new file mode 100644 index 00000000..66fec4e9 --- /dev/null +++ b/packages/sat/recursos/src/index.ts @@ -0,0 +1 @@ +export * from './SatResources'; diff --git a/packages/sat/recursos/test/sat.test.ts b/packages/sat/recursos/test/sat.test.ts new file mode 100644 index 00000000..f0273829 --- /dev/null +++ b/packages/sat/recursos/test/sat.test.ts @@ -0,0 +1,261 @@ +import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import fs from 'fs'; +import path from 'path'; +import os from 'os'; +import { SatResources } from '../src'; + +// Los tests de integracion que descargan del SAT requieren conexion a internet. +// Se ejecutan en CI solo si la variable INTEGRATION_TESTS=1 esta presente, +// o siempre en desarrollo local cuando se corre este archivo directamente. +const INTEGRATION = + process.env.INTEGRATION_TESTS === '1' || + process.env.NODE_ENV !== 'test' || + process.env.VITEST_RUN_INTEGRATION === '1'; + +describe('@sat/recursos - SatResources', () => { + let tmpDir: string; + + beforeAll(() => { + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cfdi-sat-test-')); + }); + + afterAll(() => { + // Limpiar directorio temporal despues de los tests + if (tmpDir && fs.existsSync(tmpDir)) { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + }); + + it('SatResources se instancia correctamente con opciones validas', () => { + const sat = new SatResources({ + version: '4.0', + outputDir: tmpDir, + }); + + expect(sat).toBeInstanceOf(SatResources); + }); + + it('SatResources se instancia correctamente con version 3.3', () => { + const sat = new SatResources({ + version: '3.3', + outputDir: tmpDir, + }); + + expect(sat).toBeInstanceOf(SatResources); + }); + + describe.skipIf(!INTEGRATION)( + 'descarga de recursos SAT (requiere internet)', + () => { + let outputDir: string; + + beforeAll(() => { + outputDir = path.join(tmpDir, 'resources-4.0'); + fs.mkdirSync(outputDir, { recursive: true }); + }); + + it('descarga los recursos CFDI 4.0 del SAT', async () => { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + const result = await sat.download(); + + // Verifica que los archivos principales existen + expect(fs.existsSync(result.schema)).toBe(true); + expect(fs.existsSync(result.xslt)).toBe(true); + }, 120_000); + + it('el XSD descargado es un schema valido', async () => { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + const result = await sat.download(); + const schemaContent = fs.readFileSync(result.schema, 'utf-8'); + + // Debe ser XML valido con declaracion de schema + expect(schemaContent).toContain(' { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + const result = await sat.download(); + const xsltContent = fs.readFileSync(result.xslt, 'utf-8'); + + // No debe contener URLs http en xsl:include + const includeMatches = xsltContent.match( + /]*href=["']([^"']+)["'][^>]*\/?>/gi + ); + + if (includeMatches) { + for (const include of includeMatches) { + expect(include).not.toMatch(/href=["']https?:\/\//); + expect(include).toMatch(/href=["']\.\/complementos\//); + } + } + }, 120_000); + + it('el XSLT tiene declaracion XML al inicio', async () => { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + const result = await sat.download(); + const xsltContent = fs.readFileSync(result.xslt, 'utf-8'); + + expect(xsltContent.trimStart()).toMatch(/^<\?xml/); + }, 120_000); + + it('los complementos se descargaron en la carpeta complementos/', async () => { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + const result = await sat.download(); + const complementosDir = path.join(outputDir, 'complementos'); + + // Debe existir la carpeta de complementos + expect(fs.existsSync(complementosDir)).toBe(true); + + // Debe haber al menos un complemento descargado + expect(result.complementos.length).toBeGreaterThan(0); + + // Cada complemento debe existir como archivo + for (const complementoPath of result.complementos) { + expect(fs.existsSync(complementoPath)).toBe(true); + } + }, 120_000); + + it('los complementos descargados son XSLTs validos', async () => { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + const result = await sat.download(); + + for (const complementoPath of result.complementos) { + const content = fs.readFileSync(complementoPath, 'utf-8'); + // Cada complemento debe ser XML que contenga stylesheet o transform + expect(content).toMatch(/ { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + const result = await sat.download(); + const complementosDir = path.join(outputDir, 'complementos'); + + for (const complementoPath of result.complementos) { + // El directorio padre de cada complemento debe ser complementosDir + expect(path.dirname(complementoPath)).toBe(complementosDir); + } + }, 120_000); + + it('el XSLT del SAT incluye complemento de utilerias', async () => { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + const result = await sat.download(); + const xsltContent = fs.readFileSync(result.xslt, 'utf-8'); + + // utilerias.xslt es un complemento conocido del SAT CFDI 4.0 + expect(xsltContent).toContain('utilerias.xslt'); + }, 120_000); + + it('extrae archivos opcionales de catalogos del schema', async () => { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + const result = await sat.download(); + + // Si el schema contiene xs:import de catCFDI o tdCFDI, deben descargarse + // Pueden ser null si el schema no los incluye + if (result.catalogSchema !== null) { + expect(fs.existsSync(result.catalogSchema)).toBe(true); + const content = fs.readFileSync(result.catalogSchema, 'utf-8'); + expect(content).toContain(' { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + const result = await sat.download(); + const xsltContent = fs.readFileSync(result.xslt, 'utf-8'); + + // No debe contener el texto de error del SAT + expect(xsltContent).not.toContain( + 'This XML file does not appear to have any style information' + ); + expect(xsltContent).not.toContain('The document tree is shown below'); + }, 120_000); + + it('crea la estructura de directorios correcta', async () => { + const sat = new SatResources({ + version: '4.0', + outputDir, + }); + + await sat.download(); + + // Estructura esperada + expect(fs.existsSync(outputDir)).toBe(true); + expect( + fs.existsSync(path.join(outputDir, 'complementos')) + ).toBe(true); + expect( + fs.existsSync(path.join(outputDir, 'cadenaoriginal.xslt')) + ).toBe(true); + expect( + fs.existsSync(path.join(outputDir, 'cfdv40.xsd')) + ).toBe(true); + }, 120_000); + + it('descarga correctamente los recursos CFDI 3.3', async () => { + const dir33 = path.join(tmpDir, 'resources-3.3'); + fs.mkdirSync(dir33, { recursive: true }); + + const sat = new SatResources({ + version: '3.3', + outputDir: dir33, + }); + + const result = await sat.download(); + + expect(fs.existsSync(result.schema)).toBe(true); + expect(fs.existsSync(result.xslt)).toBe(true); + + const schemaContent = fs.readFileSync(result.schema, 'utf-8'); + expect(schemaContent).toContain('=22" + }, + "scripts": { + "build": "vite build", + "test": "vitest", + "test:ci": "vitest run", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "author": "MisaelMa", + "dependencies": {}, + "devDependencies": { + "@recreando/eslint-settings": "workspace:*", + "@recreando/vite": "workspace:*", + "@recreando/typescript-settings": "workspace:*", + "@types/node": "^22", + "eslint": "^8.57.0", + "typescript": "^5.6.3", + "vitest": "2.1.3", + "vite-tsconfig-paths": "~4.2.1", + "@vitest/coverage-v8": "2.1.3", + "@vitest/ui": "2.1.3" + } +} diff --git a/packages/sat/scraper/src/index.ts b/packages/sat/scraper/src/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/sat/scraper/src/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/sat/scraper/tsconfig.json b/packages/sat/scraper/tsconfig.json new file mode 100644 index 00000000..0aff00ce --- /dev/null +++ b/packages/sat/scraper/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./node_modules/@recreando/typescript-settings/profiles/default/tsconfig-base.json", + "compilerOptions": { + "types": [ + "node" + ], + "outDir": "./dist", + "declaration": true, + "sourceMap": true, + "noUnusedLocals": false, + "resolveJsonModule": true, + "noUnusedParameters": false + } +} diff --git a/packages/sat/scraper/vitest.config.mts b/packages/sat/scraper/vitest.config.mts new file mode 100644 index 00000000..9152d739 --- /dev/null +++ b/packages/sat/scraper/vitest.config.mts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; +import tsconfigPaths from 'vite-tsconfig-paths'; + +export default defineConfig({ + test: {}, + plugins: [tsconfigPaths()], +}); diff --git a/packages/server/.gitignore b/packages/server/.gitignore new file mode 100644 index 00000000..5ef6a520 --- /dev/null +++ b/packages/server/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/packages/server/README.md b/packages/server/README.md new file mode 100644 index 00000000..7f1e36fe --- /dev/null +++ b/packages/server/README.md @@ -0,0 +1,21 @@ +# @cfdi/server + +Aplicacion web Next.js para el ecosistema CFDI. Proporciona una interfaz de usuario para la generacion y gestion de comprobantes fiscales. + +## Desarrollo + +```bash +pnpm dev +``` + +Abre http://localhost:3000 en tu navegador. + +## Build + +```bash +pnpm build +``` + +## Licencia + +[MIT](../../LICENSE) diff --git a/packages/server/eslint.config.mjs b/packages/server/eslint.config.mjs new file mode 100644 index 00000000..c85fb67c --- /dev/null +++ b/packages/server/eslint.config.mjs @@ -0,0 +1,16 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [ + ...compat.extends("next/core-web-vitals", "next/typescript"), +]; + +export default eslintConfig; diff --git a/packages/server/next.config.ts b/packages/server/next.config.ts new file mode 100644 index 00000000..e10954b6 --- /dev/null +++ b/packages/server/next.config.ts @@ -0,0 +1,8 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ + +}; + +export default nextConfig; diff --git a/packages/server/package-lock.json b/packages/server/package-lock.json new file mode 100644 index 00000000..33405748 --- /dev/null +++ b/packages/server/package-lock.json @@ -0,0 +1,5469 @@ +{ + "name": "server", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "server", + "version": "0.1.0", + "dependencies": { + "next": "15.2.1", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "@tailwindcss/postcss": "^4", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "15.2.1", + "tailwindcss": "^4", + "typescript": "^5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz", + "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.12.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@next/env": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.2.1.tgz", + "integrity": "sha512-JmY0qvnPuS2NCWOz2bbby3Pe0VzdAQ7XpEB6uLIHmtXNfAsAO0KLQLkuAoc42Bxbo3/jMC3dcn9cdf+piCcG2Q==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.2.1.tgz", + "integrity": "sha512-6ppeToFd02z38SllzWxayLxjjNfzvc7Wm07gQOKSLjyASvKcXjNStZrLXMHuaWkhjqxe+cnhb2uzfWXm1VEj/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.2.1.tgz", + "integrity": "sha512-aWXT+5KEREoy3K5AKtiKwioeblmOvFFjd+F3dVleLvvLiQ/mD//jOOuUcx5hzcO9ISSw4lrqtUPntTpK32uXXQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.2.1.tgz", + "integrity": "sha512-E/w8ervu4fcG5SkLhvn1NE/2POuDCDEy5gFbfhmnYXkyONZR68qbUlJlZwuN82o7BrBVAw+tkR8nTIjGiMW1jQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.2.1.tgz", + "integrity": "sha512-gXDX5lIboebbjhiMT6kFgu4svQyjoSed6dHyjx5uZsjlvTwOAnZpn13w9XDaIMFFHw7K8CpBK7HfDKw0VZvUXQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.2.1.tgz", + "integrity": "sha512-3v0pF/adKZkBWfUffmB/ROa+QcNTrnmYG4/SS+r52HPwAK479XcWoES2I+7F7lcbqc7mTeVXrIvb4h6rR/iDKg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.2.1.tgz", + "integrity": "sha512-RbsVq2iB6KFJRZ2cHrU67jLVLKeuOIhnQB05ygu5fCNgg8oTewxweJE8XlLV+Ii6Y6u4EHwETdUiRNXIAfpBww==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.2.1.tgz", + "integrity": "sha512-QHsMLAyAIu6/fWjHmkN/F78EFPKmhQlyX5C8pRIS2RwVA7z+t9cTb0IaYWC3EHLOTjsU7MNQW+n2xGXr11QPpg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.2.1.tgz", + "integrity": "sha512-Gk42XZXo1cE89i3hPLa/9KZ8OuupTjkDmhLaMKFohjf9brOeZVEa3BQy1J9s9TWUqPhgAEbwv6B2+ciGfe54Vw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.2.1.tgz", + "integrity": "sha512-YjqXCl8QGhVlMR8uBftWk0iTmvtntr41PhG1kvzGp0sUP/5ehTM+cwx25hKE54J0CRnHYjSGjSH3gkHEaHIN9g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.5.tgz", + "integrity": "sha512-kkKUDVlII2DQiKy7UstOR1ErJP8kUKAQ4oa+SQtM0K+lPdmmjj0YnnxBgtTVYH7mUKtbsxeFC9y0AmK7Yb78/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.0.9.tgz", + "integrity": "sha512-tOJvdI7XfJbARYhxX+0RArAhmuDcczTC46DGCEziqxzzbIaPnfYaIyRT31n4u8lROrsO7Q6u/K9bmQHL2uL1bQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "tailwindcss": "4.0.9" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.0.9.tgz", + "integrity": "sha512-eLizHmXFqHswJONwfqi/WZjtmWZpIalpvMlNhTM99/bkHtUs6IqgI1XQ0/W5eO2HiRQcIlXUogI2ycvKhVLNcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.0.9", + "@tailwindcss/oxide-darwin-arm64": "4.0.9", + "@tailwindcss/oxide-darwin-x64": "4.0.9", + "@tailwindcss/oxide-freebsd-x64": "4.0.9", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.9", + "@tailwindcss/oxide-linux-arm64-gnu": "4.0.9", + "@tailwindcss/oxide-linux-arm64-musl": "4.0.9", + "@tailwindcss/oxide-linux-x64-gnu": "4.0.9", + "@tailwindcss/oxide-linux-x64-musl": "4.0.9", + "@tailwindcss/oxide-win32-arm64-msvc": "4.0.9", + "@tailwindcss/oxide-win32-x64-msvc": "4.0.9" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.9.tgz", + "integrity": "sha512-YBgy6+2flE/8dbtrdotVInhMVIxnHJPbAwa7U1gX4l2ThUIaPUp18LjB9wEH8wAGMBZUb//SzLtdXXNBHPUl6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.9.tgz", + "integrity": "sha512-pWdl4J2dIHXALgy2jVkwKBmtEb73kqIfMpYmcgESr7oPQ+lbcQ4+tlPeVXaSAmang+vglAfFpXQCOvs/aGSqlw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.9.tgz", + "integrity": "sha512-4Dq3lKp0/C7vrRSkNPtBGVebEyWt9QPPlQctxJ0H3MDyiQYvzVYf8jKow7h5QkWNe8hbatEqljMj/Y0M+ERYJg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.9.tgz", + "integrity": "sha512-k7U1RwRODta8x0uealtVt3RoWAWqA+D5FAOsvVGpYoI6ObgmnzqWW6pnVwz70tL8UZ/QXjeMyiICXyjzB6OGtQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.9.tgz", + "integrity": "sha512-NDDjVweHz2zo4j+oS8y3KwKL5wGCZoXGA9ruJM982uVJLdsF8/1AeKvUwKRlMBpxHt1EdWJSAh8a0Mfhl28GlQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.9.tgz", + "integrity": "sha512-jk90UZ0jzJl3Dy1BhuFfRZ2KP9wVKMXPjmCtY4U6fF2LvrjP5gWFJj5VHzfzHonJexjrGe1lMzgtjriuZkxagg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.9.tgz", + "integrity": "sha512-3eMjyTC6HBxh9nRgOHzrc96PYh1/jWOwHZ3Kk0JN0Kl25BJ80Lj9HEvvwVDNTgPg154LdICwuFLuhfgH9DULmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.9.tgz", + "integrity": "sha512-v0D8WqI/c3WpWH1kq/HP0J899ATLdGZmENa2/emmNjubT0sWtEke9W9+wXeEoACuGAhF9i3PO5MeyditpDCiWQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.9.tgz", + "integrity": "sha512-Kvp0TCkfeXyeehqLJr7otsc4hd/BUPfcIGrQiwsTVCfaMfjQZCG7DjI+9/QqPZha8YapLA9UoIcUILRYO7NE1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.9.tgz", + "integrity": "sha512-m3+60T/7YvWekajNq/eexjhV8z10rswcz4BC9bioJ7YaN+7K8W2AmLmG0B79H14m6UHE571qB0XsPus4n0QVgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.9.tgz", + "integrity": "sha512-dpc05mSlqkwVNOUjGu/ZXd5U1XNch1kHFJ4/cHkZFvaW1RzbHmRt24gvM8/HC6IirMxNarzVw4IXVtvrOoZtxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.0.9.tgz", + "integrity": "sha512-BT/E+pdMqulavEAVM5NCpxmGEwHiLDPpkmg/c/X25ZBW+izTe+aZ+v1gf/HXTrihRoCxrUp5U4YyHsBTzspQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.0.9", + "@tailwindcss/oxide": "4.0.9", + "lightningcss": "^1.29.1", + "postcss": "^8.4.41", + "tailwindcss": "4.0.9" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.17.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.23.tgz", + "integrity": "sha512-8PCGZ1ZJbEZuYNTMqywO+Sj4vSKjSjT6Ua+6RFOYlEvIvKQABPtrNkoVSLSKDb4obYcMhspVKmsw8Cm10NFRUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/react": { + "version": "19.0.10", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz", + "integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.4.tgz", + "integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.0.tgz", + "integrity": "sha512-cLr1J6pe56zjKYajK6SSSre6nl1Gj6xDp1TY0trpgPzjVbgDwd09v2Ws37LABxzkicmUjhEeg/fAUjPJJB1v5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/type-utils": "8.26.0", + "@typescript-eslint/utils": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.0.tgz", + "integrity": "sha512-mNtXP9LTVBy14ZF3o7JG69gRPBK/2QWtQd0j0oH26HcY/foyJJau6pNUez7QrM5UHnSvwlQcJXKsk0I99B9pOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/typescript-estree": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.0.tgz", + "integrity": "sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.0.tgz", + "integrity": "sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.26.0", + "@typescript-eslint/utils": "8.26.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.0.tgz", + "integrity": "sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.0.tgz", + "integrity": "sha512-tiJ1Hvy/V/oMVRTbEOIeemA2XoylimlDQ03CgPPNaHYZbpsc78Hmngnt+WXZfJX1pjQ711V7g0H7cSJThGYfPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.0.tgz", + "integrity": "sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/typescript-estree": "8.26.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.0.tgz", + "integrity": "sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001702", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001702.tgz", + "integrity": "sha512-LoPe/D7zioC0REI5W73PeR1e1MLCipRGq/VkovJnd6Df+QVqT+vT33OXCp8QUd7kA7RZrHWxb1B36OQKI/0gOA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "optional": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-abstract": { + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz", + "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.21.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-next": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.2.1.tgz", + "integrity": "sha512-mhsprz7l0no8X+PdDnVHF4dZKu9YBJp2Rf6ztWbXBLJ4h6gxmW//owbbGJMBVUU+PibGJDAqZhW4pt8SC8HSow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "15.2.1", + "@rushstack/eslint-patch": "^1.10.3", + "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-react": "^7.37.0", + "eslint-plugin-react-hooks": "^5.0.0" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.8.3.tgz", + "integrity": "sha512-A0bu4Ks2QqDWNpeEgTQMPTngaMhuDu4yv6xpftBMAf+1ziXnpx+eSR1WRfoPTe2BAiAjHFZ7kSNx1fvr5g5pmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.3.7", + "enhanced-resolve": "^5.15.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^1.0.2", + "stable-hash": "^0.0.4", + "tinyglobby": "^0.2.12" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", + "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", + "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT", + "optional": true + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.6.3" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.1.tgz", + "integrity": "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.29.1", + "lightningcss-darwin-x64": "1.29.1", + "lightningcss-freebsd-x64": "1.29.1", + "lightningcss-linux-arm-gnueabihf": "1.29.1", + "lightningcss-linux-arm64-gnu": "1.29.1", + "lightningcss-linux-arm64-musl": "1.29.1", + "lightningcss-linux-x64-gnu": "1.29.1", + "lightningcss-linux-x64-musl": "1.29.1", + "lightningcss-win32-arm64-msvc": "1.29.1", + "lightningcss-win32-x64-msvc": "1.29.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz", + "integrity": "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.1.tgz", + "integrity": "sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.1.tgz", + "integrity": "sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.1.tgz", + "integrity": "sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.1.tgz", + "integrity": "sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.1.tgz", + "integrity": "sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.1.tgz", + "integrity": "sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.1.tgz", + "integrity": "sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.1.tgz", + "integrity": "sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz", + "integrity": "sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/next/-/next-15.2.1.tgz", + "integrity": "sha512-zxbsdQv3OqWXybK5tMkPCBKyhIz63RstJ+NvlfkaLMc/m5MwXgz2e92k+hSKcyBpyADhMk2C31RIiaDjUZae7g==", + "license": "MIT", + "dependencies": { + "@next/env": "15.2.1", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.15", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.2.1", + "@next/swc-darwin-x64": "15.2.1", + "@next/swc-linux-arm64-gnu": "15.2.1", + "@next/swc-linux-arm64-musl": "15.2.1", + "@next/swc-linux-x64-gnu": "15.2.1", + "@next/swc-linux-x64-musl": "15.2.1", + "@next/swc-win32-arm64-msvc": "15.2.1", + "@next/swc-win32-x64-msvc": "15.2.1", + "sharp": "^0.33.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", + "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", + "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.25.0" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "devOptional": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/sharp/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.9.tgz", + "integrity": "sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", + "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/packages/server/package.json b/packages/server/package.json new file mode 100644 index 00000000..0677812d --- /dev/null +++ b/packages/server/package.json @@ -0,0 +1,33 @@ +{ + "name": "server", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0", + "next": "15.2.3", + "@cfdi/designs": "workspace:*", + "@cfdi/pdf": "workspace:*", + "@cfdi/catalogos": "workspace:*", + "@cfdi/utils": "workspace:*", + "@cfdi/2json": "workspace:*", + "@cfdi/schema": "workspace:*" + }, + "devDependencies": { + "typescript": "^5", + "@types/node": "^22", + "@types/react": "^19", + "@types/react-dom": "^19", + "@tailwindcss/postcss": "^4", + "tailwindcss": "^4", + "eslint": "^9", + "eslint-config-next": "15.2.1", + "@eslint/eslintrc": "^3" + } +} diff --git a/packages/server/postcss.config.mjs b/packages/server/postcss.config.mjs new file mode 100644 index 00000000..c7bcb4b1 --- /dev/null +++ b/packages/server/postcss.config.mjs @@ -0,0 +1,5 @@ +const config = { + plugins: ["@tailwindcss/postcss"], +}; + +export default config; diff --git a/packages/server/public/file.svg b/packages/server/public/file.svg new file mode 100644 index 00000000..004145cd --- /dev/null +++ b/packages/server/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/server/public/globe.svg b/packages/server/public/globe.svg new file mode 100644 index 00000000..567f17b0 --- /dev/null +++ b/packages/server/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/server/public/next.svg b/packages/server/public/next.svg new file mode 100644 index 00000000..5174b28c --- /dev/null +++ b/packages/server/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/server/public/vercel.svg b/packages/server/public/vercel.svg new file mode 100644 index 00000000..77053960 --- /dev/null +++ b/packages/server/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/server/public/window.svg b/packages/server/public/window.svg new file mode 100644 index 00000000..b2b2a44f --- /dev/null +++ b/packages/server/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/server/src/app/cfdi/pdf/route.ts b/packages/server/src/app/cfdi/pdf/route.ts new file mode 100644 index 00000000..72296e02 --- /dev/null +++ b/packages/server/src/app/cfdi/pdf/route.ts @@ -0,0 +1,21 @@ + +import {PDF117} from '@cfdi/designs/dist/index.cjs' +import PDF111 from '@cfdi/designs/src/B333' +export async function GET(request: Request) { + /* const a = new PDF117( + '/Users/amir/Documents/proyectos/amir/node/cfdi/packages/files/xml/5E2D6AFF-2DD7-43D1-83D3-14C1ACA396D9.xml', + ); */ + const pdf = new PDF111() + pdf.design() + //console.log(pdf.design()) + // pdf.design() + const pdfBuffer = await pdf.getPDF().getBuffer() + //return Response.json({ message: 'Hello World' }) + + return new Response(pdfBuffer, { + headers: { + 'Content-Type': 'application/pdf', + 'Content-Disposition': 'inline; filename="documento.pdf"', + }, + }); +} \ No newline at end of file diff --git a/packages/server/src/app/cfdi/schema/route.ts b/packages/server/src/app/cfdi/schema/route.ts new file mode 100644 index 00000000..bd2d93fc --- /dev/null +++ b/packages/server/src/app/cfdi/schema/route.ts @@ -0,0 +1,8 @@ + +import {PDF117} from '@cfdi/designs/dist/index.cjs' +import { xsdService } from '@cfdi/schema' +export async function GET(request: Request) { + + const result = await xsdService.processXSD() + return Response.json({ message: 'Hello World',result}) +} \ No newline at end of file diff --git a/packages/server/src/app/favicon.ico b/packages/server/src/app/favicon.ico new file mode 100644 index 00000000..718d6fea Binary files /dev/null and b/packages/server/src/app/favicon.ico differ diff --git a/packages/server/src/app/globals.css b/packages/server/src/app/globals.css new file mode 100644 index 00000000..a2dc41ec --- /dev/null +++ b/packages/server/src/app/globals.css @@ -0,0 +1,26 @@ +@import "tailwindcss"; + +:root { + --background: #ffffff; + --foreground: #171717; +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +body { + background: var(--background); + color: var(--foreground); + font-family: Arial, Helvetica, sans-serif; +} diff --git a/packages/server/src/app/layout.tsx b/packages/server/src/app/layout.tsx new file mode 100644 index 00000000..f7fa87eb --- /dev/null +++ b/packages/server/src/app/layout.tsx @@ -0,0 +1,34 @@ +import type { Metadata } from "next"; +import { Geist, Geist_Mono } from "next/font/google"; +import "./globals.css"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export const metadata: Metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} diff --git a/packages/server/src/app/page.tsx b/packages/server/src/app/page.tsx new file mode 100644 index 00000000..3eee0141 --- /dev/null +++ b/packages/server/src/app/page.tsx @@ -0,0 +1,101 @@ +import Image from "next/image"; + +export default function Home() { + return ( +
+
+ Next.js logo +
    +
  1. + Get started by editing{" "} + + src/app/page.tsx + + . +
  2. +
  3. Save and see your changes instantly.
  4. +
+ + +
+ +
+ ); +} diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json new file mode 100644 index 00000000..13d0ff1d --- /dev/null +++ b/packages/server/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"], + "@cfdi/utils": ["./node_modules/@cfdi/utils/src"], + "@cfdi/utils/*": ["./node_modules/@cfdi/utils/src/*"], + "@cfdi/2json/*": ["./node_modules/@cfdi/2json/src/*"], + "@cfdi/schema": ["./node_modules/@cfdi/schema/src"], + "@cfdi/schema/*": ["./node_modules/@cfdi/schema/src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/plan/index.md b/plan/index.md new file mode 100644 index 00000000..bf22300a --- /dev/null +++ b/plan/index.md @@ -0,0 +1,189 @@ +# Analisis: Paquetes que faltan en @cfdi vs nodecfdi y npm + +## Contexto + +Comparar el ecosistema @cfdi contra @nodecfdi y otros paquetes npm para identificar funcionalidad que falta y mejoras necesarias en paquetes existentes. + +--- + +## Paquetes existentes que necesitan MEJORAS + +### 1. `@cfdi/rfc` — Necesita mejoras significativas + +**Estado actual:** Validación básica (regex + fecha + checksum + palabras prohibidas). Tests vacíos. + +**Lo que @nodecfdi/rfc tiene y nosotros NO:** + +- Clase `Rfc` como Value Object (API orientada a objetos) +- `RfcIntConverter` — convierte RFC ↔ entero de 64 bits (útil para BD) +- `RfcFaker` — genera RFCs aleatorios válidos (útil para tests) +- `obtainDate()` — extrae fecha de nacimiento/constitución +- Flags de validación: `DISALLOW_GENERIC`, `DISALLOW_FOREIGN` +- Detección de RFC genérico (`XAXX010101000`) y extranjero (`XEXX010101000`) como tipos especiales +- Compatibilidad con navegadores + +**Mejoras propuestas:** + +- [ ] Crear clase `Rfc` con métodos `isFisica()`, `isMoral()`, `isGeneric()`, `isForeign()` +- [ ] Agregar `RfcFaker` para generar RFCs de prueba +- [ ] Agregar extracción de fecha del RFC +- [ ] Escribir tests reales (actualmente tests vacíos) + +### 2. `@cfdi/csd` — Necesita soporte FIEL y limpieza + +**Estado actual:** Maneja CSD (.cer/.key) con OpenSSL CLI + node-forge. Tests vacíos. + +**Lo que @nodecfdi/credentials tiene y nosotros NO:** + +- **Soporte FIEL (eFirma)** — firma electrónica legal, no solo CSD +- Clase `Credential` que une certificado + clave privada +- `isFiel()` / `isCsd()` — detecta tipo de credencial +- `rfc()` — extrae RFC del certificado automáticamente +- `legalName()` — nombre legal del titular +- `verify(data, signature)` — verificación de firmas +- Validación de que certificado y clave sean par (`belongsTo`) +- Soporte PFX/PKCS#12 (crear y leer) +- Sin dependencia de OpenSSL CLI (usa crypto nativo) +- Múltiples algoritmos de firma + +**Mejoras propuestas:** + +- [ ] Agregar clase `Credential` (CSD + FIEL unificado) +- [ ] Migrar de OpenSSL CLI a crypto nativo de Node 22 (eliminar `@clir/openssl`) +- [ ] Agregar `isFiel()`, `isCsd()`, `rfc()`, `legalName()` +- [ ] Agregar verificación de firmas y validación de pares cert+key +- [ ] Soporte PFX import/export +- [ ] Escribir tests reales + +--- + +## Comparacion completa @cfdi vs @nodecfdi + +| Funcionalidad | @cfdi | @nodecfdi | Estado | +| --------------------- | -------------------- | ------------------------ | ----------------- | +| XML CFDI 4.0 | `@cfdi/xml` | `cfdi-core` | Ambos | +| Complementos | `@cfdi/complementos` | `cfdi-elementos` | Ambos | +| Certificados CSD | `@cfdi/csd` (básico) | `credentials` (completo) | **Mejorar** | +| FIEL (eFirma) | **NO** | `credentials` | **Agregar a csd** | +| Catalogos SAT | `@cfdi/catalogos` | `sat-micro-catalogs` | Ambos | +| XML a JSON | `@cfdi/2json` | `cfdi-to-json` | Ambos | +| Expresiones/QR | `@cfdi/expresiones` | `cfdi-expresiones` | Ambos | +| RFC | `@cfdi/rfc` (básico) | `rfc` (completo) | **Mejorar** | +| PDF | `@cfdi/designs` | `cfdi-to-pdf` | Ambos | +| CSF (Constancia) | `@cfdi/csf` | `csf-pdf-scraper` | Ambos | +| XSD Validacion | `@cfdi/xsd` | `xml-schema-validator` | Ambos | +| Transform XSLT nativo | `@cfdi/transform` | **NO EXISTE** | **Ventaja @cfdi** | +| SAT Resources | `@cfdi/sat` | `xml-resource-retriever` | Similar | +| CURP | `@cfdi/curp` | **NO EXISTE** | **Ventaja @cfdi** | +| Validador CFDI | **NO** | `cfdi-validator` | **Crear** | +| Estado CFDI (SAT) | **NO** | `sat-estado-cfdi` | **Crear** | +| Descarga masiva SAT | **NO** | `sat-ws-descarga-masiva` | **Crear** | +| CFDI Cleaner | **NO** | `cfdi-cleaner` | **Crear** | +| Auth SAT (scrapers) | **NO** | `sat-scrapers-auth` | **Crear** | + +--- + +## Paquetes NUEVOS que faltan (por prioridad) + +### ALTA PRIORIDAD + +#### `@cfdi/estado` — Consulta estado CFDI en SAT + +- Consulta webservice SAT para verificar si CFDI es vigente/cancelado +- URL: `https://consultaqr.facturaelectronica.sat.gob.mx/ConsultaCFDIService.svc` +- Solo fetch nativo, sin dependencias +- @nodecfdi tiene 663 descargas/mes → hay demanda + +#### `@cfdi/validador` — Validador de CFDI completo + +- Valida estructura XML contra XSD +- Valida reglas de negocio (montos, impuestos, fechas) +- Valida sello digital y certificado +- Valida timbre fiscal digital + +### MEDIA PRIORIDAD + +#### `@cfdi/descarga` — Descarga masiva del SAT + +- Consume webservice de descarga masiva del SAT +- Autenticación con FIEL (necesita `@cfdi/csd` mejorado primero) +- Descarga XMLs de CFDIs emitidos/recibidos + +#### `@cfdi/cleaner` — Limpiador de CFDI + +- Elimina addendas, namespaces no estándar, nodos no-SAT +- Normaliza XML para validación +- Útil cuando recibes CFDIs de terceros + +### BAJA PRIORIDAD + +#### `@cfdi/auth` — Autenticación en sitios SAT + +- Login en portal SAT con FIEL +- Scraping de información fiscal +- Necesita `@cfdi/csd` con soporte FIEL primero + +--- + +## Lo que NO necesitamos crear + +| No crear | Porque | +| ----------------------- | --------------------------------------- | +| Timbrado propio | Requiere ser PAC certificado por el SAT | +| SDK Facturapi/Fiscalapi | Servicios de terceros | +| Base converter | Trivial | +| AdonisJS wrapper | Framework-specific | +| Config packages | Ya tenemos `@recreando/*` | + +--- + +## Ventajas competitivas de @cfdi + +1. **`@cfdi/transform`** — Cadena original sin Java/Saxon. Único en el mercado +2. **`@cfdi/curp`** — Validación y consulta CURP. Nodecfdi no tiene +3. **`@cfdi/sat`** — Descarga recursos SAT con diff de complementos +4. **Monorepo unificado** — 1 repo vs 28 repos separados de nodecfdi +5. **Node 22 + Vite** — Stack más moderno +6. **Serverless-ready** — Sin Java/Saxon/OpenSSL CLI + +--- + +## Plan de acción + +### Fase 1: Consolidar (actual) + +- Terminar `@cfdi/transform` ✅ (98 tests pasan) +- Terminar READMEs +- Quitar dependencia Saxon de `@cfdi/xml` + +### Fase 2: Mejorar existentes + +- **`@cfdi/rfc`** — Clase Rfc, RfcFaker, tests reales +- **`@cfdi/csd`** — Soporte FIEL, crypto nativo, Credential class, eliminar OpenSSL CLI + +### Fase 3: Paquetes nuevos alta prioridad + +- **`@cfdi/estado`** — Consulta estado CFDI en SAT +- **`@cfdi/validador`** — Validación completa + +### Fase 4: Paquetes nuevos media prioridad + +- **`@cfdi/descarga`** — Descarga masiva SAT (requiere FIEL de fase 2) +- **`@cfdi/cleaner`** — Limpiador XML + +--- + +## Verificacion + +- Cada paquete nuevo: agregar a rush.json, commitlint.config.js, semantic.yml, github-actions.js +- Tests: `rush test:ci` +- Publicar: `rush publish` + +## Archivos a modificar por paquete nuevo + +| Archivo | Acción | +| ---------------------------------- | ----------------------------------- | +| `rush.json` | Agregar entrada del proyecto | +| `commitlint.config.js` | Agregar scope | +| `.github/workflows/semantic.yml` | Agregar a labels y scopes | +| `common/scripts/github-actions.js` | Agregar a `getDependences` y `list` | diff --git a/rigs/typescript/package.json b/rigs/typescript/package.json index f39b24d3..270fff63 100644 --- a/rigs/typescript/package.json +++ b/rigs/typescript/package.json @@ -7,10 +7,6 @@ "build": "" }, "dependencies": { - "@rushstack/heft": "^0.68.6", - "@rushstack/heft-jest-plugin": "^0.12.18", - "eslint": "^8.57.0", - "jest-environment-node": "^29.5.0", "typescript": "^5.6.3", "tsconfig-paths": "^4.0.0" } diff --git a/rigs/typescript/profiles/default/tsconfig-base.json b/rigs/typescript/profiles/default/tsconfig-base.json index 75f39e56..99949c3c 100644 --- a/rigs/typescript/profiles/default/tsconfig-base.json +++ b/rigs/typescript/profiles/default/tsconfig-base.json @@ -54,6 +54,9 @@ "@cfdi/schema": [ "./node_modules/@cfdi/schema/src" ], + "@cfdi/schema/*": [ + "./node_modules/@cfdi/schema/src/*" + ], "@cfdi/xsd": [ "./node_modules/@cfdi/xsd/src" ], @@ -72,8 +75,29 @@ "@cfdi/pdf": [ "./node_modules/@cfdi/pdf/src" ], - "@cfdi/curp": [ - "./node_modules/@cfdi/curp/src" + "@renapo/curp": [ + "./node_modules/@renapo/curp/src" + ], + "@sat/auth": [ + "./node_modules/@sat/auth/src" + ], + "@sat/recursos": [ + "./node_modules/@sat/recursos/src" + ], + "@sat/scraper": [ + "./node_modules/@sat/scraper/src" + ], + "@sat/opinion": [ + "./node_modules/@sat/opinion/src" + ], + "@sat/contabilidad": [ + "./node_modules/@sat/contabilidad/src" + ], + "@sat/captcha": [ + "./node_modules/@sat/captcha/src" + ], + "@cfdi/cancelacion": [ + "./node_modules/@cfdi/cancelacion/src" ], "@clir/openssl": [ "./node_modules/@clir/openssl/src" @@ -85,6 +109,7 @@ "./node_modules/@saxon-he/cli/src" ], "@cfdi/utils/*": [ + "./node_modules/@cfdi/utils/src", "./node_modules/@cfdi/utils/src/*" ], "@cfdi/utils": [ @@ -118,7 +143,15 @@ "../../../../../node_modules/@clir/**/src/**/*.ts", "../../../../../node_modules/@clir/**/src/**/*.tsx", "../../../../../node_modules/@clir/**/src/**/*.d.ts", - "../../../../../node_modules/@clir/**/src/**/*.json" + "../../../../../node_modules/@clir/**/src/**/*.json", + "../../../../../node_modules/@sat/**/src/**/*.ts", + "../../../../../node_modules/@sat/**/src/**/*.tsx", + "../../../../../node_modules/@sat/**/src/**/*.d.ts", + "../../../../../node_modules/@sat/**/src/**/*.json", + "../../../../../node_modules/@renapo/**/src/**/*.ts", + "../../../../../node_modules/@renapo/**/src/**/*.tsx", + "../../../../../node_modules/@renapo/**/src/**/*.d.ts", + "../../../../../node_modules/@renapo/**/src/**/*.json" ], "exclude": [ diff --git a/rigs/vite/package.json b/rigs/vite/package.json index 7b06fe5f..89c950b9 100644 --- a/rigs/vite/package.json +++ b/rigs/vite/package.json @@ -4,7 +4,8 @@ "type": "module", "main": "./vite.config.mts", "exports": { - ".": "./vite.config.mts" + ".": "./vite.config.mts", + "./lib": "./vite.config.lib.mts" }, "scripts": { "build": "", @@ -15,7 +16,8 @@ "test:ui": "vitest --ui" }, "dependencies": { - "vite": "^4.0.0" + "vite": "^7.0.0", + "vite-plugin-dts": "^4.5.3" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/rigs/vite/vite.config.lib.mts b/rigs/vite/vite.config.lib.mts new file mode 100644 index 00000000..c68d52ee --- /dev/null +++ b/rigs/vite/vite.config.lib.mts @@ -0,0 +1,33 @@ +import { defineConfig } from 'vite'; +import dts from 'vite-plugin-dts'; + +export default defineConfig({ + build: { + lib: { + entry: 'src/index.ts', + formats: ['es', 'cjs'], + fileName: (format) => `index.${format === 'es' ? 'mjs' : 'cjs'}`, + }, + rollupOptions: { + external: [ + /^@cfdi\//, + /^@clir\//, + /^@saxon-he\//, + /^@sat\//, + /^@renapo\//, + /^node:/, + 'crypto', + ], + }, + minify: 'esbuild', + sourcemap: false, + target: 'esnext', + }, + plugins: [ + dts({ + insertTypesEntry: true, + rollupTypes: true, + exclude: ['node_modules/**'], + }), + ], +}); diff --git a/rush.json b/rush.json index e6cd8e56..79800c77 100644 --- a/rush.json +++ b/rush.json @@ -1,13 +1,13 @@ { "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush.schema.json", - "rushVersion": "5.140.1", - "pnpmVersion": "9.9.0", + "rushVersion": "5.169.2", + "pnpmVersion": "9.15.0", "pnpmOptions": { "strictPeerDependencies": false, "useWorkspaces": true }, "projectFolderMaxDepth": 3, - "nodeSupportedVersionRange": ">=16.14.2", + "nodeSupportedVersionRange": ">=22.0.0", "approvedPackagesPolicy": { "reviewCategories": [ "production", @@ -135,8 +135,8 @@ "shouldPublish": true }, { - "packageName": "@cfdi/curp", - "projectFolder": "packages/cfdi/curp", + "packageName": "@renapo/curp", + "projectFolder": "packages/renapo/curp", "versionPolicyName": "curp", "reviewCategory": "libraries", "shouldPublish": true, @@ -182,6 +182,32 @@ "reviewCategory": "libraries", "shouldPublish": true }, + { + "packageName": "@cfdi/estado", + "projectFolder": "packages/cfdi/estado", + "versionPolicyName": "estado", + "reviewCategory": "libraries", + "shouldPublish": true, + "tags": [ + "beta" + ] + }, + { + "packageName": "@cfdi/descarga", + "projectFolder": "packages/cfdi/descarga", + "versionPolicyName": "descarga", + "reviewCategory": "libraries", + "shouldPublish": true, + "tags": [ + "beta" + ] + }, + { + "packageName": "@sat/recursos", + "projectFolder": "packages/sat/recursos", + "reviewCategory": "libraries", + "shouldPublish": true + }, { "packageName": "@cfdi/2json", "projectFolder": "packages/cfdi/xml2json", @@ -202,6 +228,76 @@ "versionPolicyName": "elements", "reviewCategory": "libraries", "shouldPublish": true + }, + { + "packageName": "@cfdi/designs", + "projectFolder": "packages/cfdi/designs", + "versionPolicyName": "designs", + "reviewCategory": "libraries", + "shouldPublish": true + }, + { + "packageName": "@sat/auth", + "projectFolder": "packages/sat/auth", + "versionPolicyName": "auth", + "reviewCategory": "libraries", + "shouldPublish": true, + "tags": [ + "beta" + ] + }, + { + "packageName": "@cfdi/validador", + "projectFolder": "packages/cfdi/validador", + "versionPolicyName": "validador", + "reviewCategory": "libraries", + "shouldPublish": true, + "tags": [ + "beta" + ] + }, + { + "packageName": "@cfdi/cleaner", + "projectFolder": "packages/cfdi/cleaner", + "reviewCategory": "libraries", + "shouldPublish": true + }, + { + "packageName": "@cfdi/cancelacion", + "projectFolder": "packages/cfdi/cancelacion", + "reviewCategory": "libraries", + "shouldPublish": true + }, + { + "packageName": "@sat/scraper", + "projectFolder": "packages/sat/scraper", + "reviewCategory": "libraries", + "shouldPublish": true + }, + { + "packageName": "@sat/opinion", + "projectFolder": "packages/sat/opinion", + "reviewCategory": "libraries", + "shouldPublish": true + }, + { + "packageName": "@sat/contabilidad", + "projectFolder": "packages/sat/contabilidad", + "reviewCategory": "libraries", + "shouldPublish": true + }, + { + "packageName": "@sat/captcha", + "projectFolder": "packages/sat/captcha", + "reviewCategory": "libraries", + "shouldPublish": true + }, + { + "packageName": "server", + "projectFolder": "packages/server", + "reviewCategory": "private", + "shouldPublish": false, + "skipRushCheck": true } ] } \ No newline at end of file diff --git a/scripts/download-xml-examples.sh b/scripts/download-xml-examples.sh new file mode 100755 index 00000000..ebf642fb --- /dev/null +++ b/scripts/download-xml-examples.sh @@ -0,0 +1,143 @@ +#!/bin/bash +# Download CFDI XML examples from GitHub repositories +# Classifies automatically by version (3.3 vs 4.0) based on namespace +# Usage: bash scripts/download-xml-examples.sh + +set -e + +DEST="packages/files/xml/examples" +TMP_DIR=$(mktemp -d) +trap "rm -rf $TMP_DIR" EXIT + +mkdir -p "$DEST/cfdi33" "$DEST/cfdi40" + +echo "Downloading CFDI XML examples..." +echo "" + +# ─── Download all XMLs to temp ────────────────────────────── + +URLS=( + # ── eclipxe13/CfdiUtils ── + "https://raw.githubusercontent.com/eclipxe13/CfdiUtils/master/tests/assets/cfdi40-real.xml" + "https://raw.githubusercontent.com/eclipxe13/CfdiUtils/master/tests/assets/cfdi40-valid.xml" + "https://raw.githubusercontent.com/eclipxe13/CfdiUtils/master/tests/assets/created-cfdi40-pago20-valid.xml" + "https://raw.githubusercontent.com/eclipxe13/CfdiUtils/master/tests/assets/cfdi33-real.xml" + "https://raw.githubusercontent.com/eclipxe13/CfdiUtils/master/tests/assets/cfdi33-valid.xml" + + # ── invopop/gobl.cfdi (CFDI 4.0 variados) ── + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-b2b-bare.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-b2b-full.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-b2c.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-b2c-inc.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-b2c-inc-disc.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-b2c-third-party.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-export.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-export-notax.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-global.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-ieps.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-ieps-2.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-multi-currency.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-timbre.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/credit-note.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/parse/in/invoice-b2b-full-round.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/convert/out/food-vouchers.xml" + "https://raw.githubusercontent.com/invopop/gobl.cfdi/main/test/data/convert/out/fuel-account-balance.xml" + + # ── nodecfdi/cfdi-validator (pagos, descuentos) ── + "https://raw.githubusercontent.com/nodecfdi/cfdi-validator/main/tests/_files/cfdi40-real.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-validator/main/tests/_files/cfdi40-valid.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-validator/main/tests/_files/created-with-discounts-40.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-validator/main/tests/_files/created-with-discounts-33.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-validator/main/tests/_files/created-pago-with-ns-at-root-33.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-validator/main/tests/_files/cfdi33-real.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-validator/main/tests/_files/cfdi33-valid.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-validator/main/tests/_files/pagos10/sample-factura123.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-validator/main/tests/_files/pagos10/sample-facturador01.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-validator/main/tests/_files/pagos10/sample-validacfd01.xml" + + # ── nodecfdi/cfdi-expresiones ── + "https://raw.githubusercontent.com/nodecfdi/cfdi-expresiones/main/tests/_files/cfdi40-real.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-expresiones/main/tests/_files/cfdi33-real.xml" + + # ── nodecfdi/cfdi-to-json ── + "https://raw.githubusercontent.com/nodecfdi/cfdi-to-json/main/tests/_files/cfdi-example.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-to-json/main/tests/_files/detallista-example.xml" + + # ── nodecfdi/cfdi-to-pdf ── + "https://raw.githubusercontent.com/nodecfdi/cfdi-to-pdf/main/tests/_files/cfdi33-valid.xml" + "https://raw.githubusercontent.com/nodecfdi/cfdi-to-pdf/main/tests/_files/cfdi33-payment-valid.xml" + + # ── nodecfdi/cfdi-core ── + "https://raw.githubusercontent.com/nodecfdi/cfdi-core/main/tests/_files/cfdi33.xml" + + # ── eclipxe13/buzoncfdi-cfdireader (CFDI 3.3 con timbre) ── + "https://raw.githubusercontent.com/eclipxe13/buzoncfdi-cfdireader/master/tests/assets/v33/valid.xml" + "https://raw.githubusercontent.com/eclipxe13/buzoncfdi-cfdireader/master/tests/assets/v33/valid-without-timbre.xml" + + # ── nodecfdi/sat-ws-descarga-masiva ── + "https://raw.githubusercontent.com/nodecfdi/sat-ws-descarga-masiva/main/tests/_files/zip/cfdi.xml" +) + +COUNTER=0 +for url in "${URLS[@]}"; do + filename=$(basename "$url") + # Create unique name: repo-path-filename + repo=$(echo "$url" | sed -E 's|https://raw.githubusercontent.com/[^/]+/([^/]+)/.*|\1|') + # For files in subdirs, include parent dir + parent=$(echo "$url" | sed -E 's|.*/([^/]+)/[^/]+\.xml$|\1|') + if [ "$parent" = "_files" ] || [ "$parent" = "assets" ] || [ "$parent" = "in" ] || [ "$parent" = "out" ]; then + parent="" + fi + dest_name="${repo}${parent:+-$parent}-${filename}" + + if curl -sfL "$url" -o "$TMP_DIR/$dest_name" 2>/dev/null; then + COUNTER=$((COUNTER + 1)) + echo " ✔ $dest_name" + else + echo " ✗ $dest_name (failed)" + fi +done + +echo "" +echo "Downloaded $COUNTER files. Classifying by version..." +echo "" + +# ─── Classify by CFDI version (namespace-based) ───────────── + +COUNT_40=0 +COUNT_33=0 + +for file in "$TMP_DIR"/*.xml; do + [ -f "$file" ] || continue + [ -s "$file" ] || continue + filename=$(basename "$file") + + if grep -q 'xmlns:cfdi="http://www.sat.gob.mx/cfd/4"' "$file" 2>/dev/null || \ + grep -q "xmlns:cfdi='http://www.sat.gob.mx/cfd/4'" "$file" 2>/dev/null || \ + grep -q 'xmlns="http://www.sat.gob.mx/cfd/4"' "$file" 2>/dev/null; then + cp "$file" "$DEST/cfdi40/$filename" + echo " 4.0 → $filename" + COUNT_40=$((COUNT_40 + 1)) + elif grep -q 'xmlns:cfdi="http://www.sat.gob.mx/cfd/3"' "$file" 2>/dev/null || \ + grep -q "xmlns:cfdi='http://www.sat.gob.mx/cfd/3'" "$file" 2>/dev/null || \ + grep -q 'xmlns="http://www.sat.gob.mx/cfd/3"' "$file" 2>/dev/null; then + cp "$file" "$DEST/cfdi33/$filename" + echo " 3.3 → $filename" + COUNT_33=$((COUNT_33 + 1)) + else + echo " --- → $filename (not CFDI, skipped)" + fi +done + +# ─── Summary ──────────────────────────────────────────────── + +echo "" +echo "=== CFDI 4.0 ($COUNT_40 files) ===" +ls -1 "$DEST/cfdi40/" 2>/dev/null || echo "(empty)" + +echo "" +echo "=== CFDI 3.3 ($COUNT_33 files) ===" +ls -1 "$DEST/cfdi33/" 2>/dev/null || echo "(empty)" + +echo "" +echo "Total: $COUNT_40 CFDI 4.0 + $COUNT_33 CFDI 3.3 = $((COUNT_40 + COUNT_33)) files in $DEST"