diff --git a/.env.example b/.env.example index 369c173..f288e72 100644 --- a/.env.example +++ b/.env.example @@ -55,3 +55,8 @@ VITE_SUPABASE_ANON_KEY="TU_SUPABASE_ANON_KEY" # Usuario temporal solo si VITE_ENABLE_SUPABASE_AUTH="false". VITE_OPERATOR_NAME="Isaac Aracena" VITE_OPERATOR_EMAIL="iaracena@gomezleemarketing.com" + +# República Dominicana: cruce, históricos y resolución. +VITE_N8N_REPUBLICA_DOMINICANA_WEBHOOK_URL="https://agenteit.digitalcompass.agency/webhook/nominard-bamboo-test" +VITE_HISTORICOS_RD_URL="https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-rd-historicos" +VITE_MARCAR_RESUELTO_RD_URL="https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-rd-marcar-resuelto" diff --git a/IMPLEMENTACION_REPUBLICA_DOMINICANA_READY.md b/IMPLEMENTACION_REPUBLICA_DOMINICANA_READY.md new file mode 100644 index 0000000..19a9bb2 --- /dev/null +++ b/IMPLEMENTACION_REPUBLICA_DOMINICANA_READY.md @@ -0,0 +1,182 @@ +# Cruce de Cuentas GLM — República Dominicana (RD) + +## Objetivo + +Dejar República Dominicana integrada al Portal de Cruce de Cuentas con una lógica reutilizable cada quincena, todos los meses y años, usando la misma arquitectura multi-país ya existente. + +Configuración RD: + +- Código: `RD` +- Moneda: `DOP` +- Locale: `es-DO` +- Zona horaria: `America/Santo_Domingo` +- RRHH destinataria de reportes: **Noralmy Laureano** — `nlaureano@gomezleemarketing.com` +- Bandera: `https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_the_Dominican_Republic.svg.webp` + +## Archivos incluidos + +### n8n + +Importar desde `workflows_n8n/`: + +1. `Portal de Verificación de Nómina - República Dominicana.json` +2. `Portal de Verificación de Nómina República Dominicana - Históricos.json` +3. `Portal de Verificación de Nómina República Dominicana - Envío de Reporte.json` +4. `Portal de Verificación de Nómina - Analizar Nómina con Gemini GT TT PA SV HN PR RD.json` +5. `Portal de Verificación de Nómina - Reportar corrección BambooHR a RRHH - GT TT PA SV HN PR RD.json` + +Los workflows se entregan **inactivos** para que puedan importarse/configurarse sin disparar una ejecución accidental. Los dos workflows compartidos (Gemini y correcciones BambooHR) sustituyen las versiones equivalentes sin RD una vez validados. + +### Supabase + +Ejecutar: + +`SUPABASE_Republica_Dominicana_READY.sql` + +Este script habilita `RD` en las restricciones multi-país, accesos, alias BambooHR e históricos/RPC existentes. La tabla `cruces_cuentas_gt_reportes` conserva su nombre legado, pero funciona como tabla multi-país. + +## Webhooks RD + +- Cruce principal: `/webhook/nominard-bamboo-test` +- Históricos: `/webhook/cruce-cuentas-rd-historicos` +- Marcar resuelto: `/webhook/cruce-cuentas-rd-marcar-resuelto` +- Analizar nómina con Gemini: webhook compartido `/webhook/cruce-cuentas-analizar-nomina` +- Reportar corrección BambooHR: webhook compartido `/webhook/cruce-cuentas-bamboo-correccion` + +La app ya contiene las variables `VITE_N8N_REPUBLICA_DOMINICANA_WEBHOOK_URL`, `VITE_HISTORICOS_RD_URL` y `VITE_MARCAR_RESUELTO_RD_URL`. + +## Entrada esperada cada quincena + +### Nómina + +RD requiere **exactamente un Excel de nómina** (`.xlsx`, `.xls` o `.xlsm`) por período. El flujo valida que el archivo tenga filas de empleados cuyo campo `PERÍODO` corresponda al rango seleccionado en la app; si detecta empleados de otro período, se detiene para evitar cruzar una nómina equivocada. + +Hojas operativas observadas y soportadas tras analizar las 16 nóminas de enero a agosto de 2026: + +- `GLM RD ` +- `Whirlpool` +- `Bice` +- `P&G` +- `KRAFT` +- `Motorola` +- `PMI` +- `Caribe` +- `Latam ` +- `Purina` +- `Claro` +- `Essity` + +Se excluyen hojas auxiliares como `Resumen`, `Validacion TSS`, `Validacion ISR`, `ISR`, `Calculo Horas extras`, `NVScriptsProperties`, AutoCrat, copias auxiliares como `Copia de Latam ` y hojas genéricas que no forman parte de la nómina operativa. + +Campos utilizados: nombre, cuenta, `NETO A PAGAR`, `PERÍODO` y, cuando existen, cédula, referencia y correo. + +### Banco + +Se aceptan **uno o varios archivos CSV y/o PDF** de la misma quincena. Esto es indispensable en RD porque una quincena puede incluir lotes normales, temporales, suplementos y ACH separados. + +El parser CSV soporta los formatos observados en 2026 y nombres de archivos como: + +- BICE +- CLARO +- GLM +- Kraft +- LATAM +- Motorola +- P&G +- PMI +- Purina +- Temp Purina +- Temp Moto +- Whirlpool +- Essity / Temp Essity +- Bono BICE / Bono BICE inactivos + +También admite sufijos de lote como `.1.csv` y normaliza el texto `N#U00f3minas` que aparece en algunos nombres exportados. + +Los PDF BHD se interpretan como ACH complementarios. El flujo extrae beneficiario, cuenta, fecha efectiva, monto, estado, motivo, número de instrucción y descripción. La fecha de cada CSV/PDF se valida contra el período seleccionado. + +## Reglas de conciliación RD + +La lógica final está construida a partir de los cuatro reportes de entrenamiento de junio/julio 2026. + +1. Se normalizan cuentas eliminando formato visual/ceros iniciales solo para comparación; el valor visible se conserva cuando corresponde. +2. La prioridad de match es **cuenta + monto**. +3. Cuando nómina no trae cuenta, se permite match por **nombre fuerte + monto**, evitando forzar coincidencias ambiguas. +4. Se usa tolerancia monetaria de **RD$0.05 por transacción**. +5. Un pago rechazado se conserva como hallazgo y puede explicar una discrepancia Nómina > Banco. +6. Antes de clasificar `Banco sin Nómina`, se hace una segunda búsqueda para detectar una **posible cuenta mal digitada** usando nombre/referencia/correo + monto. +7. Los suplementos `Bono BICE` se integran como pago esperado adicional para que formen parte del total de nómina de conciliación, igual que en el reporte patrón de 15-jun-2026. +8. `Banco sin Bamboo` es una revisión paralela y **no se suma a `Pendientes cruce principal`**, tal como muestran los reportes oficiales de entrenamiento. +9. Las diferencias de nombre bancario se mantienen como `Pendiente revisión`; no se fuerzan como identidad confirmada. +10. Diferencias agregadas insignificantes de centavos no generan una discrepancia si todas las transacciones individuales conciliaron dentro de tolerancia. +11. Las transacciones bancarias duplicadas exactas entre dos archivos/lotes provocan error para evitar doble contabilización. + +## BambooHR + +La consulta usa: + +`/api/v1/reports/custom?format=JSON&onlyCurrent=false` + +Esto permite validar también empleados históricos que pudieron participar en una quincena anterior. El filtro RD reconoce país/localización como `RD`, `República Dominicana`, `Dominican Republic` y variantes de localización dominicana. + +El flujo usa Employee Number cuando está disponible y trabaja con alias de nombres. Las correcciones manuales confirmadas pueden persistirse en Supabase mediante el workflow compartido de correcciones. + +## Reporte de salida + +El Google Sheet conserva siempre las seis pestañas patrón de RD: + +1. `01 Nómina vs Banco` +2. `02 Banco sin Nómina` +3. `03 Banco sin Bamboo` +4. `04 Diferencias nombre banco` +5. `05 Cuenta Mal Digitada` +6. `06 Resumen` + +La pestaña 05 se crea incluso cuando no existen casos, para que el formato sea estable entre quincenas. + +Las hojas se protegen para preservar datos calculados. La columna `Resolución` queda reservada para RRHH/administración autorizada; Noralmy Laureano está incluida entre las personas autorizadas para RD. El reporte también se comparte automáticamente con los accesos internos configurados. + +## Correo RD + +El correo automático del reporte generado se envía a: + +`nlaureano@gomezleemarketing.com` + +Utiliza branding GLM, bandera RD y muestra los indicadores relevantes del cruce. El workflow de `Marcar resuelto` también está adaptado a RD y utiliza la zona horaria de Santo Domingo. + +## Históricos + +Los históricos se guardan con `country = RD` y una identidad de período del tipo: + +`RD-2026-06-quincena_15` + +Si se vuelve a procesar el mismo período, la arquitectura reutiliza/actualiza el reporte existente y conserva resoluciones compatibles en lugar de crear duplicados innecesarios. + +## Detección automática de período + +Se actualizó el analizador compartido Gemini y el detector local de la app. Para RD se reconocen: + +- día 15 → `quincena_15` +- día 30/31 → `quincena_30` +- último día real del mes → `quincena_30` (por ejemplo, 28/29 de febrero) + +Se validaron correctamente los 16 nombres reales de nómina de enero a agosto de 2026. + +## Orden de despliegue recomendado + +1. Hacer respaldo de los workflows actualmente publicados. +2. Ejecutar `SUPABASE_Republica_Dominicana_READY.sql`. +3. Importar el workflow principal RD. +4. Importar Históricos RD. +5. Importar Envío de Reporte RD. +6. Reemplazar/actualizar el analizador compartido por la versión `... PR RD`. +7. Reemplazar/actualizar el workflow de correcciones BambooHR por la versión `... PR RD`. +8. Confirmar que las credenciales de BambooHR, Google Sheets/Drive y Gmail quedaron asociadas tras la importación. +9. Desplegar el frontend desde el código fuente actualizado (`npm ci && npm run build`). +10. Activar los cinco workflows una vez revisados los paths de webhook. +11. Ejecutar una prueba controlada con una de las cuatro quincenas conocidas y comparar con `VALIDACION_REPUBLICA_DOMINICANA_FINAL.md`. +12. Ejecutar después una quincena nueva/no entrenada antes de declararlo operación mensual definitiva. + +## Nota de despliegue frontend + +El `dist` heredado del ZIP original no debe usarse porque fue generado antes de incorporar RD. El entregable final de RD se prepara sin ese `dist` antiguo; el servidor de despliegue debe instalar dependencias y generar un `dist` nuevo desde el código fuente actualizado. diff --git a/Portal de Verificaci├│n de N├│mina - Puerto Rico.json b/Portal de Verificaci├│n de N├│mina - Puerto Rico.json index c0d421a..42a8a0e 100644 --- a/Portal de Verificaci├│n de N├│mina - Puerto Rico.json +++ b/Portal de Verificaci├│n de N├│mina - Puerto Rico.json @@ -11,10 +11,10 @@ "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ - -2800, - 5200 + -1088, + 512 ], - "id": "e07fef4a-5007-452d-b75e-975757344c59", + "id": "cce6050e-e39e-4f9b-8af2-c1b7a2f756ad", "name": "Webhook", "webhookId": "00132835-9daf-4f36-95ee-233ff6f7b691" }, @@ -25,10 +25,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -2560, - 5200 + -848, + 512 ], - "id": "1753550c-cf8b-48eb-ba58-0a8642163242", + "id": "0b3dff96-467b-4a56-8da0-e93ae51f4c44", "name": "Preparar entrada app" }, { @@ -38,10 +38,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -2080, - 4960 + -368, + 272 ], - "id": "eba2da3b-8ca3-49bd-9679-a61a1270c8f8", + "id": "af3c16fb-60a1-4f0f-a604-bf33ee3c7ac8", "name": "Preparar PDF banco PR" }, { @@ -51,10 +51,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -2080, - 5440 + -368, + 752 ], - "id": "2b1028fb-bee3-4b82-bb5c-78c534959b20", + "id": "5e49fc7d-692e-467f-9618-509f13a8674e", "name": "Preparar archivos nómina PR" }, { @@ -69,10 +69,10 @@ "type": "n8n-nodes-base.extractFromFile", "typeVersion": 1.1, "position": [ - -1840, - 5440 + -128, + 752 ], - "id": "ec028b3b-a794-462a-a33b-afb839928069", + "id": "f52d1ad9-6b32-4ea3-891b-2a16f804c4c9", "name": "Extract - Archivo Nómina PR", "retryOnFail": false, "onError": "continueRegularOutput" @@ -84,10 +84,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -1600, - 5440 + 112, + 752 ], - "id": "1e1a261f-8711-49db-9640-aa64f3540fdd", + "id": "b74e9e31-da6e-4eca-a620-ec70c92b1fa3", "name": "Normalizar Nómina PR" }, { @@ -99,10 +99,10 @@ "type": "n8n-nodes-base.merge", "typeVersion": 3.2, "position": [ - -1320, - 5200 + 400, + 512 ], - "id": "349328dc-e99b-499a-b79b-bbf62918ba68", + "id": "6ddf574c-188e-40a3-b657-8a415114d2b0", "name": "Merge Banco + Nómina PR" }, { @@ -156,10 +156,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - -1080, - 5040 + 640, + 352 ], - "id": "396dcc5d-eb94-4f6d-a234-9adaa99baa7b", + "id": "a0035219-8292-4154-b840-8fcf8d8b32d4", "name": "HTTP - Empleados BambooHR PR", "retryOnFail": true, "maxTries": 3, @@ -178,10 +178,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -840, - 5040 + 880, + 352 ], - "id": "c9609568-0db8-42c7-8629-601841c2c3d7", + "id": "ed8d309b-9742-4eba-a0c4-6b3fbe77c9cd", "name": "Normalizar BambooHR PR" }, { @@ -193,10 +193,10 @@ "type": "n8n-nodes-base.merge", "typeVersion": 3.2, "position": [ - -600, - 5200 + 1120, + 512 ], - "id": "0d44d9e2-bf49-400c-873c-c9adb8bcbbd3", + "id": "17f7daaa-1093-4885-86e8-071ba9bdc366", "name": "Merge - Agregar BambooHR PR" }, { @@ -241,10 +241,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - -360, - 5200 + 1360, + 512 ], - "id": "b8e487d1-2745-4fce-a4ae-00a1ceb44bab", + "id": "f0d44f40-cf96-4385-b4f3-4220af926fbd", "name": "Obtener alias BambooHR Supabase", "retryOnFail": true, "maxTries": 2, @@ -253,15 +253,15 @@ }, { "parameters": { - "jsCode": "const data = $('Merge - Agregar BambooHR PR').first().json || {};\nconst aliasResponse = $input.first().json || {};\nconst validatedBambooAliases = Array.isArray(aliasResponse.aliases)\n ? aliasResponse.aliases\n : Array.isArray(aliasResponse)\n ? aliasResponse\n : [];\n\nfunction clean(value) {\n return String(value ?? '')\n .replace(/\\uFEFF/g, '')\n .replace(/\\u00A0/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst normalizedNameCache = new Map();\nconst nameWordsCache = new Map();\nconst nameMatchScoreCache = new Map();\n\nfunction normalizeName(value) {\n const raw = clean(value);\n if (normalizedNameCache.has(raw)) {\n return normalizedNameCache.get(raw);\n }\n\n const normalized = raw\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/['’`-]/g, ' ')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n\n normalizedNameCache.set(raw, normalized);\n return normalized;\n}\n\nfunction normalizeAccount(value) {\n return String(value ?? '').replace(/\\.0$/g, '').replace(/\\D/g, '').trim();\n}\n\nfunction normalizeEmployeeNumber(value) {\n return String(value ?? '')\n .replace(/\\u00A0/g, '')\n .replace(/\\D/g, '')\n .trim();\n}\n\nfunction roundMoney(value) {\n return Math.round((Number(value) || 0) * 100) / 100;\n}\n\nfunction moneyDiff(payroll, bank) {\n return roundMoney((Number(payroll) || 0) - (Number(bank) || 0));\n}\n\nconst MONEY_TOLERANCE = 0.01;\nconst MONEY_TOLERANCE_CENTS = Math.round(MONEY_TOLERANCE * 100);\n\nfunction sameCent(a, b) {\n return Math.abs(moneyDiff(a, b)) <= MONEY_TOLERANCE + 1e-9;\n}\n\nconst IGNORED_NAME_TOKENS = new Set([\n 'de', 'del', 'la', 'las', 'los', 'y', 'e', 'el',\n 'da', 'do', 'dos', 'das', 'van', 'von',\n]);\n\nfunction nameWords(value) {\n const normalized = normalizeName(value);\n if (nameWordsCache.has(normalized)) {\n return nameWordsCache.get(normalized);\n }\n\n const words = normalized\n .split(' ')\n .filter((word) => word.length > 1 && !IGNORED_NAME_TOKENS.has(word));\n\n nameWordsCache.set(normalized, words);\n return words;\n}\n\nfunction editDistance(a, b) {\n if (a === b) return 0;\n if (!a) return b.length;\n if (!b) return a.length;\n let previous = Array.from({ length: b.length + 1 }, (_, index) => index);\n for (let i = 1; i <= a.length; i++) {\n const current = [i];\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n current[j] = Math.min(current[j - 1] + 1, previous[j] + 1, previous[j - 1] + cost);\n }\n previous = current;\n }\n return previous[b.length];\n}\n\nfunction tokenMatches(a, b) {\n if (a === b) return true;\n const minLength = Math.min(a.length, b.length);\n if (minLength >= 8 && editDistance(a, b) <= 2) return true;\n if (minLength >= 5 && editDistance(a, b) <= 1) return true;\n return false;\n}\n\nfunction samePersonName(a, b) {\n const normalizedA = normalizeName(a);\n const normalizedB = normalizeName(b);\n if (!normalizedA || !normalizedB) return false;\n if (normalizedA === normalizedB) return true;\n\n const wordsA = nameWords(a);\n const wordsB = nameWords(b);\n if (!wordsA.length || !wordsB.length) return false;\n\n const usedB = new Set();\n let matches = 0;\n for (const wordA of wordsA) {\n const matchIndex = wordsB.findIndex((wordB, index) =>\n !usedB.has(index) && tokenMatches(wordA, wordB)\n );\n if (matchIndex >= 0) {\n usedB.add(matchIndex);\n matches += 1;\n }\n }\n\n const smallerLength = Math.min(wordsA.length, wordsB.length);\n const ratio = matches / smallerLength;\n if (smallerLength <= 2) return matches === smallerLength && matches >= 2;\n return matches >= 2 && ratio >= 0.6;\n}\n\nfunction bankNameLooksConsistent(fileName, holderName) {\n const fileWords = nameWords(fileName);\n const holderWords = nameWords(holderName);\n\n if (!fileWords.length || !holderWords.length) return true;\n\n const used = new Set();\n\n for (const fileWord of fileWords) {\n let matchIndex = holderWords.findIndex(\n (holderWord, index) =>\n !used.has(index) &&\n holderWord === fileWord\n );\n\n // Algunos planos de Puerto Rico recortan el último carácter del apellido\n // por longitud de campo (ej.: ALVARAD -> ALVARADO). Eso no debe\n // convertirse en una diferencia de nombre. No se aceptan sustituciones\n // ortográficas (ej.: GONZALES -> GONZALEZ), porque sí requieren revisión.\n if (matchIndex < 0) {\n matchIndex = holderWords.findIndex(\n (holderWord, index) =>\n !used.has(index) &&\n holderWord.startsWith(fileWord) &&\n (\n (fileWord.length <= 3) ||\n (\n fileWord.length >= 4 &&\n holderWord.length === fileWord.length + 1\n )\n )\n );\n }\n\n if (matchIndex < 0) return false;\n used.add(matchIndex);\n }\n\n return true;\n}\n\nfunction nameMatchScore(a, b) {\n const na = normalizeName(a);\n const nb = normalizeName(b);\n if (!na || !nb) return 0;\n\n const cacheKey = na <= nb ? `${na}\\u0000${nb}` : `${nb}\\u0000${na}`;\n if (nameMatchScoreCache.has(cacheKey)) {\n return nameMatchScoreCache.get(cacheKey);\n }\n\n if (na === nb) {\n nameMatchScoreCache.set(cacheKey, 1);\n return 1;\n }\n\n const wa = nameWords(a);\n const wb = nameWords(b);\n if (!samePersonName(a, b)) {\n nameMatchScoreCache.set(cacheKey, 0);\n return 0;\n }\n\n const setA = new Set(wa);\n const setB = new Set(wb);\n let exact = 0;\n for (const w of setA) if (setB.has(w)) exact += 1;\n const min = Math.max(1, Math.min(setA.size, setB.size));\n const score = Math.min(\n 0.99,\n 0.75 + (exact / min) * 0.20 + (wa.length === wb.length ? 0.04 : 0)\n );\n\n nameMatchScoreCache.set(cacheKey, score);\n return score;\n}\n\nfunction bankNames(row) {\n return [row.bank_name_file, row.bank_account_holder]\n .map(clean)\n .filter(Boolean);\n}\n\nfunction bestNameScore(payrollName, bankRow) {\n return Math.max(0, ...bankNames(bankRow).map((name) => nameMatchScore(payrollName, name)));\n}\n\nfunction bankDisplayName(row) {\n return clean(row.bank_name_file) || clean(row.bank_account_holder) || 'Pago bancario';\n}\n\nfunction bankRowKey(row, index) {\n return clean(row.bank_row_key) || `${clean(row.source_file)}|${row.row_number || index + 1}`;\n}\n\n\nconst metadata = data.metadata || {};\n\nfunction parseBankDate(value, sourceFile = '') {\n const raw = clean(value);\n let match = raw.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})/);\n if (match) {\n return {\n year: Number(match[3]),\n month: Number(match[2]),\n day: Number(match[1]),\n };\n }\n\n match = raw.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})/);\n if (match) {\n return {\n year: Number(match[1]),\n month: Number(match[2]),\n day: Number(match[3]),\n };\n }\n\n // Respaldo por el patrón habitual del nombre: _DDMMYY / _DDMMYYYY.\n const fileMatch = clean(sourceFile).match(/_(\\d{2})(\\d{2})(\\d{2}|\\d{4})(?:\\D|$)/);\n if (!fileMatch) return null;\n\n const yearPart = Number(fileMatch[3]);\n return {\n year: fileMatch[3].length === 2 ? 2000 + yearPart : yearPart,\n month: Number(fileMatch[2]),\n day: Number(fileMatch[1]),\n };\n}\n\nfunction selectedPeriodKind() {\n const type = clean(metadata.period_type).toLowerCase();\n if (type === 'quincena_15') return 'q15';\n if (type === 'quincena_30') return 'q30';\n return 'unknown';\n}\n\nfunction conceptPeriodHint(row) {\n const concept = normalizeName(row.concept || '');\n if (!concept) return 'unknown';\n\n if (\n /(?:^| )1(?:ra|er|era)? quincena(?: |$)/.test(concept) ||\n concept.includes('primera quincena') ||\n concept.includes('quincena 1ra') ||\n concept.includes('quincena 1')\n ) {\n return 'q15';\n }\n\n if (\n /(?:^| )2(?:da|do|nda)? quincena(?: |$)/.test(concept) ||\n concept.includes('segunda quincena') ||\n concept.includes('quincena 2da') ||\n concept.includes('quincena 2') ||\n concept.includes('fin de mes')\n ) {\n return 'q30';\n }\n\n return 'unknown';\n}\n\nfunction periodInfoForBankRow(row) {\n const selected = selectedPeriodKind();\n const rowDate = parseBankDate(row.application_date, row.source_file);\n const selectedYear = Number(metadata.year || 0);\n const selectedMonth = Number(metadata.month || 0);\n const hint = conceptPeriodHint(row);\n\n if (selected === 'unknown') {\n return { known: false, selected, inPeriod: true, affinity: 1, rowDate, hint };\n }\n\n if (hint !== 'unknown' && hint === selected) {\n return { known: true, selected, inPeriod: true, affinity: 4, rowDate, hint };\n }\n\n if (!rowDate || !selectedYear || !selectedMonth) {\n return { known: false, selected, inPeriod: true, affinity: 1, rowDate, hint };\n }\n\n if (rowDate.year !== selectedYear || rowDate.month !== selectedMonth) {\n return { known: true, selected, inPeriod: false, affinity: 0, rowDate, hint };\n }\n\n const inHalf = selected === 'q15'\n ? rowDate.day <= 15\n : rowDate.day >= 16;\n\n return {\n known: true,\n selected,\n inPeriod: inHalf,\n affinity: inHalf ? 3 : 0,\n rowDate,\n hint,\n };\n}\n\nfunction isSupplementPayroll(payroll) {\n return clean(payroll?.source_kind).toLowerCase() !== 'quincenal';\n}\n\nfunction bankCandidatePeriodScore(payroll, bank) {\n const info = periodInfoForBankRow(bank);\n if (!info.known || info.inPeriod) return info.affinity || 1;\n\n // Una extraordinaria/vacación/XIII Mes puede pagarse fuera de la mitad\n // estricta del mes. Se permite como respaldo, siempre detrás de cualquier\n // candidato del período seleccionado.\n if (isSupplementPayroll(payroll) && info.rowDate) {\n const selectedYear = Number(metadata.year || 0);\n const selectedMonth = Number(metadata.month || 0);\n if (info.rowDate.year === selectedYear && info.rowDate.month === selectedMonth) {\n return 0.5;\n }\n }\n\n return -1;\n}\n\nconst payrollRows = Array.isArray(data.payroll?.rows) ? data.payroll.rows : [];\nconst bankRows = Array.isArray(data.bank?.rows) ? data.bank.rows : [];\n\n// Guardia de seguridad: nunca generar un reporte \"válido\" cuando el request\n// traía archivos pero el parser no consiguió ninguna fila. Esto evita que\n// todas las personas de nómina aparezcan falsamente como discrepancias.\nif (payrollRows.length === 0) {\n throw new Error(\n 'Puerto Rico: no se pudo leer ninguna fila válida de nómina. ' +\n 'Revisa los archivo Excel de Puerto Rico y las hojas Whirlpool, Personal 2 y Personal 3.'\n );\n}\n\nif (bankRows.length === 0) {\n const detectedFiles = Number(data.bank?.files_count || data.summary?.bank_files_count || 0);\n const invalidFiles = Array.isArray(data.bank?.file_summaries)\n ? data.bank.file_summaries.filter((file) => file?.ok === false)\n : [];\n\n throw new Error(\n 'Puerto Rico: no se pudo leer ninguna transacción bancaria. ' +\n `Archivos bancarios detectados: ${detectedFiles}. ` +\n (invalidFiles.length\n ? `Archivos con error de formato: ${invalidFiles.map((file) => file.file_name).join(', ')}.`\n : 'Verifica que el PDF sea el Transaction Detail Report de Banco Popular de Puerto Rico.')\n );\n}\n\nconst bambooEmployees = Array.isArray(data.bamboo?.employees) ? data.bamboo.employees : [];\nconst resolvedNameMatches = data.bamboo?.resolved_name_matches || {};\nconst bambooValidationAvailable = data.bamboo?.fetch_complete === true &&\n data.bamboo?.validation_available === true && bambooEmployees.length > 0;\n\nconst bambooByEmployeeNumber = new Map();\nconst bambooById = new Map();\nconst bambooByExactName = new Map();\nfor (const employee of bambooEmployees) {\n const number = normalizeEmployeeNumber(\n employee.employee_number || employee.employeeNumber\n );\n const id = clean(employee.bamboo_id || employee.id);\n if (number) {\n const arr = bambooByEmployeeNumber.get(number) || [];\n arr.push(employee);\n bambooByEmployeeNumber.set(number, arr);\n }\n if (id) bambooById.set(id, employee);\n for (const alias of employee.aliases || [employee.full_name]) {\n const normalized = normalizeName(alias);\n if (!normalized) continue;\n const arr = bambooByExactName.get(normalized) || [];\n arr.push(employee);\n bambooByExactName.set(normalized, arr);\n }\n}\n\nfunction employeeKey(employee) {\n return clean(employee?.bamboo_id || employee?.id) ||\n clean(employee?.employee_number || employee?.employeeNumber) ||\n normalizeName(employee?.full_name || employee?.displayName);\n}\n\nfunction validatedAliasDecision(row) {\n if (!validatedBambooAliases.length) return null;\n const rowAccount = normalizeAccount(row.account);\n const names = bankNames(row).map(normalizeName).filter(Boolean);\n const candidates = validatedBambooAliases.filter((alias) => {\n const country = clean(alias.pais || alias.country).toUpperCase();\n if (country && country !== 'PR') return false;\n const source = normalizeName(alias.nombre_origen || alias.source_name || alias.alias || '');\n if (!source || !names.includes(source)) return false;\n const aliasAccount = normalizeAccount(alias.cuenta_bancaria || alias.cuenta_banco || alias.bank_account || '');\n return !aliasAccount || !rowAccount || aliasAccount === rowAccount;\n });\n if (candidates.length !== 1) return null;\n const alias = candidates[0];\n let employee = null;\n const employeeNumber = normalizeEmployeeNumber(\n alias.bamboo_employee_number || ''\n );\n const bambooId = clean(alias.bamboo_employee_id || '');\n const bambooName = normalizeName(alias.bamboo_nombre || '');\n if (employeeNumber && (bambooByEmployeeNumber.get(employeeNumber) || []).length === 1) {\n employee = bambooByEmployeeNumber.get(employeeNumber)[0];\n } else if (bambooId && bambooById.has(bambooId)) {\n employee = bambooById.get(bambooId);\n } else if (bambooName && (bambooByExactName.get(bambooName) || []).length === 1) {\n employee = bambooByExactName.get(bambooName)[0];\n }\n if (!employee) return null;\n return {\n found: true,\n matched_by: 'validated_bamboo_alias',\n confidence: 1,\n employee,\n employee_key: employeeKey(employee),\n bamboo_alias: clean(alias.bamboo_nombre) || employee.full_name || '',\n };\n}\n\nfunction precomputedDecision(name) {\n const normalized = normalizeName(name);\n if (!normalized) return null;\n const decision = resolvedNameMatches[normalized];\n if (!decision || decision.found !== true) return null;\n const index = Number(decision.employee_index);\n const employee = Number.isInteger(index) && index >= 0 ? bambooEmployees[index] : null;\n const key = clean(decision.employee_key) || employeeKey(employee);\n if (!key) return null;\n return {\n found: true,\n matched_by: decision.matched_by || 'precomputed_name',\n confidence: Number(decision.confidence || 0),\n employee,\n employee_key: key,\n bamboo_alias: clean(decision.bamboo_alias) || employee?.full_name || '',\n query_name: clean(name),\n };\n}\n\nfunction resolveBamboo(\n row,\n linkedPayrollNames = [],\n linkedPayrollEmployeeNumbers = []\n) {\n if (!bambooValidationAvailable) {\n return {\n found: false,\n reason: 'validation_unavailable',\n };\n }\n\n const validated = validatedAliasDecision(row);\n if (validated) return validated;\n\n /*\n * Puerto Rico: si existe un identificador fuerte procedente de nómina se puede usar como respaldo para determinar\n * si el pago pertenece a una persona existente en BambooHR.\n *\n * Se normalizan guiones/espacios tanto en banco como en BambooHR:\n * 0611198400414 <-> 0611-1984-00414\n *\n * Como respaldo, cuando la fila bancaria ya fue conciliada con nómina,\n * también se usa el Employee Number/Identidad de esa fila de nómina.\n * Solo se acepta el identificador cuando apunta a UNA sola persona.\n */\n const referenceEmployeeNumbers = Array.from(\n new Set(\n [\n row.reference,\n row.participant_id,\n row.employee_number,\n row.employeeNumber,\n ...linkedPayrollEmployeeNumbers,\n ]\n .flatMap((value) =>\n String(value ?? '').match(/\\d{6,20}/g) || []\n )\n .map(normalizeEmployeeNumber)\n .filter((value) => value.length >= 6)\n )\n );\n\n const employeesByStrongIdentifier = new Map();\n\n for (const employeeNumber of referenceEmployeeNumbers) {\n const matches =\n bambooByEmployeeNumber.get(employeeNumber) || [];\n\n if (matches.length !== 1) continue;\n\n const employee = matches[0];\n const key = employeeKey(employee);\n\n if (key) {\n employeesByStrongIdentifier.set(\n key,\n {\n employee,\n employee_number: employeeNumber,\n }\n );\n }\n }\n\n if (employeesByStrongIdentifier.size === 1) {\n const resolved =\n employeesByStrongIdentifier.values().next().value;\n\n return {\n found: true,\n matched_by: 'bank_or_payroll_employee_number',\n confidence: 1,\n employee: resolved.employee,\n employee_key: employeeKey(resolved.employee),\n bamboo_alias:\n clean(resolved.employee.full_name) ||\n clean(resolved.employee.displayName) ||\n '',\n matched_employee_number:\n resolved.employee_number,\n };\n }\n\n const holderName = clean(row.bank_account_holder);\n const fileName = clean(row.bank_name_file);\n\n // El nombre legal del cuentahabiente es la evidencia bancaria más fuerte.\n // Si identifica exactamente a una persona que pertenecía al período,\n // prevalece sobre un nombre abreviado que pueda coincidir con un perfil\n // histórico distinto (caso real: Suyapa Palma).\n const holderDecision = holderName\n ? precomputedDecision(holderName)\n : null;\n\n const holderMatchedBy =\n clean(holderDecision?.matched_by).toLowerCase();\n\n const holderIsExactUnique =\n holderDecision?.found === true &&\n (\n holderDecision.confidence >= 0.999 ||\n holderMatchedBy.includes('exact_precomputed_name') ||\n holderMatchedBy.includes('confirmed_alias_catalog')\n );\n\n // \"Banco sin Bamboo\" valida existencia en BambooHR, no que la persona\n // siguiera activa durante toda la quincena. Un finiquito/pago final puede\n // ocurrir después de la fecha de terminación. Por eso un nombre legal\n // completo y único del cuentahabiente es suficiente evidencia.\n if (holderIsExactUnique) {\n return {\n ...holderDecision,\n matched_by:\n `${holderDecision.matched_by || 'precomputed_name'}_holder_exact`,\n };\n }\n\n if (\n holderDecision?.found &&\n holderDecision.employee?.overlaps_period === true\n ) {\n return {\n ...holderDecision,\n matched_by:\n `${holderDecision.matched_by || 'precomputed_name'}_holder_in_period`,\n };\n }\n\n const names = Array.from(\n new Set(\n [\n holderName,\n fileName,\n ...linkedPayrollNames.map(clean),\n ].filter(Boolean)\n )\n );\n\n const decisions = names\n .map(precomputedDecision)\n .filter(Boolean);\n\n if (!decisions.length) {\n return {\n found: false,\n reason: 'no_confident_name_match',\n };\n }\n\n // Antes de declarar conflicto, descartar perfiles históricos que no\n // pertenecen al período cuando existe una única persona vigente/en período.\n const inPeriodByKey = new Map();\n\n for (const decision of decisions) {\n if (decision.employee?.overlaps_period !== true) continue;\n\n const current =\n inPeriodByKey.get(decision.employee_key);\n\n if (\n !current ||\n decision.confidence > current.confidence\n ) {\n inPeriodByKey.set(\n decision.employee_key,\n decision\n );\n }\n }\n\n const inPeriodRanked =\n Array.from(inPeriodByKey.values())\n .sort(\n (left, right) =>\n right.confidence - left.confidence\n );\n\n if (inPeriodRanked.length === 1) {\n return {\n ...inPeriodRanked[0],\n matched_by:\n `${inPeriodRanked[0].matched_by || 'precomputed_name'}_unique_in_period`,\n };\n }\n\n if (\n inPeriodRanked.length >= 2 &&\n (\n inPeriodRanked[0].confidence -\n inPeriodRanked[1].confidence\n ) >= 0.08\n ) {\n return inPeriodRanked[0];\n }\n\n const byKey = new Map();\n\n for (const decision of decisions) {\n const current =\n byKey.get(decision.employee_key);\n\n if (\n !current ||\n decision.confidence > current.confidence\n ) {\n byKey.set(\n decision.employee_key,\n decision\n );\n }\n }\n\n const ranked =\n Array.from(byKey.values())\n .sort(\n (left, right) =>\n right.confidence - left.confidence\n );\n\n if (ranked.length === 1) {\n return ranked[0];\n }\n\n if (\n (\n ranked[0].confidence -\n ranked[1].confidence\n ) >= 0.08\n ) {\n return ranked[0];\n }\n\n return {\n found: false,\n reason: 'conflicting_precomputed_name_matches',\n candidates: ranked.slice(0, 3),\n };\n}\n\nconst usedBankKeys = new Set();\nconst matchedPayrollIndexes = new Set();\nconst matchedPairs = [];\nconst bankIndexByKey = new Map();\n\n// Índice por centavos para que la pasada principal no compare cada fila de\n// nómina contra todas las transacciones del banco. Esto preserva exactamente\n// la lógica original: la primera pasada ya exigía el mismo monto al centavo.\nconst bankIndexesByAmountCents = new Map();\n\nfunction amountCents(value) {\n return Math.round(roundMoney(value) * 100);\n}\n\nbankRows.forEach((row, index) => {\n const key = bankRowKey(row, index);\n bankIndexByKey.set(key, index);\n\n const amountKey = `${clean(row.currency || 'USD').toUpperCase()}|${amountCents(row.amount)}`;\n const bucket = bankIndexesByAmountCents.get(amountKey) || [];\n bucket.push(index);\n bankIndexesByAmountCents.set(amountKey, bucket);\n});\n\nfunction availableNameCandidates(payroll, requireExactAmount) {\n const candidates = [];\n\n // La pasada exacta solo inspecciona filas con el mismo importe. La segunda\n // pasada conserva el barrido completo y el mismo criterio de persona fuerte\n // + menor diferencia que tenía el workflow validado.\n let candidateIndexes = null;\n\n if (requireExactAmount) {\n const currency =\n clean(payroll.currency || 'USD')\n .toUpperCase();\n\n const center =\n amountCents(payroll.payroll_amount);\n\n const indexSet = new Set();\n\n for (\n let delta = -MONEY_TOLERANCE_CENTS;\n delta <= MONEY_TOLERANCE_CENTS;\n delta++\n ) {\n const bucket =\n bankIndexesByAmountCents.get(\n `${currency}|${center + delta}`\n ) || [];\n\n for (const bankIndex of bucket) {\n indexSet.add(bankIndex);\n }\n }\n\n candidateIndexes =\n Array.from(indexSet);\n }\n\n const inspectBank = (bankIndex) => {\n const bank = bankRows[bankIndex];\n if (!bank) return;\n\n const key = bankRowKey(bank, bankIndex);\n if (usedBankKeys.has(key)) return;\n if (clean(payroll.currency || 'USD').toUpperCase() !== clean(bank.currency || 'HNL').toUpperCase()) return;\n\n if (requireExactAmount && !sameCent(payroll.payroll_amount, bank.amount)) return;\n\n const periodScore = bankCandidatePeriodScore(payroll, bank);\n if (periodScore < 0) return;\n\n const score = bestNameScore(payroll.employee_name, bank);\n if (score <= 0) return;\n\n candidates.push({\n bank,\n bankIndex,\n key,\n score,\n periodScore,\n amountDiff: Math.abs(moneyDiff(payroll.payroll_amount, bank.amount)),\n });\n };\n\n if (candidateIndexes) {\n for (const bankIndex of candidateIndexes) {\n inspectBank(bankIndex);\n }\n } else {\n for (let bankIndex = 0; bankIndex < bankRows.length; bankIndex++) {\n inspectBank(bankIndex);\n }\n }\n\n candidates.sort((a, b) => {\n if (b.periodScore !== a.periodScore) return b.periodScore - a.periodScore;\n if (b.score !== a.score) return b.score - a.score;\n if (a.amountDiff !== b.amountDiff) return a.amountDiff - b.amountDiff;\n return a.bankIndex - b.bankIndex;\n });\n\n return candidates;\n}\n\n// Primera pasada: persona + monto exacto. Es la evidencia más fuerte y evita\n// que extraordinarias/vacaciones de una misma persona se mezclen entre sí.\npayrollRows.forEach((payroll, payrollIndex) => {\n const candidates = availableNameCandidates(payroll, true);\n if (!candidates.length) return;\n const chosen = candidates[0];\n usedBankKeys.add(chosen.key);\n matchedPayrollIndexes.add(payrollIndex);\n matchedPairs.push({ payroll, payrollIndex, ...chosen });\n});\n\n// Segunda pasada: persona fuerte aunque el monto sea distinto. Solo se toma\n// una contraparte bancaria por fila de nómina y se prioriza la menor diferencia.\npayrollRows.forEach((payroll, payrollIndex) => {\n if (matchedPayrollIndexes.has(payrollIndex)) return;\n const candidates = availableNameCandidates(payroll, false);\n if (!candidates.length) return;\n const chosen = candidates[0];\n usedBankKeys.add(chosen.key);\n matchedPayrollIndexes.add(payrollIndex);\n matchedPairs.push({ payroll, payrollIndex, ...chosen });\n});\n\nconst linkedPayrollNamesByBankKey = new Map();\nconst linkedPayrollEmployeeNumbersByBankKey = new Map();\n\nfor (const pair of matchedPairs) {\n const currentNames =\n linkedPayrollNamesByBankKey.get(pair.key) || [];\n\n currentNames.push(pair.payroll.employee_name);\n\n linkedPayrollNamesByBankKey.set(\n pair.key,\n currentNames\n );\n\n const employeeNumber =\n normalizeEmployeeNumber(\n pair.payroll.employee_number ||\n pair.payroll.employeeNumber ||\n ''\n );\n\n if (employeeNumber) {\n const currentNumbers =\n linkedPayrollEmployeeNumbersByBankKey.get(\n pair.key\n ) || [];\n\n currentNumbers.push(employeeNumber);\n\n linkedPayrollEmployeeNumbersByBankKey.set(\n pair.key,\n currentNumbers\n );\n }\n}\n\n// Filas bancarias del período de Puerto Rico.\n// Toda fila emparejada entra siempre. Para una fila no emparejada se usa la\n// fecha/concepto del plano para evitar arrastrar accidentalmente otra quincena.\nconst includedBankRows = [];\nconst excludedBankRows = [];\n\nfor (let index = 0; index < bankRows.length; index++) {\n const row = bankRows[index];\n const key = bankRowKey(row, index);\n\n if (usedBankKeys.has(key)) {\n includedBankRows.push({ row, key, index, inclusion: 'matched_payroll' });\n continue;\n }\n\n const periodInfo = periodInfoForBankRow(row);\n if (periodInfo.known && !periodInfo.inPeriod) {\n excludedBankRows.push({ row, key, reason: 'outside_selected_payroll_period' });\n continue;\n }\n\n includedBankRows.push({ row, key, index, inclusion: 'unmatched_current_period' });\n}\n\nconst includedBankKeySet = new Set(includedBankRows.map((entry) => entry.key));\n\nconst coreRows = [];\nconst wrongAccountGroups = new Map();\nfor (const pair of matchedPairs) {\n if (!includedBankKeySet.has(pair.key)) continue;\n const payrollAmount = roundMoney(pair.payroll.payroll_amount);\n const bankAmount = roundMoney(pair.bank.amount);\n const difference = moneyDiff(payrollAmount, bankAmount);\n const currency = clean(pair.payroll.currency || pair.bank.currency || 'USD').toUpperCase() === 'USD' ? 'USD' : 'HNL';\n const payrollAccount = normalizeAccount(pair.payroll.account || pair.payroll.payroll_account);\n const bankAccount = normalizeAccount(pair.bank.account);\n const accountMismatch = Boolean(payrollAccount && bankAccount && payrollAccount !== bankAccount);\n if (accountMismatch) {\n const groupKey = `${normalizeName(pair.payroll.employee_name)}|${currency}|${payrollAccount}|${bankAccount}`;\n const current = wrongAccountGroups.get(groupKey) || {\n id: `pr_wrong_account_${wrongAccountGroups.size + 1}`,\n employee: pair.payroll.employee_name,\n employee_name: pair.payroll.employee_name,\n employeeNumber: pair.payroll.employee_number || '', employee_number: pair.payroll.employee_number || '',\n account: bankAccount, payrollAccount, payroll_account: payrollAccount, bankAccount, bank_account: bankAccount,\n currency, payrollAmount:0, payroll_amount:0, bankAmount:0, bank_amount:0, difference:0,\n status:'Pendiente revisión', category:'posible_cuenta_mal_digitada', subcategory:'nombre_y_monto_coinciden_cuenta_diferente',\n observation:`El nombre y el monto coinciden, pero la cuenta de nómina (${payrollAccount}) es diferente a la cuenta del banco (${bankAccount}).`,\n source_rows:[], source_sheets:new Set(), source_files:new Set(), shipment_numbers:new Set(), plan_numbers:new Set(),\n bank_name_file: pair.bank.bank_name_file || '', bank_account_holder: pair.bank.bank_account_holder || ''\n };\n current.payrollAmount=roundMoney(current.payrollAmount+payrollAmount); current.payroll_amount=current.payrollAmount;\n current.bankAmount=roundMoney(current.bankAmount+bankAmount); current.bank_amount=current.bankAmount; current.difference=moneyDiff(current.payrollAmount,current.bankAmount);\n current.source_rows.push(pair.payroll); if(pair.payroll.source_sheet)current.source_sheets.add(pair.payroll.source_sheet); if(pair.bank.source_file)current.source_files.add(pair.bank.source_file); if(pair.bank.shipment_number)current.shipment_numbers.add(pair.bank.shipment_number); if(pair.bank.plan_number)current.plan_numbers.add(pair.bank.plan_number);\n wrongAccountGroups.set(groupKey,current); continue;\n }\n const exact = sameCent(payrollAmount, bankAmount);\n coreRows.push({id:`pr_match_${pair.payrollIndex+1}_${pair.bankIndex+1}`,employee:pair.payroll.employee_name,employee_name:pair.payroll.employee_name,employeeNumber:pair.payroll.employee_number||'',employee_number:pair.payroll.employee_number||'',account:bankAccount||payrollAccount,payrollAccount:payrollAccount,payroll_account:payrollAccount,bankAccount:bankAccount,bank_account:bankAccount,currency,payrollAmount,payroll_amount:payrollAmount,bankAmount,bank_amount:bankAmount,difference,status:exact?'Coincide':'Pendiente revisión',category:exact?'coincidencia':'discrepancia',subcategory:exact?'persona_cuenta_y_monto_exactos':'persona_y_cuenta_coinciden_monto_diferente',observation:exact?'Coincidencia de persona, cuenta y monto.':difference>0?'Se pagó de menos.':'Se pagó de más.',source_kind:pair.payroll.source_kind||'',source_sheet:pair.payroll.source_sheet||'',source_file:pair.bank.source_file||'',shipment_number:pair.bank.shipment_number||'',plan_number:pair.bank.plan_number||'',plan_label:pair.bank.plan_label||'',reference:pair.bank.reference||'',bank_name_file:pair.bank.bank_name_file||'',bank_account_holder:pair.bank.bank_account_holder||''});\n}\nfor (let payrollIndex=0; payrollIndex({...row,source_sheets:Array.from(row.source_sheets),source_files:Array.from(row.source_files),shipment_numbers:Array.from(row.shipment_numbers),plan_numbers:Array.from(row.plan_numbers),source_sheet:Array.from(row.source_sheets).join(' / '),source_file:Array.from(row.source_files).join(' / '),shipment_number:Array.from(row.shipment_numbers).join(' / '),plan_number:Array.from(row.plan_numbers).join(' / ')}));\ncoreRows.push(...wrongAccountRows);\n\n// Banco sin Nómina se conserva a nivel de TRANSACCIÓN.\n// Una misma persona/cuenta puede tener más de un pago bancario legítimamente\n// separado; agruparlos reduce artificialmente el número de hallazgos.\nconst bankWithoutPayrollRows = [];\n\nfor (const entry of includedBankRows) {\n if (usedBankKeys.has(entry.key)) continue;\n\n const row = entry.row;\n const displayName =\n bankDisplayName(row);\n\n const rowCurrency =\n clean(row.currency || 'USD')\n .toUpperCase() === 'USD'\n ? 'USD'\n : 'HNL';\n\n const bankAmount =\n roundMoney(row.amount || 0);\n\n bankWithoutPayrollRows.push({\n id:\n `pr_bank_without_payroll_${entry.index + 1}`,\n employee: displayName,\n employee_name: displayName,\n employeeNumber: '',\n employee_number: '',\n account: row.account || '',\n payrollAccount: '',\n payroll_account: '',\n bankAccount: row.account || '',\n bank_account: row.account || '',\n currency: rowCurrency,\n payrollAmount: 0,\n payroll_amount: 0,\n bankAmount,\n bank_amount: bankAmount,\n difference:\n roundMoney(0 - bankAmount),\n status: 'Pendiente revisión',\n category: 'banco_sin_nomina',\n subcategory:\n 'pago_banco_sin_registro_nomina',\n observation:\n 'Pago bancario sin registro equivalente en las planillas cargadas.',\n bank_name_file:\n row.bank_name_file || '',\n bank_account_holder:\n row.bank_account_holder || '',\n source_file:\n row.source_file || '',\n shipment_number:\n row.shipment_number || '',\n plan_number:\n row.plan_number || '',\n reference:\n row.reference || '',\n row_number:\n row.row_number || null,\n source_rows: [row],\n });\n}\n\ncoreRows.push(...bankWithoutPayrollRows);\n\nconst nameDifferenceRows = [];\nfor (const entry of includedBankRows) {\n const row = entry.row;\n const rowCurrency=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';\n if (!clean(row.bank_name_file) || !clean(row.bank_account_holder)) continue;\n if (bankNameLooksConsistent(row.bank_name_file, row.bank_account_holder)) continue;\n nameDifferenceRows.push({\n id: `pr_bank_name_difference_${entry.index + 1}`,\n employee: row.bank_name_file,\n employee_name: row.bank_name_file,\n employeeNumber: '',\n employee_number: '',\n account: row.account || '',\n payrollAccount: '',\n payroll_account: '',\n bankAccount: row.account || '',\n bank_account: row.account || '',\n currency: rowCurrency,\n payrollAmount: 0,\n payroll_amount: 0,\n bankAmount: roundMoney(row.amount),\n bank_amount: roundMoney(row.amount),\n difference: 0,\n status: 'Pendiente revisión',\n category: 'diferencia_nombre_banco',\n subcategory: 'nombre_archivo_vs_cuentahabiente',\n observation: `El Nombre en Archivo (${row.bank_name_file}) no coincide con el Nombre del Cuentahabiente (${row.bank_account_holder}).`,\n bank_name_file: row.bank_name_file,\n bank_account_holder: row.bank_account_holder,\n source_file: row.source_file || '',\n shipment_number: row.shipment_number || '',\n plan_number: row.plan_number || '',\n reference: row.reference || '',\n row_number: row.row_number || null,\n });\n}\n\nconst bankWithoutBambooMap = new Map();\nconst bambooMatchDetails = [];\nfor (const entry of includedBankRows) {\n const row = entry.row;\n const linkedNames =\n linkedPayrollNamesByBankKey.get(entry.key) || [];\n\n const linkedEmployeeNumbers =\n linkedPayrollEmployeeNumbersByBankKey.get(\n entry.key\n ) || [];\n\n const decision = resolveBamboo(\n row,\n linkedNames,\n linkedEmployeeNumbers\n );\n bambooMatchDetails.push({\n bank_row_key: entry.key,\n bank_name_file: row.bank_name_file || '',\n bank_account_holder: row.bank_account_holder || '',\n account: row.account || '',\n amount: row.amount || 0,\n linked_payroll_names: linkedNames,\n ...decision,\n });\n if (decision.found) continue;\n\n const displayName = bankDisplayName(row);\n const rowCurrency=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';\n const groupingKey = `${normalizeAccount(row.account)}|${normalizeName(displayName)}|${rowCurrency}`;\n const current = bankWithoutBambooMap.get(groupingKey) || {\n id: `pr_bank_without_bamboo_${bankWithoutBambooMap.size + 1}`,\n bank_name_file: row.bank_name_file || displayName,\n bank_account_holder: row.bank_account_holder || '',\n employee_name: row.bank_name_file || displayName,\n account: row.account || '',\n currency: rowCurrency,\n bank_amount: 0,\n amount: 0,\n status: 'Pendiente revisión',\n category: 'banco_sin_bamboo',\n shipment_numbers: new Set(),\n references: new Set(),\n source_files: new Set(),\n source_rows: [],\n };\n current.bank_amount = roundMoney(current.bank_amount + Number(row.amount || 0));\n current.amount = current.bank_amount;\n if (row.shipment_number) current.shipment_numbers.add(row.shipment_number);\n if (row.reference) current.references.add(row.reference);\n if (row.source_file) current.source_files.add(row.source_file);\n current.source_rows.push(row);\n bankWithoutBambooMap.set(groupingKey, current);\n}\n\nconst bankWithoutBamboo = Array.from(bankWithoutBambooMap.values()).map((row) => ({\n ...row,\n shipment_numbers: Array.from(row.shipment_numbers),\n shipment_number: Array.from(row.shipment_numbers).join(' / '),\n references: Array.from(row.references),\n source_files: Array.from(row.source_files),\n source_file: Array.from(row.source_files).join(' / '),\n difference: roundMoney(0 - row.bank_amount),\n}));\n\nfunction priority(row) {\n const category = clean(row.category).toLowerCase();\n if (category === 'posible_cuenta_mal_digitada') return 1;\n if (category === 'discrepancia') return 2;\n if (category === 'banco_sin_nomina') return 3;\n if (category === 'diferencia_nombre_banco') return 5;\n if (category === 'coincidencia') return 99;\n return 50;\n}\n\nconst rowsFinales = [...coreRows, ...nameDifferenceRows].sort((a, b) => {\n const p = priority(a) - priority(b);\n if (p !== 0) return p;\n return clean(a.employee_name).localeCompare(clean(b.employee_name), 'es');\n});\n\nconst coincidencias = coreRows.filter((row) => row.category === 'coincidencia').length;\nconst discrepancias = coreRows.filter((row) => row.category === 'discrepancia').length;\nconst bancoSinNomina = bankWithoutPayrollRows.length;\nconst diferenciasNombreBanco = nameDifferenceRows.length;\nconst posiblesCuentasMalDigitadas = wrongAccountRows.length;\nconst pendientes = discrepancias + bancoSinNomina + diferenciasNombreBanco;\nconst totalNominaByCurrency = {HNL:0,USD:0};\nfor(const row of payrollRows){const c=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';totalNominaByCurrency[c]=roundMoney(totalNominaByCurrency[c]+Number(row.payroll_amount||0));}\nconst totalBancoByCurrency = {HNL:0,USD:0};\nfor(const entry of includedBankRows){const c=clean(entry.row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';totalBancoByCurrency[c]=roundMoney(totalBancoByCurrency[c]+Number(entry.row.amount||0));}\nconst diferenciaByCurrency={HNL:moneyDiff(totalNominaByCurrency.HNL,totalBancoByCurrency.HNL),USD:moneyDiff(totalNominaByCurrency.USD,totalBancoByCurrency.USD)};\nconst totalNomina=totalNominaByCurrency.HNL || totalNominaByCurrency.USD;\nconst totalBanco=totalBancoByCurrency.HNL || totalBancoByCurrency.USD;\nconst diferenciaTotal=totalNominaByCurrency.HNL||totalBancoByCurrency.HNL?diferenciaByCurrency.HNL:diferenciaByCurrency.USD;\n\nconst bambooSummaryCompact = { ...(data.bamboo || {}) };\ndelete bambooSummaryCompact.employees;\n\nreturn [{\n json: {\n ok: true,\n stage: 'cruce_nomina_banco_puerto_rico',\n errors: [],\n metadata: data.metadata || {},\n summary: {\n coincidencias,\n discrepancias,\n bancoSinNomina,\n bancoSinBamboo: bankWithoutBamboo.length,\n nominaSinCuenta: 0,\n diferenciasNombreBanco,\n posiblesCuentasMalDigitadas,\n pendientes,\n filasNominaValidas: Number(data.payroll?.base_rows_count || data.payroll?.valid_rows_count || 0),\n filasNominaSinCuenta: 0,\n suplementosPotenciales: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaAplicados: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaNoAplicados: 0,\n suplementosNominaAdjuntados: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaNoAdjuntados: Number(data.payroll?.unattached_supplements_count || 0),\n reconciliacionesExactasFinales: coincidencias,\n cuentasNominaAgrupadas: 0,\n transaccionesBanco: includedBankRows.length,\n cuentasBancoAgrupadas: new Set(includedBankRows.map((entry) => normalizeAccount(entry.row.account)).filter(Boolean)).size,\n empleadosBambooPR: Number(data.bamboo?.puerto_rico_count || 0),\n empleadosBambooEnPeriodo: Number(data.bamboo?.active_in_period_count || 0),\n bambooPaginasDescargadas: Number(data.bamboo?.pages_fetched || 0),\n bambooEmpleadosEsperados: Number(data.bamboo?.expected_total || 0),\n bambooDescargaCompleta: Boolean(data.bamboo?.fetch_complete),\n bambooValidacionDisponible: bambooValidationAvailable,\n totalNominaBase: roundMoney(data.payroll?.base_total || 0),\n totalSuplementosAplicados: roundMoney(data.payroll?.supplements_total || 0),\n totalNomina,\n totalBanco,\n diferenciaTotal,\n totalNominaPorMoneda: totalNominaByCurrency,\n totalBancoPorMoneda: totalBancoByCurrency,\n diferenciaTotalPorMoneda: diferenciaByCurrency,\n },\n rows: rowsFinales,\n bankWithoutBamboo,\n nameDifferences: nameDifferenceRows,\n bambooSummary: bambooSummaryCompact,\n reportUrl: null,\n debug: {\n matched_pairs_count: matchedPairs.length,\n included_bank_rows_count: includedBankRows.length,\n excluded_bank_rows_count: excludedBankRows.length,\n excluded_bank_rows_preview: excludedBankRows.slice(0, 100),\n validated_bamboo_aliases_loaded: validatedBambooAliases.length,\n bamboo_matches: bambooMatchDetails,\n bamboo_validation_available: bambooValidationAvailable,\n banco_sin_bamboo: bankWithoutBamboo,\n payroll_preview: payrollRows.slice(0, 20),\n bank_included_preview: includedBankRows.slice(0, 20).map((entry) => entry.row),\n },\n },\n}];\n" + "jsCode": "const data = $('Merge - Agregar BambooHR PR').first().json || {};\nconst aliasResponse = $input.first().json || {};\nconst validatedBambooAliases = Array.isArray(aliasResponse.aliases)\n ? aliasResponse.aliases\n : Array.isArray(aliasResponse)\n ? aliasResponse\n : [];\n\nfunction clean(value) {\n return String(value ?? '')\n .replace(/\\uFEFF/g, '')\n .replace(/\\u00A0/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst normalizedNameCache = new Map();\nconst nameWordsCache = new Map();\nconst nameMatchScoreCache = new Map();\n\nfunction normalizeName(value) {\n const raw = clean(value);\n if (normalizedNameCache.has(raw)) {\n return normalizedNameCache.get(raw);\n }\n\n const normalized = raw\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/['’`-]/g, ' ')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n\n normalizedNameCache.set(raw, normalized);\n return normalized;\n}\n\nfunction normalizeAccount(value) {\n return String(value ?? '').replace(/\\.0$/g, '').replace(/\\D/g, '').trim();\n}\n\nfunction normalizeEmployeeNumber(value) {\n return String(value ?? '')\n .replace(/\\u00A0/g, '')\n .replace(/\\D/g, '')\n .trim();\n}\n\nfunction roundMoney(value) {\n return Math.round((Number(value) || 0) * 100) / 100;\n}\n\nfunction moneyDiff(payroll, bank) {\n return roundMoney((Number(payroll) || 0) - (Number(bank) || 0));\n}\n\nconst MONEY_TOLERANCE = 0.01;\nconst MONEY_TOLERANCE_CENTS = Math.round(MONEY_TOLERANCE * 100);\n\nfunction sameCent(a, b) {\n return Math.abs(moneyDiff(a, b)) <= MONEY_TOLERANCE + 1e-9;\n}\n\nconst IGNORED_NAME_TOKENS = new Set([\n 'de', 'del', 'la', 'las', 'los', 'y', 'e', 'el',\n 'da', 'do', 'dos', 'das', 'van', 'von',\n]);\n\nfunction nameWords(value) {\n const normalized = normalizeName(value);\n if (nameWordsCache.has(normalized)) {\n return nameWordsCache.get(normalized);\n }\n\n const words = normalized\n .split(' ')\n .filter((word) => word.length > 1 && !IGNORED_NAME_TOKENS.has(word));\n\n nameWordsCache.set(normalized, words);\n return words;\n}\n\nfunction editDistance(a, b) {\n if (a === b) return 0;\n if (!a) return b.length;\n if (!b) return a.length;\n let previous = Array.from({ length: b.length + 1 }, (_, index) => index);\n for (let i = 1; i <= a.length; i++) {\n const current = [i];\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n current[j] = Math.min(current[j - 1] + 1, previous[j] + 1, previous[j - 1] + cost);\n }\n previous = current;\n }\n return previous[b.length];\n}\n\nfunction tokenMatches(a, b) {\n if (a === b) return true;\n const minLength = Math.min(a.length, b.length);\n if (minLength >= 8 && editDistance(a, b) <= 2) return true;\n if (minLength >= 5 && editDistance(a, b) <= 1) return true;\n return false;\n}\n\nfunction samePersonName(a, b) {\n const normalizedA = normalizeName(a);\n const normalizedB = normalizeName(b);\n if (!normalizedA || !normalizedB) return false;\n if (normalizedA === normalizedB) return true;\n\n const wordsA = nameWords(a);\n const wordsB = nameWords(b);\n if (!wordsA.length || !wordsB.length) return false;\n\n const usedB = new Set();\n let matches = 0;\n for (const wordA of wordsA) {\n const matchIndex = wordsB.findIndex((wordB, index) =>\n !usedB.has(index) && tokenMatches(wordA, wordB)\n );\n if (matchIndex >= 0) {\n usedB.add(matchIndex);\n matches += 1;\n }\n }\n\n const smallerLength = Math.min(wordsA.length, wordsB.length);\n const ratio = matches / smallerLength;\n if (smallerLength <= 2) return matches === smallerLength && matches >= 2;\n return matches >= 2 && ratio >= 0.6;\n}\n\nfunction bankNameLooksConsistent(fileName, holderName) {\n const fileWords = nameWords(fileName);\n const holderWords = nameWords(holderName);\n\n if (!fileWords.length || !holderWords.length) return true;\n\n const used = new Set();\n\n for (const fileWord of fileWords) {\n let matchIndex = holderWords.findIndex(\n (holderWord, index) =>\n !used.has(index) &&\n holderWord === fileWord\n );\n\n // Algunos planos de Puerto Rico recortan el último carácter del apellido\n // por longitud de campo (ej.: ALVARAD -> ALVARADO). Eso no debe\n // convertirse en una diferencia de nombre. No se aceptan sustituciones\n // ortográficas (ej.: GONZALES -> GONZALEZ), porque sí requieren revisión.\n if (matchIndex < 0) {\n matchIndex = holderWords.findIndex(\n (holderWord, index) =>\n !used.has(index) &&\n holderWord.startsWith(fileWord) &&\n (\n (fileWord.length <= 3) ||\n (\n fileWord.length >= 4 &&\n holderWord.length === fileWord.length + 1\n )\n )\n );\n }\n\n if (matchIndex < 0) return false;\n used.add(matchIndex);\n }\n\n return true;\n}\n\nfunction nameMatchScore(a, b) {\n const na = normalizeName(a);\n const nb = normalizeName(b);\n if (!na || !nb) return 0;\n\n const cacheKey = na <= nb ? `${na}\\u0000${nb}` : `${nb}\\u0000${na}`;\n if (nameMatchScoreCache.has(cacheKey)) {\n return nameMatchScoreCache.get(cacheKey);\n }\n\n if (na === nb) {\n nameMatchScoreCache.set(cacheKey, 1);\n return 1;\n }\n\n const wa = nameWords(a);\n const wb = nameWords(b);\n if (!samePersonName(a, b)) {\n nameMatchScoreCache.set(cacheKey, 0);\n return 0;\n }\n\n const setA = new Set(wa);\n const setB = new Set(wb);\n let exact = 0;\n for (const w of setA) if (setB.has(w)) exact += 1;\n const min = Math.max(1, Math.min(setA.size, setB.size));\n const score = Math.min(\n 0.99,\n 0.75 + (exact / min) * 0.20 + (wa.length === wb.length ? 0.04 : 0)\n );\n\n nameMatchScoreCache.set(cacheKey, score);\n return score;\n}\n\nfunction bankNames(row) {\n return [row.bank_name_file, row.bank_account_holder]\n .map(clean)\n .filter(Boolean);\n}\n\nfunction bestNameScore(payrollName, bankRow) {\n return Math.max(0, ...bankNames(bankRow).map((name) => nameMatchScore(payrollName, name)));\n}\n\nfunction bankDisplayName(row) {\n return clean(row.bank_name_file) || clean(row.bank_account_holder) || 'Pago bancario';\n}\n\nfunction bankRowKey(row, index) {\n return clean(row.bank_row_key) || `${clean(row.source_file)}|${row.row_number || index + 1}`;\n}\n\n\nconst metadata = data.metadata || {};\n\nfunction parseBankDate(value, sourceFile = '') {\n const raw = clean(value);\n let match = raw.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})/);\n if (match) {\n return {\n year: Number(match[3]),\n month: Number(match[2]),\n day: Number(match[1]),\n };\n }\n\n match = raw.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})/);\n if (match) {\n return {\n year: Number(match[1]),\n month: Number(match[2]),\n day: Number(match[3]),\n };\n }\n\n // Respaldo por el patrón habitual del nombre: _DDMMYY / _DDMMYYYY.\n const fileMatch = clean(sourceFile).match(/_(\\d{2})(\\d{2})(\\d{2}|\\d{4})(?:\\D|$)/);\n if (!fileMatch) return null;\n\n const yearPart = Number(fileMatch[3]);\n return {\n year: fileMatch[3].length === 2 ? 2000 + yearPart : yearPart,\n month: Number(fileMatch[2]),\n day: Number(fileMatch[1]),\n };\n}\n\nfunction selectedPeriodKind() {\n const type = clean(metadata.period_type).toLowerCase();\n if (type === 'quincena_15') return 'q15';\n if (type === 'quincena_30') return 'q30';\n return 'unknown';\n}\n\nfunction conceptPeriodHint(row) {\n const concept = normalizeName(row.concept || '');\n if (!concept) return 'unknown';\n\n if (\n /(?:^| )1(?:ra|er|era)? quincena(?: |$)/.test(concept) ||\n concept.includes('primera quincena') ||\n concept.includes('quincena 1ra') ||\n concept.includes('quincena 1')\n ) {\n return 'q15';\n }\n\n if (\n /(?:^| )2(?:da|do|nda)? quincena(?: |$)/.test(concept) ||\n concept.includes('segunda quincena') ||\n concept.includes('quincena 2da') ||\n concept.includes('quincena 2') ||\n concept.includes('fin de mes')\n ) {\n return 'q30';\n }\n\n return 'unknown';\n}\n\nfunction periodInfoForBankRow(row) {\n const selected = selectedPeriodKind();\n const rowDate = parseBankDate(row.application_date, row.source_file);\n const selectedYear = Number(metadata.year || 0);\n const selectedMonth = Number(metadata.month || 0);\n const hint = conceptPeriodHint(row);\n\n if (selected === 'unknown') {\n return { known: false, selected, inPeriod: true, affinity: 1, rowDate, hint };\n }\n\n if (hint !== 'unknown' && hint === selected) {\n return { known: true, selected, inPeriod: true, affinity: 4, rowDate, hint };\n }\n\n if (!rowDate || !selectedYear || !selectedMonth) {\n return { known: false, selected, inPeriod: true, affinity: 1, rowDate, hint };\n }\n\n if (rowDate.year !== selectedYear || rowDate.month !== selectedMonth) {\n return { known: true, selected, inPeriod: false, affinity: 0, rowDate, hint };\n }\n\n const inHalf = selected === 'q15'\n ? rowDate.day <= 15\n : rowDate.day >= 16;\n\n return {\n known: true,\n selected,\n inPeriod: inHalf,\n affinity: inHalf ? 3 : 0,\n rowDate,\n hint,\n };\n}\n\nfunction isSupplementPayroll(payroll) {\n return clean(payroll?.source_kind).toLowerCase() !== 'quincenal';\n}\n\nfunction bankCandidatePeriodScore(payroll, bank) {\n const info = periodInfoForBankRow(bank);\n if (!info.known || info.inPeriod) return info.affinity || 1;\n\n // Una extraordinaria/vacación/XIII Mes puede pagarse fuera de la mitad\n // estricta del mes. Se permite como respaldo, siempre detrás de cualquier\n // candidato del período seleccionado.\n if (isSupplementPayroll(payroll) && info.rowDate) {\n const selectedYear = Number(metadata.year || 0);\n const selectedMonth = Number(metadata.month || 0);\n if (info.rowDate.year === selectedYear && info.rowDate.month === selectedMonth) {\n return 0.5;\n }\n }\n\n return -1;\n}\n\nconst payrollRows = Array.isArray(data.payroll?.rows) ? data.payroll.rows : [];\nconst bankRows = Array.isArray(data.bank?.rows) ? data.bank.rows : [];\n\n// Guardia de seguridad: nunca generar un reporte \"válido\" cuando el request\n// traía archivos pero el parser no consiguió ninguna fila. Esto evita que\n// todas las personas de nómina aparezcan falsamente como discrepancias.\nif (payrollRows.length === 0) {\n throw new Error(\n 'Puerto Rico: no se pudo leer ninguna fila válida de nómina. ' +\n 'Revisa los archivo Excel de Puerto Rico y las hojas Whirlpool, Personal 2 y Personal 3.'\n );\n}\n\nif (bankRows.length === 0) {\n const detectedFiles = Number(data.bank?.files_count || data.summary?.bank_files_count || 0);\n const invalidFiles = Array.isArray(data.bank?.file_summaries)\n ? data.bank.file_summaries.filter((file) => file?.ok === false)\n : [];\n\n throw new Error(\n 'Puerto Rico: no se pudo leer ninguna transacción bancaria. ' +\n `Archivos bancarios detectados: ${detectedFiles}. ` +\n (invalidFiles.length\n ? `Archivos con error de formato: ${invalidFiles.map((file) => file.file_name).join(', ')}.`\n : 'Verifica que el PDF sea el Transaction Detail Report de Banco Popular de Puerto Rico.')\n );\n}\n\nconst bambooEmployees = Array.isArray(data.bamboo?.employees) ? data.bamboo.employees : [];\nconst resolvedNameMatches = data.bamboo?.resolved_name_matches || {};\nconst bambooValidationAvailable = data.bamboo?.fetch_complete === true &&\n data.bamboo?.validation_available === true && bambooEmployees.length > 0;\n\nconst bambooByEmployeeNumber = new Map();\nconst bambooById = new Map();\nconst bambooByExactName = new Map();\nfor (const employee of bambooEmployees) {\n const number = normalizeEmployeeNumber(\n employee.employee_number || employee.employeeNumber\n );\n const id = clean(employee.bamboo_id || employee.id);\n if (number) {\n const arr = bambooByEmployeeNumber.get(number) || [];\n arr.push(employee);\n bambooByEmployeeNumber.set(number, arr);\n }\n if (id) bambooById.set(id, employee);\n for (const alias of employee.aliases || [employee.full_name]) {\n const normalized = normalizeName(alias);\n if (!normalized) continue;\n const arr = bambooByExactName.get(normalized) || [];\n arr.push(employee);\n bambooByExactName.set(normalized, arr);\n }\n}\n\nfunction employeeKey(employee) {\n return clean(employee?.bamboo_id || employee?.id) ||\n clean(employee?.employee_number || employee?.employeeNumber) ||\n normalizeName(employee?.full_name || employee?.displayName);\n}\n\nfunction validatedAliasDecision(row) {\n if (!validatedBambooAliases.length) return null;\n const rowAccount = normalizeAccount(row.account);\n const names = bankNames(row).map(normalizeName).filter(Boolean);\n const candidates = validatedBambooAliases.filter((alias) => {\n const country = clean(alias.pais || alias.country).toUpperCase();\n if (country && country !== 'PR') return false;\n const source = normalizeName(alias.nombre_origen || alias.source_name || alias.alias || '');\n if (!source || !names.includes(source)) return false;\n const aliasAccount = normalizeAccount(alias.cuenta_bancaria || alias.cuenta_banco || alias.bank_account || '');\n return !aliasAccount || !rowAccount || aliasAccount === rowAccount;\n });\n if (candidates.length !== 1) return null;\n const alias = candidates[0];\n let employee = null;\n const employeeNumber = normalizeEmployeeNumber(\n alias.bamboo_employee_number || ''\n );\n const bambooId = clean(alias.bamboo_employee_id || '');\n const bambooName = normalizeName(alias.bamboo_nombre || '');\n if (employeeNumber && (bambooByEmployeeNumber.get(employeeNumber) || []).length === 1) {\n employee = bambooByEmployeeNumber.get(employeeNumber)[0];\n } else if (bambooId && bambooById.has(bambooId)) {\n employee = bambooById.get(bambooId);\n } else if (bambooName && (bambooByExactName.get(bambooName) || []).length === 1) {\n employee = bambooByExactName.get(bambooName)[0];\n }\n if (!employee) return null;\n return {\n found: true,\n matched_by: 'validated_bamboo_alias',\n confidence: 1,\n employee,\n employee_key: employeeKey(employee),\n bamboo_alias: clean(alias.bamboo_nombre) || employee.full_name || '',\n };\n}\n\nfunction precomputedDecision(name) {\n const normalized = normalizeName(name);\n if (!normalized) return null;\n const decision = resolvedNameMatches[normalized];\n if (!decision || decision.found !== true) return null;\n const index = Number(decision.employee_index);\n const employee = Number.isInteger(index) && index >= 0 ? bambooEmployees[index] : null;\n const key = clean(decision.employee_key) || employeeKey(employee);\n if (!key) return null;\n return {\n found: true,\n matched_by: decision.matched_by || 'precomputed_name',\n confidence: Number(decision.confidence || 0),\n employee,\n employee_key: key,\n bamboo_alias: clean(decision.bamboo_alias) || employee?.full_name || '',\n query_name: clean(name),\n };\n}\n\nfunction resolveBamboo(\n row,\n linkedPayrollNames = [],\n linkedPayrollEmployeeNumbers = []\n) {\n if (!bambooValidationAvailable) {\n return {\n found: false,\n reason: 'validation_unavailable',\n };\n }\n\n const validated = validatedAliasDecision(row);\n if (validated) return validated;\n\n /*\n * Puerto Rico: si existe un identificador fuerte procedente de nómina se puede usar como respaldo para determinar\n * si el pago pertenece a una persona existente en BambooHR.\n *\n * Se normalizan guiones/espacios tanto en banco como en BambooHR:\n * 0611198400414 <-> 0611-1984-00414\n *\n * Como respaldo, cuando la fila bancaria ya fue conciliada con nómina,\n * también se usa el Employee Number/Identidad de esa fila de nómina.\n * Solo se acepta el identificador cuando apunta a UNA sola persona.\n */\n const referenceEmployeeNumbers = Array.from(\n new Set(\n [\n row.reference,\n row.participant_id,\n row.employee_number,\n row.employeeNumber,\n ...linkedPayrollEmployeeNumbers,\n ]\n .flatMap((value) =>\n String(value ?? '').match(/\\d{6,20}/g) || []\n )\n .map(normalizeEmployeeNumber)\n .filter((value) => value.length >= 6)\n )\n );\n\n const employeesByStrongIdentifier = new Map();\n\n for (const employeeNumber of referenceEmployeeNumbers) {\n const matches =\n bambooByEmployeeNumber.get(employeeNumber) || [];\n\n if (matches.length !== 1) continue;\n\n const employee = matches[0];\n const key = employeeKey(employee);\n\n if (key) {\n employeesByStrongIdentifier.set(\n key,\n {\n employee,\n employee_number: employeeNumber,\n }\n );\n }\n }\n\n if (employeesByStrongIdentifier.size === 1) {\n const resolved =\n employeesByStrongIdentifier.values().next().value;\n\n return {\n found: true,\n matched_by: 'bank_or_payroll_employee_number',\n confidence: 1,\n employee: resolved.employee,\n employee_key: employeeKey(resolved.employee),\n bamboo_alias:\n clean(resolved.employee.full_name) ||\n clean(resolved.employee.displayName) ||\n '',\n matched_employee_number:\n resolved.employee_number,\n };\n }\n\n const holderName = clean(row.bank_account_holder);\n const fileName = clean(row.bank_name_file);\n\n // El nombre legal del cuentahabiente es la evidencia bancaria más fuerte.\n // Si identifica exactamente a una persona que pertenecía al período,\n // prevalece sobre un nombre abreviado que pueda coincidir con un perfil\n // histórico distinto (caso real: Suyapa Palma).\n const holderDecision = holderName\n ? precomputedDecision(holderName)\n : null;\n\n const holderMatchedBy =\n clean(holderDecision?.matched_by).toLowerCase();\n\n const holderIsExactUnique =\n holderDecision?.found === true &&\n (\n holderDecision.confidence >= 0.999 ||\n holderMatchedBy.includes('exact_precomputed_name') ||\n holderMatchedBy.includes('confirmed_alias_catalog')\n );\n\n // \"Banco sin Bamboo\" valida existencia en BambooHR, no que la persona\n // siguiera activa durante toda la quincena. Un finiquito/pago final puede\n // ocurrir después de la fecha de terminación. Por eso un nombre legal\n // completo y único del cuentahabiente es suficiente evidencia.\n if (holderIsExactUnique) {\n return {\n ...holderDecision,\n matched_by:\n `${holderDecision.matched_by || 'precomputed_name'}_holder_exact`,\n };\n }\n\n if (\n holderDecision?.found &&\n holderDecision.employee?.overlaps_period === true\n ) {\n return {\n ...holderDecision,\n matched_by:\n `${holderDecision.matched_by || 'precomputed_name'}_holder_in_period`,\n };\n }\n\n const names = Array.from(\n new Set(\n [\n holderName,\n fileName,\n ...linkedPayrollNames.map(clean),\n ].filter(Boolean)\n )\n );\n\n const decisions = names\n .map(precomputedDecision)\n .filter(Boolean);\n\n if (!decisions.length) {\n return {\n found: false,\n reason: 'no_confident_name_match',\n };\n }\n\n // Antes de declarar conflicto, descartar perfiles históricos que no\n // pertenecen al período cuando existe una única persona vigente/en período.\n const inPeriodByKey = new Map();\n\n for (const decision of decisions) {\n if (decision.employee?.overlaps_period !== true) continue;\n\n const current =\n inPeriodByKey.get(decision.employee_key);\n\n if (\n !current ||\n decision.confidence > current.confidence\n ) {\n inPeriodByKey.set(\n decision.employee_key,\n decision\n );\n }\n }\n\n const inPeriodRanked =\n Array.from(inPeriodByKey.values())\n .sort(\n (left, right) =>\n right.confidence - left.confidence\n );\n\n if (inPeriodRanked.length === 1) {\n return {\n ...inPeriodRanked[0],\n matched_by:\n `${inPeriodRanked[0].matched_by || 'precomputed_name'}_unique_in_period`,\n };\n }\n\n if (\n inPeriodRanked.length >= 2 &&\n (\n inPeriodRanked[0].confidence -\n inPeriodRanked[1].confidence\n ) >= 0.08\n ) {\n return inPeriodRanked[0];\n }\n\n const byKey = new Map();\n\n for (const decision of decisions) {\n const current =\n byKey.get(decision.employee_key);\n\n if (\n !current ||\n decision.confidence > current.confidence\n ) {\n byKey.set(\n decision.employee_key,\n decision\n );\n }\n }\n\n const ranked =\n Array.from(byKey.values())\n .sort(\n (left, right) =>\n right.confidence - left.confidence\n );\n\n if (ranked.length === 1) {\n return ranked[0];\n }\n\n if (\n (\n ranked[0].confidence -\n ranked[1].confidence\n ) >= 0.08\n ) {\n return ranked[0];\n }\n\n return {\n found: false,\n reason: 'conflicting_precomputed_name_matches',\n candidates: ranked.slice(0, 3),\n };\n}\n\nconst usedBankKeys = new Set();\nconst matchedPayrollIndexes = new Set();\nconst matchedPairs = [];\nconst bankIndexByKey = new Map();\n\n// Índice por centavos para que la pasada principal no compare cada fila de\n// nómina contra todas las transacciones del banco. Esto preserva exactamente\n// la lógica original: la primera pasada ya exigía el mismo monto al centavo.\nconst bankIndexesByAmountCents = new Map();\n\nfunction amountCents(value) {\n return Math.round(roundMoney(value) * 100);\n}\n\nbankRows.forEach((row, index) => {\n const key = bankRowKey(row, index);\n bankIndexByKey.set(key, index);\n\n const amountKey = `${clean(row.currency || 'USD').toUpperCase()}|${amountCents(row.amount)}`;\n const bucket = bankIndexesByAmountCents.get(amountKey) || [];\n bucket.push(index);\n bankIndexesByAmountCents.set(amountKey, bucket);\n});\n\nfunction availableNameCandidates(payroll, requireExactAmount) {\n const candidates = [];\n\n // La pasada exacta solo inspecciona filas con el mismo importe. La segunda\n // pasada conserva el barrido completo y el mismo criterio de persona fuerte\n // + menor diferencia que tenía el workflow validado.\n let candidateIndexes = null;\n\n if (requireExactAmount) {\n const currency =\n clean(payroll.currency || 'USD')\n .toUpperCase();\n\n const center =\n amountCents(payroll.payroll_amount);\n\n const indexSet = new Set();\n\n for (\n let delta = -MONEY_TOLERANCE_CENTS;\n delta <= MONEY_TOLERANCE_CENTS;\n delta++\n ) {\n const bucket =\n bankIndexesByAmountCents.get(\n `${currency}|${center + delta}`\n ) || [];\n\n for (const bankIndex of bucket) {\n indexSet.add(bankIndex);\n }\n }\n\n candidateIndexes =\n Array.from(indexSet);\n }\n\n const inspectBank = (bankIndex) => {\n const bank = bankRows[bankIndex];\n if (!bank) return;\n\n const key = bankRowKey(bank, bankIndex);\n if (usedBankKeys.has(key)) return;\n if (clean(payroll.currency || 'USD').toUpperCase() !== clean(bank.currency || 'HNL').toUpperCase()) return;\n\n if (requireExactAmount && !sameCent(payroll.payroll_amount, bank.amount)) return;\n\n const periodScore = bankCandidatePeriodScore(payroll, bank);\n if (periodScore < 0) return;\n\n const score = bestNameScore(payroll.employee_name, bank);\n if (score <= 0) return;\n\n candidates.push({\n bank,\n bankIndex,\n key,\n score,\n periodScore,\n amountDiff: Math.abs(moneyDiff(payroll.payroll_amount, bank.amount)),\n });\n };\n\n if (candidateIndexes) {\n for (const bankIndex of candidateIndexes) {\n inspectBank(bankIndex);\n }\n } else {\n for (let bankIndex = 0; bankIndex < bankRows.length; bankIndex++) {\n inspectBank(bankIndex);\n }\n }\n\n candidates.sort((a, b) => {\n if (b.periodScore !== a.periodScore) return b.periodScore - a.periodScore;\n if (b.score !== a.score) return b.score - a.score;\n if (a.amountDiff !== b.amountDiff) return a.amountDiff - b.amountDiff;\n return a.bankIndex - b.bankIndex;\n });\n\n return candidates;\n}\n\n// Primera pasada: persona + monto exacto. Es la evidencia más fuerte y evita\n// que extraordinarias/vacaciones de una misma persona se mezclen entre sí.\npayrollRows.forEach((payroll, payrollIndex) => {\n const candidates = availableNameCandidates(payroll, true);\n if (!candidates.length) return;\n const chosen = candidates[0];\n usedBankKeys.add(chosen.key);\n matchedPayrollIndexes.add(payrollIndex);\n matchedPairs.push({ payroll, payrollIndex, ...chosen });\n});\n\n// Segunda pasada: persona fuerte aunque el monto sea distinto. Solo se toma\n// una contraparte bancaria por fila de nómina y se prioriza la menor diferencia.\npayrollRows.forEach((payroll, payrollIndex) => {\n if (matchedPayrollIndexes.has(payrollIndex)) return;\n const candidates = availableNameCandidates(payroll, false);\n if (!candidates.length) return;\n const chosen = candidates[0];\n usedBankKeys.add(chosen.key);\n matchedPayrollIndexes.add(payrollIndex);\n matchedPairs.push({ payroll, payrollIndex, ...chosen });\n});\n\nconst linkedPayrollNamesByBankKey = new Map();\nconst linkedPayrollEmployeeNumbersByBankKey = new Map();\n\nfor (const pair of matchedPairs) {\n const currentNames =\n linkedPayrollNamesByBankKey.get(pair.key) || [];\n\n currentNames.push(pair.payroll.employee_name);\n\n linkedPayrollNamesByBankKey.set(\n pair.key,\n currentNames\n );\n\n const employeeNumber =\n normalizeEmployeeNumber(\n pair.payroll.employee_number ||\n pair.payroll.employeeNumber ||\n ''\n );\n\n if (employeeNumber) {\n const currentNumbers =\n linkedPayrollEmployeeNumbersByBankKey.get(\n pair.key\n ) || [];\n\n currentNumbers.push(employeeNumber);\n\n linkedPayrollEmployeeNumbersByBankKey.set(\n pair.key,\n currentNumbers\n );\n }\n}\n\n// Filas bancarias del período de Puerto Rico.\n// Toda fila emparejada entra siempre. Para una fila no emparejada se usa la\n// fecha/concepto del plano para evitar arrastrar accidentalmente otra quincena.\nconst includedBankRows = [];\nconst excludedBankRows = [];\n\nfor (let index = 0; index < bankRows.length; index++) {\n const row = bankRows[index];\n const key = bankRowKey(row, index);\n\n if (usedBankKeys.has(key)) {\n includedBankRows.push({ row, key, index, inclusion: 'matched_payroll' });\n continue;\n }\n\n const periodInfo = periodInfoForBankRow(row);\n if (periodInfo.known && !periodInfo.inPeriod) {\n excludedBankRows.push({ row, key, reason: 'outside_selected_payroll_period' });\n continue;\n }\n\n includedBankRows.push({ row, key, index, inclusion: 'unmatched_current_period' });\n}\n\nconst includedBankKeySet = new Set(includedBankRows.map((entry) => entry.key));\n\n/*\n * Employee Number para la interfaz.\n *\n * La nómina de Puerto Rico no trae Employee Number, pero en este punto ya\n * contamos con la resolución de identidad contra BambooHR. La versión\n * anterior mantenía employeeNumber vacío porque copiaba únicamente el valor\n * de nómina. Reutilizamos exactamente la misma resolución BambooHR que ya\n * valida Banco sin Bamboo para completar el Employee Number sin alterar la\n * lógica de conciliación, montos, cuentas ni categorías.\n */\nfunction bambooEmployeeNumberFromDecision(decision) {\n return clean(\n decision?.employee?.employee_number ||\n decision?.employee?.employeeNumber ||\n decision?.matched_employee_number ||\n ''\n );\n}\n\nfunction resolvedEmployeeNumberForPair(pair) {\n const payrollNumber = clean(\n pair?.payroll?.employee_number ||\n pair?.payroll?.employeeNumber ||\n ''\n );\n\n if (payrollNumber) return payrollNumber;\n\n const decision = resolveBamboo(\n pair?.bank || {},\n [pair?.payroll?.employee_name || ''].filter(Boolean),\n []\n );\n\n return bambooEmployeeNumberFromDecision(decision);\n}\n\nfunction resolvedEmployeeNumberForPayroll(payroll) {\n const payrollNumber = clean(\n payroll?.employee_number ||\n payroll?.employeeNumber ||\n ''\n );\n\n if (payrollNumber) return payrollNumber;\n\n const decision = precomputedDecision(\n payroll?.employee_name || ''\n );\n\n return bambooEmployeeNumberFromDecision(decision);\n}\n\nfunction resolvedEmployeeNumberForBankRow(\n bankRow,\n linkedNames = []\n) {\n const decision = resolveBamboo(\n bankRow || {},\n linkedNames.filter(Boolean),\n []\n );\n\n return bambooEmployeeNumberFromDecision(decision);\n}\n\nconst coreRows = [];\nconst wrongAccountGroups = new Map();\nfor (const pair of matchedPairs) {\n if (!includedBankKeySet.has(pair.key)) continue;\n const payrollAmount = roundMoney(pair.payroll.payroll_amount);\n const bankAmount = roundMoney(pair.bank.amount);\n const difference = moneyDiff(payrollAmount, bankAmount);\n const currency = clean(pair.payroll.currency || pair.bank.currency || 'USD').toUpperCase() === 'USD' ? 'USD' : 'HNL';\n const payrollAccount = normalizeAccount(pair.payroll.account || pair.payroll.payroll_account);\n const bankAccount = normalizeAccount(pair.bank.account);\n const accountMismatch = Boolean(payrollAccount && bankAccount && payrollAccount !== bankAccount);\n const resolvedEmployeeNumber = resolvedEmployeeNumberForPair(pair);\n if (accountMismatch) {\n const groupKey = `${normalizeName(pair.payroll.employee_name)}|${currency}|${payrollAccount}|${bankAccount}`;\n const current = wrongAccountGroups.get(groupKey) || {\n id: `pr_wrong_account_${wrongAccountGroups.size + 1}`,\n employee: pair.payroll.employee_name,\n employee_name: pair.payroll.employee_name,\n employeeNumber: resolvedEmployeeNumber, employee_number: resolvedEmployeeNumber,\n account: bankAccount, payrollAccount, payroll_account: payrollAccount, bankAccount, bank_account: bankAccount,\n currency, payrollAmount:0, payroll_amount:0, bankAmount:0, bank_amount:0, difference:0,\n status:'Pendiente revisión', category:'posible_cuenta_mal_digitada', subcategory:'nombre_y_monto_coinciden_cuenta_diferente',\n observation:`El nombre y el monto coinciden, pero la cuenta de nómina (${payrollAccount}) es diferente a la cuenta del banco (${bankAccount}).`,\n source_rows:[], source_sheets:new Set(), source_files:new Set(), shipment_numbers:new Set(), plan_numbers:new Set(),\n bank_name_file: pair.bank.bank_name_file || '', bank_account_holder: pair.bank.bank_account_holder || ''\n };\n current.payrollAmount=roundMoney(current.payrollAmount+payrollAmount); current.payroll_amount=current.payrollAmount;\n current.bankAmount=roundMoney(current.bankAmount+bankAmount); current.bank_amount=current.bankAmount; current.difference=moneyDiff(current.payrollAmount,current.bankAmount);\n current.source_rows.push(pair.payroll); if(pair.payroll.source_sheet)current.source_sheets.add(pair.payroll.source_sheet); if(pair.bank.source_file)current.source_files.add(pair.bank.source_file); if(pair.bank.shipment_number)current.shipment_numbers.add(pair.bank.shipment_number); if(pair.bank.plan_number)current.plan_numbers.add(pair.bank.plan_number);\n wrongAccountGroups.set(groupKey,current); continue;\n }\n const exact = sameCent(payrollAmount, bankAmount);\n coreRows.push({id:`pr_match_${pair.payrollIndex+1}_${pair.bankIndex+1}`,employee:pair.payroll.employee_name,employee_name:pair.payroll.employee_name,employeeNumber:resolvedEmployeeNumber,employee_number:resolvedEmployeeNumber,account:bankAccount||payrollAccount,payrollAccount:payrollAccount,payroll_account:payrollAccount,bankAccount:bankAccount,bank_account:bankAccount,currency,payrollAmount,payroll_amount:payrollAmount,bankAmount,bank_amount:bankAmount,difference,status:exact?'Coincide':'Pendiente revisión',category:exact?'coincidencia':'discrepancia',subcategory:exact?'persona_cuenta_y_monto_exactos':'persona_y_cuenta_coinciden_monto_diferente',observation:exact?'Coincidencia de persona, cuenta y monto.':difference>0?'Se pagó de menos.':'Se pagó de más.',source_kind:pair.payroll.source_kind||'',source_sheet:pair.payroll.source_sheet||'',source_file:pair.bank.source_file||'',shipment_number:pair.bank.shipment_number||'',plan_number:pair.bank.plan_number||'',plan_label:pair.bank.plan_label||'',reference:pair.bank.reference||'',bank_name_file:pair.bank.bank_name_file||'',bank_account_holder:pair.bank.bank_account_holder||''});\n}\nfor (let payrollIndex=0; payrollIndex({...row,source_sheets:Array.from(row.source_sheets),source_files:Array.from(row.source_files),shipment_numbers:Array.from(row.shipment_numbers),plan_numbers:Array.from(row.plan_numbers),source_sheet:Array.from(row.source_sheets).join(' / '),source_file:Array.from(row.source_files).join(' / '),shipment_number:Array.from(row.shipment_numbers).join(' / '),plan_number:Array.from(row.plan_numbers).join(' / ')}));\ncoreRows.push(...wrongAccountRows);\n\n// Banco sin Nómina se conserva a nivel de TRANSACCIÓN.\n// Una misma persona/cuenta puede tener más de un pago bancario legítimamente\n// separado; agruparlos reduce artificialmente el número de hallazgos.\nconst bankWithoutPayrollRows = [];\n\nfor (const entry of includedBankRows) {\n if (usedBankKeys.has(entry.key)) continue;\n\n const row = entry.row;\n const displayName =\n bankDisplayName(row);\n\n const rowCurrency =\n clean(row.currency || 'USD')\n .toUpperCase() === 'USD'\n ? 'USD'\n : 'HNL';\n\n const bankAmount =\n roundMoney(row.amount || 0);\n\n const resolvedEmployeeNumber =\n resolvedEmployeeNumberForBankRow(\n row,\n [displayName]\n );\n\n bankWithoutPayrollRows.push({\n id:\n `pr_bank_without_payroll_${entry.index + 1}`,\n employee: displayName,\n employee_name: displayName,\n employeeNumber: resolvedEmployeeNumber,\n employee_number: resolvedEmployeeNumber,\n account: row.account || '',\n payrollAccount: '',\n payroll_account: '',\n bankAccount: row.account || '',\n bank_account: row.account || '',\n currency: rowCurrency,\n payrollAmount: 0,\n payroll_amount: 0,\n bankAmount,\n bank_amount: bankAmount,\n difference:\n roundMoney(0 - bankAmount),\n status: 'Pendiente revisión',\n category: 'banco_sin_nomina',\n subcategory:\n 'pago_banco_sin_registro_nomina',\n observation:\n 'Pago bancario sin registro equivalente en las planillas cargadas.',\n bank_name_file:\n row.bank_name_file || '',\n bank_account_holder:\n row.bank_account_holder || '',\n source_file:\n row.source_file || '',\n shipment_number:\n row.shipment_number || '',\n plan_number:\n row.plan_number || '',\n reference:\n row.reference || '',\n row_number:\n row.row_number || null,\n source_rows: [row],\n });\n}\n\ncoreRows.push(...bankWithoutPayrollRows);\n\nconst nameDifferenceRows = [];\nfor (const entry of includedBankRows) {\n const row = entry.row;\n const rowCurrency=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';\n if (!clean(row.bank_name_file) || !clean(row.bank_account_holder)) continue;\n if (bankNameLooksConsistent(row.bank_name_file, row.bank_account_holder)) continue;\n const resolvedEmployeeNumber =\n resolvedEmployeeNumberForBankRow(\n row,\n [row.bank_name_file, row.bank_account_holder]\n );\n nameDifferenceRows.push({\n id: `pr_bank_name_difference_${entry.index + 1}`,\n employee: row.bank_name_file,\n employee_name: row.bank_name_file,\n employeeNumber: resolvedEmployeeNumber,\n employee_number: resolvedEmployeeNumber,\n account: row.account || '',\n payrollAccount: '',\n payroll_account: '',\n bankAccount: row.account || '',\n bank_account: row.account || '',\n currency: rowCurrency,\n payrollAmount: 0,\n payroll_amount: 0,\n bankAmount: roundMoney(row.amount),\n bank_amount: roundMoney(row.amount),\n difference: 0,\n status: 'Pendiente revisión',\n category: 'diferencia_nombre_banco',\n subcategory: 'nombre_archivo_vs_cuentahabiente',\n observation: `El Nombre en Archivo (${row.bank_name_file}) no coincide con el Nombre del Cuentahabiente (${row.bank_account_holder}).`,\n bank_name_file: row.bank_name_file,\n bank_account_holder: row.bank_account_holder,\n source_file: row.source_file || '',\n shipment_number: row.shipment_number || '',\n plan_number: row.plan_number || '',\n reference: row.reference || '',\n row_number: row.row_number || null,\n });\n}\n\nconst bankWithoutBambooMap = new Map();\nconst bambooMatchDetails = [];\nfor (const entry of includedBankRows) {\n const row = entry.row;\n const linkedNames =\n linkedPayrollNamesByBankKey.get(entry.key) || [];\n\n const linkedEmployeeNumbers =\n linkedPayrollEmployeeNumbersByBankKey.get(\n entry.key\n ) || [];\n\n const decision = resolveBamboo(\n row,\n linkedNames,\n linkedEmployeeNumbers\n );\n bambooMatchDetails.push({\n bank_row_key: entry.key,\n bank_name_file: row.bank_name_file || '',\n bank_account_holder: row.bank_account_holder || '',\n account: row.account || '',\n amount: row.amount || 0,\n linked_payroll_names: linkedNames,\n ...decision,\n });\n if (decision.found) continue;\n\n const displayName = bankDisplayName(row);\n const rowCurrency=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';\n const groupingKey = `${normalizeAccount(row.account)}|${normalizeName(displayName)}|${rowCurrency}`;\n const current = bankWithoutBambooMap.get(groupingKey) || {\n id: `pr_bank_without_bamboo_${bankWithoutBambooMap.size + 1}`,\n bank_name_file: row.bank_name_file || displayName,\n bank_account_holder: row.bank_account_holder || '',\n employee_name: row.bank_name_file || displayName,\n account: row.account || '',\n currency: rowCurrency,\n bank_amount: 0,\n amount: 0,\n status: 'Pendiente revisión',\n category: 'banco_sin_bamboo',\n shipment_numbers: new Set(),\n references: new Set(),\n source_files: new Set(),\n source_rows: [],\n };\n current.bank_amount = roundMoney(current.bank_amount + Number(row.amount || 0));\n current.amount = current.bank_amount;\n if (row.shipment_number) current.shipment_numbers.add(row.shipment_number);\n if (row.reference) current.references.add(row.reference);\n if (row.source_file) current.source_files.add(row.source_file);\n current.source_rows.push(row);\n bankWithoutBambooMap.set(groupingKey, current);\n}\n\nconst bankWithoutBamboo = Array.from(bankWithoutBambooMap.values()).map((row) => ({\n ...row,\n shipment_numbers: Array.from(row.shipment_numbers),\n shipment_number: Array.from(row.shipment_numbers).join(' / '),\n references: Array.from(row.references),\n source_files: Array.from(row.source_files),\n source_file: Array.from(row.source_files).join(' / '),\n difference: roundMoney(0 - row.bank_amount),\n}));\n\nfunction priority(row) {\n const category = clean(row.category).toLowerCase();\n if (category === 'posible_cuenta_mal_digitada') return 1;\n if (category === 'discrepancia') return 2;\n if (category === 'banco_sin_nomina') return 3;\n if (category === 'diferencia_nombre_banco') return 5;\n if (category === 'coincidencia') return 99;\n return 50;\n}\n\nconst rowsFinales = [...coreRows, ...nameDifferenceRows].sort((a, b) => {\n const p = priority(a) - priority(b);\n if (p !== 0) return p;\n return clean(a.employee_name).localeCompare(clean(b.employee_name), 'es');\n});\n\nconst coincidencias = coreRows.filter((row) => row.category === 'coincidencia').length;\nconst discrepancias = coreRows.filter((row) => row.category === 'discrepancia').length;\nconst bancoSinNomina = bankWithoutPayrollRows.length;\nconst diferenciasNombreBanco = nameDifferenceRows.length;\nconst posiblesCuentasMalDigitadas = wrongAccountRows.length;\nconst pendientes = discrepancias + bancoSinNomina + diferenciasNombreBanco;\nconst totalNominaByCurrency = {HNL:0,USD:0};\nfor(const row of payrollRows){const c=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';totalNominaByCurrency[c]=roundMoney(totalNominaByCurrency[c]+Number(row.payroll_amount||0));}\nconst totalBancoByCurrency = {HNL:0,USD:0};\nfor(const entry of includedBankRows){const c=clean(entry.row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';totalBancoByCurrency[c]=roundMoney(totalBancoByCurrency[c]+Number(entry.row.amount||0));}\nconst diferenciaByCurrency={HNL:moneyDiff(totalNominaByCurrency.HNL,totalBancoByCurrency.HNL),USD:moneyDiff(totalNominaByCurrency.USD,totalBancoByCurrency.USD)};\nconst totalNomina=totalNominaByCurrency.HNL || totalNominaByCurrency.USD;\nconst totalBanco=totalBancoByCurrency.HNL || totalBancoByCurrency.USD;\nconst diferenciaTotal=totalNominaByCurrency.HNL||totalBancoByCurrency.HNL?diferenciaByCurrency.HNL:diferenciaByCurrency.USD;\n\nconst bambooSummaryCompact = { ...(data.bamboo || {}) };\ndelete bambooSummaryCompact.employees;\n\nreturn [{\n json: {\n ok: true,\n stage: 'cruce_nomina_banco_puerto_rico',\n errors: [],\n metadata: data.metadata || {},\n summary: {\n coincidencias,\n discrepancias,\n bancoSinNomina,\n bancoSinBamboo: bankWithoutBamboo.length,\n nominaSinCuenta: 0,\n diferenciasNombreBanco,\n posiblesCuentasMalDigitadas,\n pendientes,\n filasNominaValidas: Number(data.payroll?.base_rows_count || data.payroll?.valid_rows_count || 0),\n filasNominaSinCuenta: 0,\n suplementosPotenciales: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaAplicados: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaNoAplicados: 0,\n suplementosNominaAdjuntados: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaNoAdjuntados: Number(data.payroll?.unattached_supplements_count || 0),\n reconciliacionesExactasFinales: coincidencias,\n cuentasNominaAgrupadas: 0,\n transaccionesBanco: includedBankRows.length,\n cuentasBancoAgrupadas: new Set(includedBankRows.map((entry) => normalizeAccount(entry.row.account)).filter(Boolean)).size,\n empleadosBambooPR: Number(data.bamboo?.puerto_rico_count || 0),\n empleadosBambooEnPeriodo: Number(data.bamboo?.active_in_period_count || 0),\n bambooPaginasDescargadas: Number(data.bamboo?.pages_fetched || 0),\n bambooEmpleadosEsperados: Number(data.bamboo?.expected_total || 0),\n bambooDescargaCompleta: Boolean(data.bamboo?.fetch_complete),\n bambooValidacionDisponible: bambooValidationAvailable,\n totalNominaBase: roundMoney(data.payroll?.base_total || 0),\n totalSuplementosAplicados: roundMoney(data.payroll?.supplements_total || 0),\n totalNomina,\n totalBanco,\n diferenciaTotal,\n totalNominaPorMoneda: totalNominaByCurrency,\n totalBancoPorMoneda: totalBancoByCurrency,\n diferenciaTotalPorMoneda: diferenciaByCurrency,\n },\n rows: rowsFinales,\n bankWithoutBamboo,\n nameDifferences: nameDifferenceRows,\n bambooSummary: bambooSummaryCompact,\n reportUrl: null,\n debug: {\n matched_pairs_count: matchedPairs.length,\n included_bank_rows_count: includedBankRows.length,\n excluded_bank_rows_count: excludedBankRows.length,\n excluded_bank_rows_preview: excludedBankRows.slice(0, 100),\n validated_bamboo_aliases_loaded: validatedBambooAliases.length,\n bamboo_matches: bambooMatchDetails,\n rows_with_employee_number: rowsFinales.filter((row) => clean(row.employeeNumber || row.employee_number)).length,\n bamboo_validation_available: bambooValidationAvailable,\n banco_sin_bamboo: bankWithoutBamboo,\n payroll_preview: payrollRows.slice(0, 20),\n bank_included_preview: includedBankRows.slice(0, 20).map((entry) => entry.row),\n },\n },\n}];\n" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -120, - 5200 + 1600, + 512 ], - "id": "f7befa53-9b77-44d3-b0fb-e456328163e5", + "id": "cb9e73f3-01f2-4f5c-a0df-930cbeb2c785", "name": "Cruzar Nómina vs Banco" }, { @@ -271,10 +271,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 120, - 5200 + 1840, + 512 ], - "id": "ffde494e-1ffa-41e6-a76d-3322f684dec7", + "id": "b5d8cdc8-e213-42ab-abfb-a7a1c8c1e933", "name": "Preparar Google Sheet" }, { @@ -317,10 +317,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 360, - 5200 + 2080, + 512 ], - "id": "81fd24de-a18d-4efd-b030-c8f193673745", + "id": "52000c75-ab56-457f-93c6-9881ed06ceb5", "name": "Buscar reporte existente Supabase" }, { @@ -337,10 +337,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 600, - 5200 + 2320, + 512 ], - "id": "170ec328-0a9f-401b-9852-ca472d6ac14d", + "id": "b43f794a-99ce-493c-9351-11efad8ff4e8", "name": "Crear Google Sheet", "retryOnFail": true, "credentials": { @@ -362,10 +362,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 840, - 5200 + 2560, + 512 ], - "id": "5d4d04ba-ee83-4a46-a419-f028729bb7bc", + "id": "529d496a-8835-4400-b6fe-fed68ededa4f", "name": "Leer Google Sheet actual", "retryOnFail": true, "credentials": { @@ -382,10 +382,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 1080, - 5200 + 2800, + 512 ], - "id": "81decb9b-a5ca-4c4b-836f-41a1389cf472", + "id": "a870ce54-541e-4153-8a39-16b40c4473ee", "name": "Preparar actualización Google Sheet" }, { @@ -404,10 +404,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 1320, - 5200 + 3040, + 512 ], - "id": "973e9e0e-a044-4870-8f41-1c02f1ff5412", + "id": "1e8e1a60-3c44-4032-90a2-f730cfc7e923", "name": "Actualizar estructura Google Sheet", "retryOnFail": true, "credentials": { @@ -433,10 +433,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 1560, - 5200 + 3280, + 512 ], - "id": "174a00f9-d50b-439a-ae7f-844d3c5cc53e", + "id": "17a9f487-226d-4e5e-a25f-211307a82eba", "name": "Limpiar Google Sheet", "retryOnFail": true, "credentials": { @@ -462,10 +462,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 1800, - 5200 + 3520, + 512 ], - "id": "7731ef3c-018c-4a73-b4c2-11247e0142b8", + "id": "d6360b18-64d0-4bac-bd8a-0c36408ae17a", "name": "Escribir Google Sheet", "retryOnFail": true, "credentials": { @@ -491,10 +491,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2040, - 5200 + 3760, + 512 ], - "id": "0e27f441-b958-44ad-8f90-b33449c42d03", + "id": "a0548db1-391c-44ac-8ecb-dcf743e43288", "name": "Formatear Google Sheet", "retryOnFail": true, "credentials": { @@ -511,10 +511,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2280, - 5200 + 4000, + 512 ], - "id": "24e9bed0-49df-488f-8b07-d9027c62bf9f", + "id": "33a944c6-427c-49ff-8357-815e04819b67", "name": "Preparar permisos Google Sheet" }, { @@ -531,10 +531,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2520, - 5200 + 4240, + 512 ], - "id": "88b2fb70-5a7b-4343-bc45-b84fb664b21b", + "id": "c6f70254-2628-4bc1-9fce-c69fb28e9fde", "name": "Compartir Google Sheet", "credentials": { "googleOAuth2Api": { @@ -551,10 +551,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2760, - 5200 + 4480, + 512 ], - "id": "0534fec7-fb94-4893-9e50-9a1afdfb843f", + "id": "d61a3429-2611-4bb7-9047-001b70f9bbfe", "name": "Preparar histórico Supabase" }, { @@ -590,10 +590,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 3000, - 5200 + 4720, + 512 ], - "id": "c87f31ff-6179-42c7-904c-e2fc684685f9", + "id": "cd030296-381a-4c2e-ac83-12387336cb99", "name": "Insertar histórico Supabase", "onError": "continueRegularOutput" }, @@ -604,10 +604,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 3240, - 5120 + 4960, + 432 ], - "id": "aaa3a012-5f5f-412d-93fb-890f7093b906", + "id": "acc74d61-7462-4c74-bb5a-8bf5e85700f4", "name": "Preparar respuesta final" }, { @@ -629,23 +629,23 @@ "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.5, "position": [ - 3480, - 5120 + 5200, + 432 ], - "id": "3278f6df-9a9a-443d-a8a5-5267cf38286c", + "id": "bf03d628-bf89-4be8-a451-09ac9d561ebe", "name": "Respond to Webhook" }, { "parameters": { - "jsCode": "const prepared = $('Preparar histórico Supabase').first().json || {};\nconst payload = prepared.supabasePayload || {};\nconst metadata = payload.metadata || {};\nconst summary = payload.summary || {};\nconst reportUpdated = prepared.reportUpdated === true;\n\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction numberValue(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction formatGeneratedAt(date) {\n const timeZone = 'America/Puerto_Rico';\n\n const dateLabel = new Intl.DateTimeFormat('es-PR', {\n timeZone,\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(date);\n\n const timeLabel = new Intl.DateTimeFormat('es-PR', {\n timeZone,\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }).format(date);\n\n const hour24Raw = new Intl.DateTimeFormat('en-US', {\n timeZone,\n hour: '2-digit',\n hour12: false,\n }).format(date);\n\n const hour24 =\n Number(String(hour24Raw).replace(/\\D/g, '')) % 24;\n\n const hourArticle =\n hour24 === 1 || hour24 === 13\n ? 'a la'\n : 'a las';\n\n return `${dateLabel} ${hourArticle} ${timeLabel}`;\n}\n\nfunction metricCard(label, value, accent) {\n return `\n \n \n \n \n \n ${escapeHtml(label)}\n \n\n \n ${numberValue(value).toLocaleString('en-US')}\n \n \n \n \n \n `;\n}\n\nconst countryCode = 'PR';\nconst countryName = 'Puerto Rico';\n\nconst periodLabel =\n payload.period_label ||\n metadata.period_label ||\n [\n payload.year || metadata.year,\n payload.month || metadata.month,\n payload.period_type || metadata.period_type,\n ]\n .filter(Boolean)\n .join(' · ') ||\n 'Período no especificado';\n\nconst executedByName =\n payload.ejecutado_por_nombre ||\n metadata.requested_by_name ||\n 'Usuario GLM';\n\nconst executedByEmail =\n payload.ejecutado_por_email ||\n metadata.requested_by_email ||\n '';\n\nconst reportUrl =\n payload.report_url ||\n prepared.reportUrl ||\n '';\n\nconst discrepancias = numberValue(\n payload.discrepancias ??\n summary.discrepancias\n);\n\nconst bancoSinNomina = numberValue(\n payload.banco_sin_nomina ??\n summary.bancoSinNomina\n);\n\nconst bancoSinBamboo = numberValue(\n payload.banco_sin_bamboo ??\n summary.bancoSinBamboo\n);\n\nconst diferenciasNombreBanco = numberValue(\n metadata.diferencias_nombre_banco ??\n summary.diferenciasNombreBanco\n);\n\nconst nominaSinCuenta = numberValue(\n payload.nomina_sin_cuenta ??\n summary.nominaSinCuenta\n);\n\nconst coincidencias = numberValue(\n payload.coincidencias ??\n summary.coincidencias\n);\n\nconst generatedAt = new Date();\nconst generatedAtLabel =\n formatGeneratedAt(generatedAt);\n\nconst statusLabel =\n String(payload.estado || '').toLowerCase() === 'resuelto'\n ? 'Resuelto'\n : 'Pendiente de revisión';\n\nconst logoUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png';\n\nconst flagUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/bandera-nacional-tela-puerto-rico_113767-1759.avif';\n\nconst subject = reportUpdated\n ? `Reporte actualizado - Cruce de Cuentas ${countryName} - ${periodLabel}`\n : `Nuevo reporte generado - Cruce de Cuentas ${countryName} - ${periodLabel}`;\n\n/*\n * Todos son destinatarios directos.\n * Nadie se envía en CC.\n */\n\nconst to = [\n 'iaracena@gomezleemarketing.com',\n 'jgomez@gomezleemarketing.com',\n 'mgomez@gomezleemarketing.com',\n 'vparamo@gomezleemarketing.com',\n 'ymadera@gomezleemarketing.com',\n 'adminregional@gomezleemarketing.com',\n].join(',');\n\n\n// Paleta oficial GLM.\nconst metricCards = [\n metricCard(\n 'Discrepancias',\n discrepancias,\n '#FF6A13'\n ),\n metricCard(\n 'Banco sin nómina',\n bancoSinNomina,\n '#FF8C00'\n ),\n metricCard(\n 'Banco sin Bamboo',\n bancoSinBamboo,\n '#E87722'\n ),\n metricCard(\n 'Diferencias nombre banco',\n diferenciasNombreBanco,\n '#5B7F95'\n ),\n metricCard(\n 'Nómina sin cuenta',\n nominaSinCuenta,\n '#4F758B'\n ),\n].join('');\n\nconst htmlBody = `\n\n\n\n\n \n \n ${escapeHtml(subject)}\n\n\n\n\n \n \n \n\n \n\n \n \n \n  \n \n \n\n \n \n \n\n \n \n \n \n \n\n \n \n ${reportUpdated ? 'REPORTE ACTUALIZADO' : 'REPORTE GENERADO'}\n \n \n \n \n\n \n\n \n \n\n \n \n \n\n \n\n \n Cruce de Cuentas · ${escapeHtml(countryName)}\n \n\n \n ${escapeHtml(periodLabel)}\n \n\n \n\n \n \n\n \n \n\n \n \n \n\n \n ${reportUpdated ? 'Se actualizó el reporte existente del Portal de Cruce de Cuentas GLM conservando las resoluciones previamente registradas que continúan correspondiendo a los mismos casos.' : 'Se completó una nueva ejecución del Portal de Cruce de Cuentas GLM. Este es el resumen del reporte generado.'}\n \n\n \n \n\n \n \n \n\n \n \n ${metricCards}\n \n \n\n \n \n\n \n \n \n\n \n\n \n\n \n\n \n Ejecutado por\n \n\n \n ${escapeHtml(executedByName)}\n \n\n \n ${escapeHtml(\n executedByEmail ||\n 'Correo no disponible'\n )}\n \n\n \n\n \n\n \n País\n \n\n \n \n\n \n \n \n\n \n\n \n ${escapeHtml(countryName)}\n \n\n \n ${escapeHtml(\n countryCode || '—'\n )}\n \n\n \n\n \n \n\n \n\n \n\n \n\n \n\n \n Período\n \n\n \n ${escapeHtml(periodLabel)}\n \n\n \n ${escapeHtml(generatedAtLabel)}\n \n\n \n\n \n\n \n Estado inicial\n \n\n \n ${escapeHtml(statusLabel)}\n \n\n \n Coincidencias:\n ${coincidencias.toLocaleString('en-US')}\n \n\n \n\n \n\n \n\n \n \n\n \n ${\n reportUrl\n ? `\n \n \n\n \n Abrir reporte en Google Sheets\n \n\n \n \n `\n : ''\n }\n\n \n \n \n\n \n\n \n Notificación automática · Portal Cruce de Cuentas GLM\n
\n Los casos de revisión deben gestionarse directamente en el reporte generado.\n \n\n \n \n\n \n\n \n \n \n\n\n\n`;\n\nreturn [\n {\n json: {\n to,\n subject,\n htmlBody,\n\n notification: {\n country: countryCode,\n countryName,\n flagUrl,\n periodLabel,\n executedByName,\n executedByEmail,\n generatedAt: generatedAt.toISOString(),\n reportUrl,\n\n metrics: {\n discrepancias,\n bancoSinNomina,\n bancoSinBamboo,\n diferenciasNombreBanco,\n nominaSinCuenta,\n coincidencias,\n },\n },\n },\n },\n];" + "jsCode": "const prepared = $('Preparar histórico Supabase').first().json || {};\nconst payload = prepared.supabasePayload || {};\nconst metadata = payload.metadata || {};\nconst summary = payload.summary || {};\nconst reportUpdated = prepared.reportUpdated === true;\n\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction numberValue(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction formatGeneratedAt(date) {\n const timeZone = 'America/Puerto_Rico';\n\n const dateLabel = new Intl.DateTimeFormat('es-PR', {\n timeZone,\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(date);\n\n const timeLabel = new Intl.DateTimeFormat('es-PR', {\n timeZone,\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }).format(date);\n\n const hour24Raw = new Intl.DateTimeFormat('en-US', {\n timeZone,\n hour: '2-digit',\n hour12: false,\n }).format(date);\n\n const hour24 =\n Number(String(hour24Raw).replace(/\\D/g, '')) % 24;\n\n const hourArticle =\n hour24 === 1 || hour24 === 13\n ? 'a la'\n : 'a las';\n\n return `${dateLabel} ${hourArticle} ${timeLabel}`;\n}\n\nfunction metricCard(label, value, accent) {\n return `\n \n \n \n \n \n ${escapeHtml(label)}\n \n\n \n ${numberValue(value).toLocaleString('en-US')}\n \n \n \n \n \n `;\n}\n\nconst countryCode = 'PR';\nconst countryName = 'Puerto Rico';\n\nconst periodLabel =\n payload.period_label ||\n metadata.period_label ||\n [\n payload.year || metadata.year,\n payload.month || metadata.month,\n payload.period_type || metadata.period_type,\n ]\n .filter(Boolean)\n .join(' · ') ||\n 'Período no especificado';\n\nconst executedByName =\n payload.ejecutado_por_nombre ||\n metadata.requested_by_name ||\n 'Usuario GLM';\n\nconst executedByEmail =\n payload.ejecutado_por_email ||\n metadata.requested_by_email ||\n '';\n\nconst reportUrl =\n payload.report_url ||\n prepared.reportUrl ||\n '';\n\nconst discrepancias = numberValue(\n payload.discrepancias ??\n summary.discrepancias\n);\n\nconst bancoSinNomina = numberValue(\n payload.banco_sin_nomina ??\n summary.bancoSinNomina\n);\n\nconst bancoSinBamboo = numberValue(\n payload.banco_sin_bamboo ??\n summary.bancoSinBamboo\n);\n\nconst diferenciasNombreBanco = numberValue(\n metadata.diferencias_nombre_banco ??\n summary.diferenciasNombreBanco\n);\n\nconst nominaSinCuenta = numberValue(\n payload.nomina_sin_cuenta ??\n summary.nominaSinCuenta\n);\n\nconst coincidencias = numberValue(\n payload.coincidencias ??\n summary.coincidencias\n);\n\nconst generatedAt = new Date();\nconst generatedAtLabel =\n formatGeneratedAt(generatedAt);\n\nconst statusLabel =\n String(payload.estado || '').toLowerCase() === 'resuelto'\n ? 'Resuelto'\n : 'Pendiente de revisión';\n\nconst logoUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png';\n\nconst flagUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/bandera-nacional-tela-puerto-rico_113767-1759.avif';\n\nconst subject = reportUpdated\n ? `Reporte actualizado - Cruce de Cuentas ${countryName} - ${periodLabel}`\n : `Nuevo reporte generado - Cruce de Cuentas ${countryName} - ${periodLabel}`;\n\n/*\n * Todos son destinatarios directos.\n * Nadie se envía en CC.\n */\n\nconst to = [\n 'iaracena@gomezleemarketing.com'\n].join(',');\n\n\n// Paleta oficial GLM.\nconst metricCards = [\n metricCard(\n 'Discrepancias',\n discrepancias,\n '#FF6A13'\n ),\n metricCard(\n 'Banco sin nómina',\n bancoSinNomina,\n '#FF8C00'\n ),\n metricCard(\n 'Banco sin Bamboo',\n bancoSinBamboo,\n '#E87722'\n ),\n metricCard(\n 'Diferencias nombre banco',\n diferenciasNombreBanco,\n '#5B7F95'\n ),\n metricCard(\n 'Nómina sin cuenta',\n nominaSinCuenta,\n '#4F758B'\n ),\n].join('');\n\nconst htmlBody = `\n\n\n\n\n \n \n ${escapeHtml(subject)}\n\n\n\n\n \n \n \n\n \n\n \n \n \n  \n \n \n\n \n \n \n\n \n \n \n \n \n\n \n \n ${reportUpdated ? 'REPORTE ACTUALIZADO' : 'REPORTE GENERADO'}\n \n \n \n \n\n \n\n \n \n\n \n \n \n\n \n\n \n Cruce de Cuentas · ${escapeHtml(countryName)}\n \n\n \n ${escapeHtml(periodLabel)}\n \n\n \n\n \n \n\n \n \n\n \n \n \n\n \n ${reportUpdated ? 'Se actualizó el reporte existente del Portal de Cruce de Cuentas GLM conservando las resoluciones previamente registradas que continúan correspondiendo a los mismos casos.' : 'Se completó una nueva ejecución del Portal de Cruce de Cuentas GLM. Este es el resumen del reporte generado.'}\n \n\n \n \n\n \n \n \n\n \n \n ${metricCards}\n \n \n\n \n \n\n \n \n \n\n \n\n \n\n \n\n \n Ejecutado por\n \n\n \n ${escapeHtml(executedByName)}\n \n\n \n ${escapeHtml(\n executedByEmail ||\n 'Correo no disponible'\n )}\n \n\n \n\n \n\n \n País\n \n\n \n \n\n \n \n \n\n \n\n \n ${escapeHtml(countryName)}\n \n\n \n ${escapeHtml(\n countryCode || '—'\n )}\n \n\n \n\n \n \n\n \n\n \n\n \n\n \n\n \n Período\n \n\n \n ${escapeHtml(periodLabel)}\n \n\n \n ${escapeHtml(generatedAtLabel)}\n \n\n \n\n \n\n \n Estado inicial\n \n\n \n ${escapeHtml(statusLabel)}\n \n\n \n Coincidencias:\n ${coincidencias.toLocaleString('en-US')}\n \n\n \n\n \n\n \n\n \n \n\n \n ${\n reportUrl\n ? `\n \n \n\n \n Abrir reporte en Google Sheets\n \n\n \n \n `\n : ''\n }\n\n \n \n \n\n \n\n \n Notificación automática · Portal Cruce de Cuentas GLM\n
\n Los casos de revisión deben gestionarse directamente en el reporte generado.\n \n\n \n \n\n \n\n \n \n \n\n\n\n`;\n\nreturn [\n {\n json: {\n to,\n subject,\n htmlBody,\n\n notification: {\n country: countryCode,\n countryName,\n flagUrl,\n periodLabel,\n executedByName,\n executedByEmail,\n generatedAt: generatedAt.toISOString(),\n reportUrl,\n\n metrics: {\n discrepancias,\n bancoSinNomina,\n bancoSinBamboo,\n diferenciasNombreBanco,\n nominaSinCuenta,\n coincidencias,\n },\n },\n },\n },\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 3240, - 5360 + 4960, + 672 ], - "id": "6875ed54-851a-44b3-b998-25735b5464dd", + "id": "94f01fb4-e536-4b86-aebc-8ab27b61381f", "name": "Preparar correo reporte generado" }, { @@ -660,10 +660,10 @@ "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ - 3480, - 5360 + 5200, + 672 ], - "id": "442d0a94-4369-4bfd-8d8e-dbb9f77e4df3", + "id": "5bd3e192-88b5-400e-acd5-57511f78c440", "name": "Enviar correo reporte generado", "webhookId": "4bcdbd7b-503d-46ac-aeaf-9207f59f01e7", "credentials": { @@ -683,10 +683,10 @@ "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ - -2800, - 4768 + -1088, + 80 ], - "id": "ebbfb113-b7a1-42ff-bedb-bb02ad43ac33", + "id": "43fccfea-0ca0-4500-acbd-259f5bec978e", "name": "📌 PUERTO RICO · V1" }, { @@ -698,10 +698,10 @@ "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ - -1712, - 4688 + 0, + 0 ], - "id": "3f985792-728c-4f1a-baae-18e963312f62", + "id": "aaa2fb59-9745-48b6-9b8b-3d5442493347", "name": "📌 REGLA BANCO PR" }, { @@ -713,10 +713,10 @@ "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ - -2320, - 5616 + -608, + 928 ], - "id": "c1e22489-fa4a-49f8-984d-fa2c497620de", + "id": "c2f319b9-18d2-4b48-90b0-adb64308b513", "name": "📌 ARCHIVOS NÓMINA PR" }, { @@ -728,10 +728,10 @@ "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ - 1672, - 5520 + 3392, + 832 ], - "id": "dd6b181f-198e-4a8a-a363-a0db9d5741b5", + "id": "2fc5ac1d-e386-4997-8e24-7dd5205bc966", "name": "📌 REPORTES" }, { @@ -745,10 +745,10 @@ "type": "n8n-nodes-base.extractFromFile", "typeVersion": 1.1, "position": [ - -1840, - 4960 + -128, + 272 ], - "id": "d9f7fced-ae32-4065-87fb-9f86c8c286f2", + "id": "3ae0b89c-da34-4fdc-aef8-46a4c8a3ff8a", "name": "Extract - PDF Banco PR" }, { @@ -758,10 +758,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -1600, - 4960 + 112, + 272 ], - "id": "aaead29e-f149-443f-80ab-7d6bad0a2b6f", + "id": "15cc9f68-6c58-4ca2-b8bc-67198a69c6f2", "name": "Parsear PDF banco PR" }, { @@ -792,10 +792,10 @@ "type": "n8n-nodes-base.if", "typeVersion": 2.3, "position": [ - -2320, - 5200 + -608, + 512 ], - "id": "e48a9f66-61b5-4880-8f51-4032744e9f8b", + "id": "8b489512-819e-4f62-a6b9-309cdbb42732", "name": "¿Entrada PR válida?" }, { @@ -821,10 +821,10 @@ "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.5, "position": [ - -2080, - 5720 + -368, + 1040 ], - "id": "9a663a01-3ad7-4904-a2ac-239c9c6a2ef8", + "id": "d9247c61-bd3a-4fd8-a706-e15518665037", "name": "Responder error entrada PR" } ], @@ -1183,14 +1183,15 @@ ] } }, - "active": false, + "active": true, "settings": { "executionOrder": "v1", "binaryMode": "separate" }, - "versionId": "1a174b21-9f77-443a-9616-ef028022f4d8", + "versionId": "9b578dec-b1d2-410a-9920-4d888faf128f", "meta": { "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" }, + "id": "1ddUHqgdN3lZQx6T", "tags": [] -} +} \ No newline at end of file diff --git a/Portal de Verificaci├│n de N├│mina - Reportar correcci├│n BambooHR a RRHH - GT TT PA SV HN PR.json b/Portal de Verificaci├│n de N├│mina - Reportar correcci├│n BambooHR a RRHH - GT TT PA SV HN PR.json new file mode 100644 index 0000000..5d1cb81 --- /dev/null +++ b/Portal de Verificaci├│n de N├│mina - Reportar correcci├│n BambooHR a RRHH - GT TT PA SV HN PR.json @@ -0,0 +1,515 @@ +{ + "name": "Portal de Verificación de Nómina - Reportar corrección BambooHR a RRHH - GT TT PA SV HN PR", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "cruce-cuentas-bamboo-correccion", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + 4032, + 2704 + ], + "id": "501c9b4c-9884-43a6-a550-93a17d6b1e57", + "name": "Webhook", + "webhookId": "821fa25f-8b4c-417b-870c-73183194a709" + }, + { + "parameters": { + "jsCode": "const incoming = $input.first().json || {};\nconst rawBody = incoming.body ?? incoming;\n\nlet body = rawBody;\n\nif (rawBody && typeof rawBody === 'object' && typeof rawBody.payload === 'string') {\n try {\n body = JSON.parse(rawBody.payload);\n } catch (error) {\n throw new Error('El payload recibido no contiene JSON válido.');\n }\n}\n\nif (!body || typeof body !== 'object') {\n throw new Error('No se recibió una solicitud válida.');\n}\n\nconst accessToken = String(\n (rawBody && typeof rawBody === 'object' ? rawBody.access_token : '') ||\n body.access_token ||\n ''\n).trim();\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizeName(value) {\n return clean(value)\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst country = clean(body.country).toUpperCase();\nif (!['GT', 'TT', 'PA', 'SV', 'HN', 'PR'].includes(country)) {\n throw new Error('País no permitido para reportar correcciones BambooHR.');\n}\n\nif (!accessToken) {\n throw new Error('No se recibió una sesión autenticada de Supabase.');\n}\n\nif (body.confirmed_same_person !== true) {\n throw new Error('La revisión manual debe confirmar que se trata de la misma persona.');\n}\n\nconst sourceNames = Array.from(new Set([\n ...(Array.isArray(body.source_names) ? body.source_names : []),\n body.source_name,\n body.bank_name_file,\n body.bank_account_holder,\n]\n .map(clean)\n .filter(Boolean)\n .filter((value) => normalizeName(value))));\n\nif (!sourceNames.length) {\n throw new Error('No se recibió el nombre detectado en Banco sin BambooHR.');\n}\n\nconst bambooName = clean(body.bamboo_name);\nif (!bambooName) {\n throw new Error('Debes indicar el nombre correcto en BambooHR.');\n}\n\nreturn [{\n json: {\n accessToken,\n request: {\n country,\n countryName: ({ GT: 'Guatemala', TT: 'Trinidad y Tobago', PA: 'Panamá', SV: 'El Salvador', HN: 'Honduras', PR: 'Puerto Rico' })[country],\n sourceName: clean(body.source_name) || sourceNames[0],\n sourceNames,\n bankNameFile: clean(body.bank_name_file),\n bankAccountHolder: clean(body.bank_account_holder),\n bankAccount: clean(body.bank_account),\n bankAmount: Number.isFinite(Number(body.bank_amount)) ? Number(body.bank_amount) : null,\n currency: clean(body.currency) || ({ GT: 'GTQ', TT: 'TTD', PA: 'USD', SV: 'USD', HN: 'HNL', PR: 'USD' })[country],\n bambooName,\n bambooEmployeeNumber: clean(body.bamboo_employee_number),\n reason: clean(body.reason) || 'Corrección de identidad en BambooHR',\n comment: clean(body.comment),\n executionId: clean(body.execution_id),\n reportUrl: clean(body.report_url),\n periodLabel: clean(body.period_label),\n periodStart: clean(body.period_start),\n periodEnd: clean(body.period_end),\n requestedByNameClaimed: clean(body.requested_by_name),\n requestedByEmailClaimed: clean(body.requested_by_email).toLowerCase(),\n },\n },\n}];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 4272, + 2704 + ], + "id": "9bb2300d-b2ad-44bc-bdcc-bdb09787a70c", + "name": "Preparar solicitud" + }, + { + "parameters": { + "method": "POST", + "url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cruce_cuentas_mi_acceso", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE" + }, + { + "name": "Authorization", + "value": "={{ 'Bearer ' + $('Preparar solicitud').first().json.accessToken }}" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": {}, + "options": { + "timeout": 30000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 4512, + 2704 + ], + "id": "2222f4f8-8341-48d1-b6cf-0d7996c4c20d", + "name": "Validar acceso Supabase", + "retryOnFail": true, + "maxTries": 2, + "waitBetweenTries": 1000 + }, + { + "parameters": { + "jsCode": "const raw = $input.first().json || {};\nconst access = Array.isArray(raw) ? (raw[0] || {}) : raw;\nconst prepared = $('Preparar solicitud').first().json || {};\nconst request = prepared.request || {};\n\nconst email = String(access.email || '').trim().toLowerCase();\nconst countries = Array.isArray(access.paises)\n ? access.paises.map((value) => String(value || '').trim().toUpperCase()).filter(Boolean)\n : [];\n\nif (\n access.ok !== true ||\n access.autenticado !== true ||\n access.autorizado !== true ||\n access.activo !== true ||\n access.acceso_app !== true ||\n !email\n) {\n throw new Error(access.motivo || 'El usuario no tiene acceso autorizado al Cruce de Cuentas.');\n}\n\nif (countries.length && !countries.includes(request.country)) {\n throw new Error(`El usuario autenticado no tiene acceso al país ${request.country}.`);\n}\n\nreturn [{\n json: {\n ...request,\n requestedByName: String(access.nombre || request.requestedByNameClaimed || email).trim(),\n requestedByEmail: email,\n },\n}];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 4752, + 2704 + ], + "id": "4aed5c27-8691-4638-a1eb-96dc648cd557", + "name": "Validar usuario" + }, + { + "parameters": { + "method": "POST", + "url": "https://glm.bamboohr.com/api/v1/reports/custom?format=JSON&onlyCurrent=false", + "authentication": "genericCredentialType", + "genericAuthType": "httpBasicAuth", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Accept", + "value": "application/json" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": { + "title": "Validación manual - Corrección identidad Cruce de Cuentas", + "fields": [ + "firstName", + "middleName", + "lastName", + "displayName", + "location", + "status", + "employeeNumber", + "country" + ] + }, + "options": { + "response": { + "response": { + "responseFormat": "json" + } + }, + "timeout": 300000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 4992, + 2704 + ], + "id": "828893b5-01c1-410e-b8e5-a1d99fa4451e", + "name": "Consultar empleado BambooHR", + "retryOnFail": true, + "maxTries": 3, + "waitBetweenTries": 3000, + "credentials": { + "httpBasicAuth": { + "id": "7VrpNZ2jBLmiJ35q", + "name": "BambooHR GLM Full Access" + } + } + }, + { + "parameters": { + "jsCode": "const request = $('Validar usuario').first().json || {};\nconst raw = $input.first().json || {};\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizeName(value) {\n return clean(value)\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalizeIdentifier(value) {\n return clean(value).toUpperCase().replace(/[^A-Z0-9]/g, '');\n}\n\nfunction countryMatches(employee) {\n const location = normalizeName(\n employee.location ||\n employee.jobInformationLocation ||\n employee.jobLocation ||\n ''\n );\n const country = normalizeName(employee.country || '');\n const combined = `${location} ${country}`.trim();\n\n if (request.country === 'GT') {\n return combined.includes('guatemala');\n }\n\n if (request.country === 'PA') {\n return combined.includes('panama');\n }\n\n if (request.country === 'SV') {\n return combined.includes('el salvador') || combined.includes('salvador');\n }\n\n if (request.country === 'HN') {\n return combined.includes('honduras');\n }\n\n if (request.country === 'PR') {\n return combined.includes('puerto rico') || combined === 'pr';\n }\n\n return combined.includes('trinidad') || combined.includes('tobago');\n}\n\nfunction employeeAliases(employee) {\n const first = clean(employee.firstName || employee.first_name);\n const middle = clean(employee.middleName || employee.middle_name);\n const last = clean(employee.lastName || employee.last_name);\n const display = clean(employee.displayName || employee.fullName || employee.full_name);\n\n return Array.from(new Set([\n display,\n [first, middle, last].filter(Boolean).join(' '),\n [first, last].filter(Boolean).join(' '),\n ].map(clean).filter(Boolean)));\n}\n\nconst employees = Array.isArray(raw.employees)\n ? raw.employees\n : Array.isArray(raw.data?.employees)\n ? raw.data.employees\n : [];\n\nif (!employees.length) {\n throw new Error('BambooHR no devolvió empleados para validar la corrección.');\n}\n\nconst candidates = employees.filter(countryMatches);\nif (!candidates.length) {\n throw new Error(`No se encontraron empleados de ${request.countryName} en BambooHR.`);\n}\n\nconst requestedNumber = normalizeIdentifier(request.bambooEmployeeNumber);\nlet matches = [];\nlet matchedBy = '';\n\nif (requestedNumber) {\n matches = candidates.filter((employee) =>\n normalizeIdentifier(employee.employeeNumber || employee.employee_number) === requestedNumber\n );\n matchedBy = 'employee_number';\n}\n\nif (!matches.length) {\n const targetName = normalizeName(request.bambooName);\n matches = candidates.filter((employee) =>\n employeeAliases(employee).some((alias) => normalizeName(alias) === targetName)\n );\n matchedBy = 'exact_bamboo_name';\n}\n\nif (matches.length !== 1) {\n if (matches.length > 1) {\n throw new Error('La identificación en BambooHR es ambigua. Indica el Employee Number para seleccionar una sola persona.');\n }\n\n throw new Error(\n 'No se encontró exactamente ese empleado en BambooHR para el país seleccionado. Revisa el nombre o indica el Employee Number.'\n );\n}\n\nconst employee = matches[0];\nconst aliases = employeeAliases(employee);\nconst actualName = clean(employee.displayName) || aliases[0] || request.bambooName;\nconst actualEmployeeNumber = clean(employee.employeeNumber || employee.employee_number);\nconst bambooId = clean(employee.employeeId || employee.id);\nconst now = new Date().toISOString();\n\nconst recipientsByCountry = {\n GT: ['haguirre@gomezleemarketing.com'],\n TT: ['lnicomejack@gomezleemarketing.com'],\n PA: ['dpenalba@gomezleemarketing.com'],\n SV: ['cmalta@gomezleemarketing.com'],\n HN: ['mchang@gomezleemarketing.com'],\n PR: ['nlaureano@gomezleemarketing.com'],\n};\nconst recipients = recipientsByCountry[request.country] || [];\n\nconst aliasPayload = request.sourceNames.map((sourceName) => ({\n pais: request.country,\n nombre_origen: sourceName,\n nombre_origen_normalizado: normalizeName(sourceName),\n cuenta_bancaria: String(request.bankAccount || '').replace(/[^0-9A-Za-z]+/g, ''),\n bamboo_employee_number: actualEmployeeNumber || null,\n bamboo_employee_id: bambooId || null,\n bamboo_nombre: actualName,\n motivo: request.reason,\n comentario: request.comment || null,\n activo: true,\n validado_por_email: request.requestedByEmail,\n validado_por_nombre: request.requestedByName,\n last_reported_at: now,\n updated_at: now,\n}));\n\nreturn [{\n json: {\n request,\n matchedBy,\n employee: {\n bambooId,\n employeeNumber: actualEmployeeNumber,\n name: actualName,\n status: clean(employee.status),\n location: clean(employee.location),\n },\n recipients,\n aliasPayload,\n },\n}];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 5232, + 2704 + ], + "id": "4c4b60ba-b8da-440f-96fe-c623878635c6", + "name": "Resolver empleado BambooHR" + }, + { + "parameters": { + "method": "POST", + "url": "https://dbit.digitalcompass.agency/rest/v1/cruce_cuentas_bamboo_aliases?on_conflict=pais,nombre_origen_normalizado,cuenta_bancaria", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Authorization", + "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "resolution=merge-duplicates,return=representation" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $('Resolver empleado BambooHR').first().json.aliasPayload }}", + "options": { + "timeout": 30000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 5472, + 2704 + ], + "id": "a11df008-2590-40bf-abb7-969ce88990ac", + "name": "Guardar alias Supabase", + "retryOnFail": true, + "maxTries": 2, + "waitBetweenTries": 1000 + }, + { + "parameters": { + "jsCode": "const resolved = $('Resolver empleado BambooHR').first().json || {};\nconst request = resolved.request || {};\nconst employee = resolved.employee || {};\nconst aliasResponseItems = $input.all().map((item) => item.json || {});\n\nfunction flattenRows(items) {\n const rows = [];\n for (const item of items) {\n if (Array.isArray(item)) rows.push(...item);\n else if (Array.isArray(item.data)) rows.push(...item.data);\n else rows.push(item);\n }\n return rows.filter((row) => row && typeof row === 'object');\n}\n\nconst aliasRows = flattenRows(aliasResponseItems);\nconst aliasIds = aliasRows\n .map((row) => row.id)\n .filter(Boolean);\n\nconst requestPayload = {\n pais: request.country,\n nombre_origen_principal: request.sourceName,\n nombres_origen: request.sourceNames,\n cuenta_bancaria: request.bankAccount || null,\n monto_banco: request.bankAmount,\n moneda: request.currency,\n bamboo_employee_number: employee.employeeNumber || null,\n bamboo_employee_id: employee.bambooId || null,\n bamboo_nombre: employee.name,\n motivo: request.reason,\n comentario: request.comment || null,\n execution_id: request.executionId || null,\n report_url: request.reportUrl || null,\n period_label: request.periodLabel || null,\n period_start: request.periodStart || null,\n period_end: request.periodEnd || null,\n solicitado_por_email: request.requestedByEmail,\n solicitado_por_nombre: request.requestedByName,\n destinatarios_rrhh: resolved.recipients || [],\n alias_ids: aliasIds,\n estado: 'pendiente_notificacion',\n correo_enviado: false,\n};\n\nreturn [{ json: { requestPayload, aliasIds } }];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 5712, + 2704 + ], + "id": "deef7899-7afe-4fc9-b91f-502784b3f4fb", + "name": "Preparar auditoría" + }, + { + "parameters": { + "method": "POST", + "url": "https://dbit.digitalcompass.agency/rest/v1/cruce_cuentas_bamboo_correcciones", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Authorization", + "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=representation" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $json.requestPayload }}", + "options": { + "timeout": 30000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 5952, + 2704 + ], + "id": "3a28062c-3bfd-4e78-800e-b4ecd6df10fb", + "name": "Guardar solicitud Supabase", + "retryOnFail": true, + "maxTries": 2, + "waitBetweenTries": 1000 + }, + { + "parameters": { + "jsCode": "const resolved = $('Resolver empleado BambooHR').first().json || {};\nconst request = resolved.request || {};\nconst employee = resolved.employee || {};\nconst auditInput = $input.all().map((item) => item.json || {});\n\nfunction firstObject(value) {\n if (Array.isArray(value)) return value[0] || {};\n if (value?.data && Array.isArray(value.data)) return value.data[0] || {};\n return value || {};\n}\n\nconst auditRow = firstObject(auditInput[0]);\nconst requestId = String(auditRow.id || '');\nif (!requestId) {\n throw new Error('Supabase no devolvió el ID de la solicitud de corrección.');\n}\n\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nconst logoUrl = 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png';\nconst flagUrl = request.country === 'TT'\n ? 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_Trinidad_and_Tobago.svg.webp'\n : request.country === 'PA'\n ? 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_Panama.svg'\n : request.country === 'SV'\n ? 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_El_Salvador.svg.webp'\n : request.country === 'HN'\n ? 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Bandera%20de%20Honduras.webp'\n : request.country === 'PR'\n ? 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/bandera-nacional-tela-puerto-rico_113767-1759.avif'\n : 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_Guatemala.svg.webp';\n\nconst to = (resolved.recipients || []).join(',');\nconst subject = `Corrección requerida en BambooHR - ${request.countryName} - ${request.sourceName}`;\n\nconst reportButton = request.reportUrl\n ? `Abrir reporte de Cruce de Cuentas`\n : '';\n\nconst htmlBody = `\n\n\n\n\n
\n\n\n
 
\n\n\n\n
\"GomezLee\"Bandera
\n
\n
Corrección de identidad · BambooHR
\n

Revisión solicitada para ${escapeHtml(request.countryName)}

\n

Durante la revisión manual de Banco sin BambooHR se confirmó que el pago corresponde a una persona existente en BambooHR, pero su nombre no está permitiendo identificarla correctamente en el cruce.

\n\n\n\n\n\n\n\n\n
Nombre detectado${escapeHtml(request.sourceName)}
Empleado en BambooHR${escapeHtml(employee.name)}
Employee Number${escapeHtml(employee.employeeNumber || 'No disponible')}
Motivo${escapeHtml(request.reason)}
Período${escapeHtml(request.periodLabel || 'No especificado')}
Reportado por${escapeHtml(request.requestedByName)} · ${escapeHtml(request.requestedByEmail)}
\n\n${request.comment ? `
Comentario: ${escapeHtml(request.comment)}
` : ''}\n\n

Por favor, revisen y corrijan el nombre o la información correspondiente en BambooHR. La equivalencia validada ya quedó registrada en el Cruce de Cuentas para evitar que este mismo falso positivo se repita mientras se realiza la corrección.

\n\n${reportButton ? `
${reportButton}
` : ''}\n\n
\n
Notificación automática · Portal Cruce de Cuentas GLM · Uso interno
\n
\n
\n`;\n\nreturn [{\n json: {\n requestId,\n to,\n subject,\n htmlBody,\n country: request.country,\n countryName: request.countryName,\n aliasCount: Array.isArray(resolved.aliasPayload) ? resolved.aliasPayload.length : 0,\n },\n}];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 6192, + 2704 + ], + "id": "6fa9b4f3-b2a2-4ebf-bc73-3fbf06fa7347", + "name": "Preparar correo RRHH" + }, + { + "parameters": { + "sendTo": "={{$json.to}}", + "subject": "={{$json.subject}}", + "message": "={{$json.htmlBody}}", + "options": { + "appendAttribution": false + } + }, + "type": "n8n-nodes-base.gmail", + "typeVersion": 2.2, + "position": [ + 6432, + 2704 + ], + "id": "be28e0b5-8b88-4cbe-a1e1-3671f452d608", + "name": "Enviar correo RRHH", + "retryOnFail": true, + "maxTries": 3, + "waitBetweenTries": 2000, + "webhookId": "f1d0bb21-fe2a-4742-9dcf-6d6f5eb60fa3", + "credentials": { + "gmailOAuth2": { + "id": "UDcO1FLJqA453V2D", + "name": "Gmail account 3" + } + } + }, + { + "parameters": { + "method": "PATCH", + "url": "={{ 'https://dbit.digitalcompass.agency/rest/v1/cruce_cuentas_bamboo_correcciones?id=eq.' + $('Preparar correo RRHH').first().json.requestId }}", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Authorization", + "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=minimal" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ { correo_enviado: true, correo_enviado_at: new Date().toISOString(), estado: 'notificado_rrhh' } }}", + "options": { + "timeout": 30000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 6672, + 2704 + ], + "id": "69eb67cd-4465-4cc5-8d2b-3bf636b6aa96", + "name": "Marcar correo enviado", + "retryOnFail": true, + "maxTries": 2, + "waitBetweenTries": 1000 + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{ { ok: true, message: 'Caso validado, equivalencia registrada y correo enviado a RRHH.', country: $('Preparar correo RRHH').first().json.country, countryName: $('Preparar correo RRHH').first().json.countryName, aliasCount: $('Preparar correo RRHH').first().json.aliasCount, requestId: $('Preparar correo RRHH').first().json.requestId } }}", + "options": { + "responseCode": 200, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 6912, + 2704 + ], + "id": "f7794d83-3fcf-4b0d-a4b8-a2df39a448fa", + "name": "Respond to Webhook" + } + ], + "pinData": {}, + "connections": { + "Webhook": { + "main": [ + [ + { + "node": "Preparar solicitud", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar solicitud": { + "main": [ + [ + { + "node": "Validar acceso Supabase", + "type": "main", + "index": 0 + } + ] + ] + }, + "Validar acceso Supabase": { + "main": [ + [ + { + "node": "Validar usuario", + "type": "main", + "index": 0 + } + ] + ] + }, + "Validar usuario": { + "main": [ + [ + { + "node": "Consultar empleado BambooHR", + "type": "main", + "index": 0 + } + ] + ] + }, + "Consultar empleado BambooHR": { + "main": [ + [ + { + "node": "Resolver empleado BambooHR", + "type": "main", + "index": 0 + } + ] + ] + }, + "Resolver empleado BambooHR": { + "main": [ + [ + { + "node": "Guardar alias Supabase", + "type": "main", + "index": 0 + } + ] + ] + }, + "Guardar alias Supabase": { + "main": [ + [ + { + "node": "Preparar auditoría", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar auditoría": { + "main": [ + [ + { + "node": "Guardar solicitud Supabase", + "type": "main", + "index": 0 + } + ] + ] + }, + "Guardar solicitud Supabase": { + "main": [ + [ + { + "node": "Preparar correo RRHH", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar correo RRHH": { + "main": [ + [ + { + "node": "Enviar correo RRHH", + "type": "main", + "index": 0 + } + ] + ] + }, + "Enviar correo RRHH": { + "main": [ + [ + { + "node": "Marcar correo enviado", + "type": "main", + "index": 0 + } + ] + ] + }, + "Marcar correo enviado": { + "main": [ + [ + { + "node": "Respond to Webhook", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": true, + "settings": { + "executionOrder": "v1", + "binaryMode": "separate" + }, + "versionId": "5407cdef-d773-4055-aa6c-23a6d413e663", + "meta": { + "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" + }, + "id": "0yaiagL1tWdhRUXy", + "tags": [] +} diff --git a/README_RD_READY.md b/README_RD_READY.md new file mode 100644 index 0000000..be22cba --- /dev/null +++ b/README_RD_READY.md @@ -0,0 +1,20 @@ +# RD READY — archivos que debes usar + +Para desplegar República Dominicana, consulta primero: + +- `IMPLEMENTACION_REPUBLICA_DOMINICANA_READY.md` +- `VALIDACION_REPUBLICA_DOMINICANA_FINAL.md` +- `SUPABASE_Republica_Dominicana_READY.sql` +- carpeta `workflows_n8n/` + +Workflows nuevos/actualizados a importar: + +- `Portal de Verificación de Nómina - República Dominicana.json` +- `Portal de Verificación de Nómina República Dominicana - Históricos.json` +- `Portal de Verificación de Nómina República Dominicana - Envío de Reporte.json` +- `Portal de Verificación de Nómina - Analizar Nómina con Gemini GT TT PA SV HN PR RD.json` +- `Portal de Verificación de Nómina - Reportar corrección BambooHR a RRHH - GT TT PA SV HN PR RD.json` + +RRHH RD: Noralmy Laureano — `nlaureano@gomezleemarketing.com`. + +No desplegar un `dist` viejo. Generar uno nuevo desde este código fuente con `npm ci && npm run build` en el entorno de despliegue. diff --git a/SUPABASE_Republica_Dominicana_READY.sql b/SUPABASE_Republica_Dominicana_READY.sql new file mode 100644 index 0000000..b42eea2 --- /dev/null +++ b/SUPABASE_Republica_Dominicana_READY.sql @@ -0,0 +1,311 @@ +-- ============================================================ +-- CRUCE DE CUENTAS GLM · HABILITAR REPÚBLICA DOMINICANA (RD) +-- GT + TT + PA + SV + HN + PR + RD +-- ============================================================ +-- Ejecutar una sola vez en el SQL Editor del Supabase empresarial. +-- Es idempotente respecto a RD: conserva datos existentes y puede +-- volver a ejecutarse si se interrumpe antes del COMMIT. + +begin; + +-- 1) Validar tablas requeridas y ampliar constraints de país. +do $$ +declare r record; +begin + if to_regclass('public.cruce_cuentas_bamboo_aliases') is null then raise exception 'No existe public.cruce_cuentas_bamboo_aliases.'; end if; + if to_regclass('public.cruce_cuentas_bamboo_correcciones') is null then raise exception 'No existe public.cruce_cuentas_bamboo_correcciones.'; end if; + if to_regclass('public.cruces_cuentas_gt_reportes') is null then raise exception 'No existe public.cruces_cuentas_gt_reportes.'; end if; + if to_regclass('public.cruce_cuentas_usuarios_autorizados') is null then raise exception 'No existe public.cruce_cuentas_usuarios_autorizados.'; end if; + + -- Alias BambooHR. + for r in + select conname + from pg_constraint + where conrelid='public.cruce_cuentas_bamboo_aliases'::regclass + and contype='c' + and pg_get_constraintdef(oid) ilike '%pais%' + and pg_get_constraintdef(oid) ilike '%GT%' + and pg_get_constraintdef(oid) not ilike '%RD%' + loop + execute format('alter table public.cruce_cuentas_bamboo_aliases drop constraint %I',r.conname); + end loop; + alter table public.cruce_cuentas_bamboo_aliases drop constraint if exists ck_cruce_cuentas_bamboo_aliases_pais; + alter table public.cruce_cuentas_bamboo_aliases + add constraint ck_cruce_cuentas_bamboo_aliases_pais + check (upper(trim(pais)) in ('GT','TT','PA','SV','HN','PR','RD')); + + -- Solicitudes/correcciones BambooHR. + for r in + select conname + from pg_constraint + where conrelid='public.cruce_cuentas_bamboo_correcciones'::regclass + and contype='c' + and pg_get_constraintdef(oid) ilike '%pais%' + and pg_get_constraintdef(oid) ilike '%GT%' + and pg_get_constraintdef(oid) not ilike '%RD%' + loop + execute format('alter table public.cruce_cuentas_bamboo_correcciones drop constraint %I',r.conname); + end loop; + alter table public.cruce_cuentas_bamboo_correcciones drop constraint if exists ck_cruce_cuentas_bamboo_correcciones_pais; + alter table public.cruce_cuentas_bamboo_correcciones + add constraint ck_cruce_cuentas_bamboo_correcciones_pais + check (upper(trim(pais)) in ('GT','TT','PA','SV','HN','PR','RD')); + + -- Históricos multi-país (el nombre de la tabla es legado). + for r in + select conname + from pg_constraint + where conrelid='public.cruces_cuentas_gt_reportes'::regclass + and contype='c' + and pg_get_constraintdef(oid) ilike '%country%' + and pg_get_constraintdef(oid) ilike '%GT%' + and pg_get_constraintdef(oid) not ilike '%RD%' + loop + execute format('alter table public.cruces_cuentas_gt_reportes drop constraint %I',r.conname); + end loop; + alter table public.cruces_cuentas_gt_reportes drop constraint if exists ck_cruces_cuentas_reportes_country; + alter table public.cruces_cuentas_gt_reportes + add constraint ck_cruces_cuentas_reportes_country + check (country is null or upper(trim(country)) in ('GT','TT','PA','SV','HN','PR','RD')); + + -- Accesos: text[] de países habilitados. + alter table public.cruce_cuentas_usuarios_autorizados drop constraint if exists cruce_cuentas_paises_validos_check; + alter table public.cruce_cuentas_usuarios_autorizados + add constraint cruce_cuentas_paises_validos_check + check (paises is null or paises <@ array['GT','TT','PA','SV','HN','PR','RD']::text[]); +end; +$$; + +-- 2) Dar RD a todos los usuarios actualmente autorizados, preservando permisos. +update public.cruce_cuentas_usuarios_autorizados +set paises = case + when paises is null then array['GT','TT','PA','SV','HN','PR','RD']::text[] + when not ('RD'=any(paises)) then array_append(paises,'RD') + else paises +end, +updated_at = now(); + +-- 3) Alias BambooHR activos: habilitar RD en la función compartida. +create or replace function public.cruce_cuentas_bamboo_aliases_activos(p_pais text) +returns jsonb +language sql +stable +security definer +set search_path=public +as $$ + select jsonb_build_object( + 'ok',true, + 'pais',upper(trim(coalesce(p_pais,''))), + 'aliases',coalesce( + jsonb_agg( + jsonb_build_object( + 'id',a.id, + 'pais',a.pais, + 'nombre_origen',a.nombre_origen, + 'nombre_origen_normalizado',a.nombre_origen_normalizado, + 'cuenta_bancaria',a.cuenta_bancaria, + 'bamboo_employee_number',a.bamboo_employee_number, + 'bamboo_employee_id',a.bamboo_employee_id, + 'bamboo_nombre',a.bamboo_nombre, + 'motivo',a.motivo, + 'activo',a.activo + ) order by a.updated_at desc + ) filter (where a.id is not null), + '[]'::jsonb + ) + ) + from public.cruce_cuentas_bamboo_aliases a + where a.activo=true + and a.pais=upper(trim(coalesce(p_pais,''))) + and upper(trim(coalesce(p_pais,''))) in ('GT','TT','PA','SV','HN','PR','RD'); +$$; +revoke all on function public.cruce_cuentas_bamboo_aliases_activos(text) from public,anon,authenticated; +grant execute on function public.cruce_cuentas_bamboo_aliases_activos(text) to service_role; + +-- 4) Históricos paginados multi-país, incluyendo RD. +create index if not exists idx_cruces_cuentas_reportes_country_created + on public.cruces_cuentas_gt_reportes(country,created_at desc); +create index if not exists idx_cruces_cuentas_reportes_country_status_created + on public.cruces_cuentas_gt_reportes(country,estado,created_at desc); + +create or replace function public.cruce_cuentas_get_historicos( + p_country text, + p_page integer default 1, + p_page_size integer default 10, + p_search text default null, + p_status text default null +) +returns jsonb +language plpgsql +security definer +set search_path=public +as $$ +declare + v_country text := upper(trim(coalesce(p_country,''))); + v_page integer := greatest(coalesce(p_page,1),1); + v_page_size integer := least(greatest(coalesce(p_page_size,10),1),100); + v_offset integer; + v_search text := nullif(trim(coalesce(p_search,'')),''); + v_status text := nullif(trim(coalesce(p_status,'')),''); + v_total bigint; + v_filtered_total bigint; + v_reports jsonb; +begin + if v_country not in ('GT','TT','PA','SV','HN','PR','RD') then + raise exception 'País no permitido: %',v_country; + end if; + + v_offset := (v_page-1)*v_page_size; + + select count(*) into v_total + from public.cruces_cuentas_gt_reportes r + where upper(coalesce(r.country,'GT'))=v_country; + + select count(*) into v_filtered_total + from public.cruces_cuentas_gt_reportes r + where upper(coalesce(r.country,'GT'))=v_country + and (v_status is null or r.estado=v_status) + and ( + v_search is null + or coalesce(r.period_label,'') ilike '%'||v_search||'%' + or coalesce(r.payroll_file_name,'') ilike '%'||v_search||'%' + or coalesce(r.ejecutado_por_nombre,'') ilike '%'||v_search||'%' + or coalesce(r.resuelto_por_nombre,'') ilike '%'||v_search||'%' + or r.id::text ilike '%'||v_search||'%' + ); + + select coalesce( + jsonb_agg((to_jsonb(q)-'detalle_banco_sin_bamboo') order by q.created_at desc), + '[]'::jsonb + ) into v_reports + from ( + select r.* + from public.cruces_cuentas_gt_reportes r + where upper(coalesce(r.country,'GT'))=v_country + and (v_status is null or r.estado=v_status) + and ( + v_search is null + or coalesce(r.period_label,'') ilike '%'||v_search||'%' + or coalesce(r.payroll_file_name,'') ilike '%'||v_search||'%' + or coalesce(r.ejecutado_por_nombre,'') ilike '%'||v_search||'%' + or coalesce(r.resuelto_por_nombre,'') ilike '%'||v_search||'%' + or r.id::text ilike '%'||v_search||'%' + ) + order by r.created_at desc + limit v_page_size offset v_offset + ) q; + + return jsonb_build_object( + 'ok',true, + 'country',v_country, + 'page',v_page, + 'page_size',v_page_size, + 'total',v_total, + 'filtered_total',v_filtered_total, + 'total_pages',greatest(ceil(v_filtered_total::numeric/v_page_size)::integer,1), + 'reports',v_reports + ); +end; +$$; +revoke all on function public.cruce_cuentas_get_historicos(text,integer,integer,text,text) from public,anon; +grant execute on function public.cruce_cuentas_get_historicos(text,integer,integer,text,text) to authenticated; + +-- 5) Detalle Banco sin BambooHR de históricos, incluyendo RD. +create or replace function public.cruce_cuentas_get_banco_sin_bamboo_reporte( + p_report_id text, + p_country text +) +returns jsonb +language plpgsql +stable +security definer +set search_path=public +as $$ +declare + v_country text := upper(trim(coalesce(p_country,''))); + v_report public.cruces_cuentas_gt_reportes%rowtype; + v_corrections jsonb := '[]'::jsonb; +begin + if auth.uid() is null then raise exception 'No autenticado.'; end if; + if v_country not in ('GT','TT','PA','SV','HN','PR','RD') then raise exception 'País no permitido: %',v_country; end if; + + select r.* into v_report + from public.cruces_cuentas_gt_reportes r + where r.id::text=trim(coalesce(p_report_id,'')) + and upper(coalesce(r.country,'GT'))=v_country + limit 1; + + if not found then + return jsonb_build_object('ok',false,'message','No se encontró el reporte solicitado.'); + end if; + + select coalesce( + jsonb_agg( + jsonb_build_object( + 'id',c.id, + 'pais',c.pais, + 'nombre_origen_principal',c.nombre_origen_principal, + 'nombres_origen',c.nombres_origen, + 'cuenta_bancaria',c.cuenta_bancaria, + 'bamboo_employee_number',c.bamboo_employee_number, + 'bamboo_nombre',c.bamboo_nombre, + 'estado',c.estado, + 'correo_enviado',c.correo_enviado, + 'correo_enviado_at',c.correo_enviado_at, + 'created_at',c.created_at + ) order by c.created_at desc + ), + '[]'::jsonb + ) into v_corrections + from public.cruce_cuentas_bamboo_correcciones c + where c.pais=v_country + and ( + c.execution_id=v_report.id::text + or ( + nullif(trim(coalesce(c.execution_id,'')),'') is null + and nullif(trim(coalesce(c.report_url,'')),'') is not null + and c.report_url=v_report.report_url + ) + ); + + return jsonb_build_object( + 'ok',true, + 'report',jsonb_build_object( + 'id',v_report.id, + 'country',v_report.country, + 'period_label',v_report.period_label, + 'period_start',v_report.period_start, + 'period_end',v_report.period_end, + 'report_url',v_report.report_url, + 'banco_sin_bamboo',v_report.banco_sin_bamboo + ), + 'cases',coalesce(v_report.detalle_banco_sin_bamboo,'[]'::jsonb), + 'corrections',v_corrections + ); +end; +$$; +revoke all on function public.cruce_cuentas_get_banco_sin_bamboo_reporte(text,text) from public,anon; +grant execute on function public.cruce_cuentas_get_banco_sin_bamboo_reporte(text,text) to authenticated; + +commit; + +-- ============================================================ +-- VALIDACIÓN (solo lectura) +-- ============================================================ +select email,nombre,paises +from public.cruce_cuentas_usuarios_autorizados +order by email; + +select conname, pg_get_constraintdef(oid) as definicion +from pg_constraint +where conrelid in ( + 'public.cruce_cuentas_bamboo_aliases'::regclass, + 'public.cruce_cuentas_bamboo_correcciones'::regclass, + 'public.cruces_cuentas_gt_reportes'::regclass, + 'public.cruce_cuentas_usuarios_autorizados'::regclass +) + and contype='c' + and (pg_get_constraintdef(oid) ilike '%pais%' or pg_get_constraintdef(oid) ilike '%country%') +order by conname; + +select public.cruce_cuentas_get_historicos('RD',1,10,null,null) as historicos_rd; diff --git a/VALIDACION_PUERTO_RICO_EMPLOYEE_NUMBER_FIX.md b/VALIDACION_PUERTO_RICO_EMPLOYEE_NUMBER_FIX.md new file mode 100644 index 0000000..0ea57e2 --- /dev/null +++ b/VALIDACION_PUERTO_RICO_EMPLOYEE_NUMBER_FIX.md @@ -0,0 +1,17 @@ +# Puerto Rico — validación final del cruce + +Corrección aplicada al workflow principal `Portal de Verificación de Nómina - Puerto Rico`: + +- La lógica de conciliación, montos, cuentas y categorías no fue modificada. +- Las filas devueltas a la app ahora reutilizan la resolución de identidad contra BambooHR para completar `employeeNumber` / `employee_number` cuando la nómina no lo trae. +- Se aplica a coincidencias, discrepancias, posibles cuentas mal digitadas, nómina sin pago bancario y banco sin nómina cuando existe una identificación BambooHR confiable. +- `Banco sin BambooHR` conserva su semántica: no se inventa Employee Number cuando la identidad no pudo validarse. +- La fila visual vacía previa a los encabezados y las celdas vacías de `Resolución` permanecen vacías. El valor interno `17` observado al inspeccionar el XLSX era el índice de la cadena compartida vacía (`sharedStrings[17] = ""`), no contenido visible del reporte. + +Validaciones estáticas realizadas: + +- JSON válido. +- 37 nodos y 30 grupos de conexiones conservados. +- Sin referencias a nodos inexistentes. +- 13 Code Nodes analizados sintácticamente sin errores. +- Endpoint principal conservado: `nominapr-bamboo-test`. diff --git a/VALIDACION_RD_REGRESION.json b/VALIDACION_RD_REGRESION.json new file mode 100644 index 0000000..96e9f5c --- /dev/null +++ b/VALIDACION_RD_REGRESION.json @@ -0,0 +1,283 @@ +{ + "generated_at": "2026-09-12", + "country": "RD", + "country_name": "República Dominicana", + "currency": "DOP", + "training_references": { + "Junio 15": { + "matches": 257, + "discrepancies": 1, + "bank_without_payroll": 0, + "bank_without_bamboo": 7, + "payroll_without_account": 0, + "name_differences": 2, + "wrong_accounts": 0, + "pending": 3, + "payroll_total": 4665382.94, + "bank_total": 4644692.08, + "difference": 20690.86 + }, + "Junio 30": { + "matches": 213, + "discrepancies": 1, + "bank_without_payroll": 0, + "bank_without_bamboo": 8, + "payroll_without_account": 0, + "name_differences": 2, + "wrong_accounts": 0, + "pending": 3, + "payroll_total": 4148894.42, + "bank_total": 4134786.57, + "difference": 14107.85 + }, + "Julio 15": { + "matches": 213, + "discrepancies": 0, + "bank_without_payroll": 0, + "bank_without_bamboo": 8, + "payroll_without_account": 0, + "name_differences": 2, + "wrong_accounts": 0, + "pending": 2, + "payroll_total": 4008539.03, + "bank_total": 4008539.04, + "difference": -0.01 + }, + "Julio 30": { + "matches": 262, + "discrepancies": 0, + "bank_without_payroll": 0, + "bank_without_bamboo": 8, + "payroll_without_account": 0, + "name_differences": 2, + "wrong_accounts": 0, + "pending": 2, + "payroll_total": 4431266.35, + "bank_total": 4431266.42, + "difference": -0.07 + } + }, + "offline_regression": [ + { + "period": "Junio 15", + "payroll_rows": 210, + "supplement_rows": 48, + "all_bank_rows": 258, + "processed_bank_rows": 257, + "rejected_bank_rows": 1, + "matches": 257, + "coincidencias": 257, + "discrepancias": 1, + "banco_sin_nomina": 0, + "nomina_sin_cuenta": 0, + "possible_wrong_accounts": 0, + "name_differences": 2, + "total_nomina": 4665382.94, + "total_banco": 4644692.08, + "diferencia": 20690.86, + "discrepancy_people": [ + "Angel Leonardo Baez" + ], + "unused_bank": [], + "wrong": [] + }, + { + "period": "Junio 30", + "payroll_rows": 214, + "supplement_rows": 0, + "all_bank_rows": 213, + "processed_bank_rows": 213, + "rejected_bank_rows": 0, + "matches": 213, + "coincidencias": 213, + "discrepancias": 1, + "banco_sin_nomina": 0, + "nomina_sin_cuenta": 0, + "possible_wrong_accounts": 0, + "name_differences": 2, + "total_nomina": 4148894.42, + "total_banco": 4134786.57, + "diferencia": 14107.85, + "discrepancy_people": [ + "Edgar Jimenez De Los Santos" + ], + "unused_bank": [], + "wrong": [] + }, + { + "period": "Julio 15", + "payroll_rows": 213, + "supplement_rows": 0, + "all_bank_rows": 213, + "processed_bank_rows": 213, + "rejected_bank_rows": 0, + "matches": 213, + "coincidencias": 213, + "discrepancias": 0, + "banco_sin_nomina": 0, + "nomina_sin_cuenta": 0, + "possible_wrong_accounts": 0, + "name_differences": 2, + "total_nomina": 4008539.04, + "total_banco": 4008539.04, + "diferencia": 0.0, + "discrepancy_people": [], + "unused_bank": [], + "wrong": [] + }, + { + "period": "Julio 30", + "payroll_rows": 262, + "supplement_rows": 0, + "all_bank_rows": 262, + "processed_bank_rows": 262, + "rejected_bank_rows": 0, + "matches": 262, + "coincidencias": 262, + "discrepancias": 0, + "banco_sin_nomina": 0, + "nomina_sin_cuenta": 0, + "possible_wrong_accounts": 0, + "name_differences": 2, + "total_nomina": 4431266.42, + "total_banco": 4431266.42, + "diferencia": 0.0, + "discrepancy_people": [], + "unused_bank": [], + "wrong": [] + } + ], + "acceptance": { + "core_row_classification": "PASS for all 4 trained periods", + "name_difference_count": "PASS: 2 for all 4 trained periods", + "bank_without_payroll": "PASS: 0 for all 4 trained periods", + "wrong_account_false_positives": "PASS: 0 for all 4 trained periods", + "june_totals": "PASS exact", + "july_aggregate_rounding": "PASS functional: zero row discrepancies; workflow uses deterministic currency rounding and therefore normalizes the historical -0.01/-0.07 aggregate artifacts to 0.00", + "bamboo_live_counts": "NOT EXECUTED OFFLINE; requires n8n live BambooHR credential. Workflow uses onlyCurrent=false and RD country/location filter." + }, + "payroll_filename_detection": { + "tested_files": 16, + "failures": 0, + "cases": [ + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Abril 15 2026_20260401.xlsx", + "year": 2026, + "month": 4, + "period_type": "quincena_15", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Abril 30 2026_20260418.xlsx", + "year": 2026, + "month": 4, + "period_type": "quincena_30", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Agosto 15 2026_20260730.xlsx", + "year": 2026, + "month": 8, + "period_type": "quincena_15", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Agosto 30 2026_20260818.xlsx", + "year": 2026, + "month": 8, + "period_type": "quincena_30", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Enero 15 2026_20260108.xlsx", + "year": 2026, + "month": 1, + "period_type": "quincena_15", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Enero 30 2026_20260119.xlsx", + "year": 2026, + "month": 1, + "period_type": "quincena_30", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Febrero 15 2026_20260202.xlsx", + "year": 2026, + "month": 2, + "period_type": "quincena_15", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Febrero 28 2026_202602018.xlsx", + "year": 2026, + "month": 2, + "period_type": "quincena_30", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Julio 15 2026_20260706.xlsx", + "year": 2026, + "month": 7, + "period_type": "quincena_15", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Julio 30 2026_20260716.xlsx", + "year": 2026, + "month": 7, + "period_type": "quincena_30", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Junio 15 2026_20260602.xlsx", + "year": 2026, + "month": 6, + "period_type": "quincena_15", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Junio 30 2026_20260616.xlsx", + "year": 2026, + "month": 6, + "period_type": "quincena_30", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Marzo 15 2026_20260303.xlsx", + "year": 2026, + "month": 3, + "period_type": "quincena_15", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Marzo 30 2026_20260318.xlsx", + "year": 2026, + "month": 3, + "period_type": "quincena_30", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Mayo 15 2026_20260507.xlsx", + "year": 2026, + "month": 5, + "period_type": "quincena_15", + "pass": true + }, + { + "file": "GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Mayo 30 2026_20260519.xlsx", + "year": 2026, + "month": 5, + "period_type": "quincena_30", + "pass": true + } + ] + }, + "static_validation": { + "n8n_workflow_json_and_connections": "PASS", + "n8n_code_node_js_syntax": "PASS", + "app_ts_tsx_syntax": "PASS", + "full_vite_build": "NOT EXECUTED in this container because project dependencies/node_modules were not available; deployment environment must run npm ci && npm run build" + } +} \ No newline at end of file diff --git a/VALIDACION_REPUBLICA_DOMINICANA_FINAL.md b/VALIDACION_REPUBLICA_DOMINICANA_FINAL.md new file mode 100644 index 0000000..2d3b03f --- /dev/null +++ b/VALIDACION_REPUBLICA_DOMINICANA_FINAL.md @@ -0,0 +1,156 @@ +# Validación final — República Dominicana + +Fecha de revisión: 12-09-2026. + +## Material analizado + +Se analizaron de forma conjunta: + +- las **16 nóminas RD** disponibles de enero a agosto de 2026 (Q15 y cierre de mes); +- los **62 archivos de pagos** disponibles para las cuatro quincenas de entrenamiento de junio/julio 2026; +- los **4 Excel oficiales de referencia** generados durante el entrenamiento; +- la arquitectura actual de la app multi-país; +- los workflows de Puerto Rico y los workflows compartidos de Gemini/corrección BambooHR utilizados como base estructural. + +## Reportes patrón + +| Período | Coincidencias | Discrepancias | Banco sin nómina | Banco sin Bamboo | Dif. nombre | Cuenta mal digitada | Pendientes principales | Total nómina ref. | Total banco ref. | Diferencia ref. | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| 15-jun-2026 | 257 | 1 | 0 | 7 | 2 | 0 | 3 | RD$4,665,382.94 | RD$4,644,692.08 | RD$20,690.86 | +| 30-jun-2026 | 213 | 1 | 0 | 8 | 2 | 0 | 3 | RD$4,148,894.42 | RD$4,134,786.57 | RD$14,107.85 | +| 15-jul-2026 | 213 | 0 | 0 | 8 | 2 | 0 | 2 | RD$4,008,539.03 | RD$4,008,539.04 | -RD$0.01 | +| 30-jul-2026 | 262 | 0 | 0 | 8 | 2 | 0 | 2 | RD$4,431,266.35 | RD$4,431,266.42 | -RD$0.07 | + +## Regresión independiente sobre archivos originales + +La lógica RD fue re-ejecutada offline contra los archivos de nómina/pago disponibles, sin utilizar como entrada los totales de los reportes de referencia. + +### 15-jun-2026 + +Resultado reconstruido: + +- 210 filas válidas de nómina. +- 48 suplementos `Bono BICE`. +- 258 movimientos bancarios totales, de los cuales 257 fueron procesados y 1 rechazado. +- 257 coincidencias. +- 1 discrepancia. +- 0 Banco sin nómina. +- 0 Nómina sin cuenta sin resolver. +- 0 posibles cuentas mal digitadas. +- 2 diferencias de nombre bancario. +- Total nómina: RD$4,665,382.94. +- Total banco procesado: RD$4,644,692.08. +- Diferencia: RD$20,690.86. + +La discrepancia reconstruida corresponde a **Angel Leonardo Baez** y reproduce el caso de pago rechazado por banco. + +### 30-jun-2026 + +Resultado reconstruido: + +- 214 filas válidas de nómina. +- 213 movimientos bancarios procesados. +- 213 coincidencias. +- 1 discrepancia. +- 0 Banco sin nómina. +- 0 Nómina sin cuenta sin resolver. +- 0 posibles cuentas mal digitadas. +- 2 diferencias de nombre bancario. +- Total nómina: RD$4,148,894.42. +- Total banco: RD$4,134,786.57. +- Diferencia: RD$14,107.85. + +La discrepancia reconstruida corresponde a **Edgar Jimenez De Los Santos**. El ACH adicional de **Jose Luis Ventura** por RD$22,661.00 se incorpora correctamente al conjunto bancario. + +### 15-jul-2026 + +Resultado reconstruido: + +- 213 filas válidas. +- 213 movimientos bancarios. +- 213 coincidencias. +- 0 discrepancias. +- 0 Banco sin nómina. +- 0 Nómina sin cuenta sin resolver. +- 0 posibles cuentas mal digitadas. +- 2 diferencias de nombre. + +La conciliación transacción por transacción queda completa. Con redondeo monetario determinista por fila, Nómina y Banco quedan en RD$4,008,539.04. El reporte histórico mostraba RD$4,008,539.03 / diferencia -RD$0.01. Esa diferencia histórica es un artefacto agregado de redondeo y **no debe convertirse en discrepancia**, exactamente como se decidió durante el entrenamiento. + +### 30-jul-2026 + +Resultado reconstruido: + +- 262 filas válidas. +- 262 movimientos bancarios. +- 262 coincidencias. +- 0 discrepancias. +- 0 Banco sin nómina. +- 0 Nómina sin cuenta sin resolver. +- 0 posibles cuentas mal digitadas. +- 2 diferencias de nombre. + +La conciliación por transacción queda completa. El flujo redondea de forma consistente y obtiene RD$4,431,266.42 tanto en Nómina como en Banco. El reporte histórico mostraba una diferencia agregada de -RD$0.07. Nuevamente, no existe una discrepancia real por empleado y el flujo no genera un falso hallazgo. + +## Diferencias de nombre bancario + +La regresión devuelve exactamente los **2 casos recurrentes** que sirvieron de referencia, sin agregar el falso positivo de Waldo Antonio Gonzales/Gonzalez: + +- `GOMEZ PERERA JOSE LEOPOLDO F` frente a Yelida Gómez Lee. +- `JAILYN CHAU` frente a Elizabeth Carrasco. + +La lógica fuzzy se ajustó para reconocer variaciones ortográficas cercanas/reordenamiento de tokens sin convertir coincidencias reales en “Diferencia nombre banco”. + +## Nóminas enero-agosto 2026 + +Se confirmaron 16 archivos reales, uno por cada quincena disponible. El detector local de la app identifica correctamente los 16 períodos, incluyendo **28-feb-2026 como segunda quincena/cierre de mes**. + +El flujo no depende de que el calendario termine en día 30; el último día real de febrero también se interpreta como `quincena_30`. + +La nómina de 30-may-2026 tiene un total bruto notablemente superior al resto. No se modificó ni se “corrigió” automáticamente porque no existen pagos de mayo en el material recibido para validar si corresponde a pagos extraordinarios. El workflow procesará el archivo por sus filas reales y requerirá los archivos bancarios de esa misma quincena para conciliarlo. + +## Pagos analizados + +Los 62 archivos recibidos corresponden a junio/julio 2026 e incluyen CSV regulares, lotes temporales, suplementos y siete PDFs BHD. La lógica contempla que una quincena tenga múltiples lotes y archivos con sufijo `.1.csv`. + +Los ACH PDF detectados incluyen pagos de Jose Luis Ventura, Reimon Perez y Jenny Salazar. La clasificación de origen del PDF se usa como información descriptiva; el match contable se sostiene en cuenta/monto/nombre, por lo que una descripción bancaria inconsistente no invalida un pago real. + +## Validaciones técnicas realizadas + +- Los 5 workflows RD/compartidos son JSON válido. +- No existen conexiones n8n hacia nodos inexistentes. +- Todos los Code nodes pasan validación sintáctica JavaScript. +- Los archivos `.ts/.tsx` modificados pasan transpilación sintáctica TypeScript. +- El workflow principal RD no conserva referencias operativas a Puerto Rico, USD, `es-PR` ni `America/Puerto_Rico`. +- Moneda RD: `DOP`. +- Locale: `es-DO`. +- Zona horaria: `America/Santo_Domingo`. +- BambooHR: `onlyCurrent=false`. +- Destinataria RRHH: `nlaureano@gomezleemarketing.com`. +- Bandera: URL suministrada para República Dominicana. +- Las 6 pestañas del reporte quedan siempre definidas. +- La protección de `Resolución` incluye a Noralmy para RD. + +## Límite de la validación local + +No se ejecutó una prueba **live** contra las credenciales reales de n8n/BambooHR/Google Workspace/Supabase desde este entorno. Por esa razón, aunque el paquete está preparado para importar y la lógica fue validada estáticamente y contra los archivos históricos, la condición final de “producción 100%” debe cerrarse con **una ejecución real controlada en n8n**. + +En particular, los conteos históricos de `Banco sin Bamboo` (7/8) dependen de la foto real de BambooHR y de los alias almacenados en Supabase al momento de ejecutar. La lógica de consulta y filtrado está implementada, pero esos conteos no pueden reproducirse offline sin consultar BambooHR. + +## Gate final de producción + +RD puede declararse definitivamente “ready mensual” cuando una ejecución live cumpla simultáneamente: + +- webhook RD recibe el Excel + todos los CSV/PDF de la quincena; +- período detectado/seleccionado coincide con `PERÍODO` de la nómina; +- BambooHR responde correctamente con `onlyCurrent=false`; +- se generan las 6 pestañas; +- el Google Sheet se comparte correctamente; +- Noralmy recibe el correo; +- histórico `country=RD` queda guardado; +- “Marcar resuelto” actualiza ese reporte; +- un segundo procesamiento del mismo período reutiliza el reporte y preserva resoluciones aplicables; +- una de las cuatro quincenas patrón reproduce sus hallazgos funcionales; +- una quincena nueva/no entrenada no arroja falsos positivos evidentes. + +El detalle de la regresión también queda en `VALIDACION_RD_REGRESION.json`. diff --git a/dist/assets/index-CLG5SAqX.css b/dist/assets/index-CLG5SAqX.css deleted file mode 100644 index f678dd5..0000000 --- a/dist/assets/index-CLG5SAqX.css +++ /dev/null @@ -1 +0,0 @@ -@import"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&display=swap";/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:"Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-mono:"JetBrains Mono", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-800:oklch(44.4% .177 26.899);--color-orange-50:oklch(98% .016 73.684);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-300:oklch(83.7% .128 66.29);--color-orange-800:oklch(47% .157 37.304);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-800:oklch(47.3% .137 46.201);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-700:oklch(50.8% .118 165.612);--color-emerald-800:oklch(43.2% .095 166.913);--color-blue-50:oklch(97% .014 254.604);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-800:oklch(42.4% .199 265.638);--color-violet-200:oklch(89.4% .057 293.283);--color-violet-800:oklch(43.2% .232 292.759);--color-slate-700:oklch(37.2% .044 257.287);--color-neutral-50:oklch(98.5% 0 0);--color-neutral-100:oklch(97% 0 0);--color-neutral-200:oklch(92.2% 0 0);--color-neutral-300:oklch(87% 0 0);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-500:oklch(55.6% 0 0);--color-neutral-600:oklch(43.9% 0 0);--color-neutral-700:oklch(37.1% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-3xl:48rem;--container-5xl:64rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-black:900;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-md:.375rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-gris-fondo:#f5f5f5}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.top-0{top:0}.top-1\/2{top:50%}.top-\[84px\]{top:84px}.top-full{top:100%}.right-0{right:0}.right-6{right:calc(var(--spacing) * 6)}.bottom-0{bottom:0}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-0{left:0}.left-3{left:calc(var(--spacing) * 3)}.left-3\.5{left:calc(var(--spacing) * 3.5)}.z-10{z-index:10}.z-40{z-index:40}.z-45{z-index:45}.z-50{z-index:50}.z-\[80\]{z-index:80}.z-\[90\]{z-index:90}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-7{margin-bottom:calc(var(--spacing) * 7)}.-ml-2{margin-left:calc(var(--spacing) * -2)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-4\.5{height:calc(var(--spacing) * 4.5)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-14{height:calc(var(--spacing) * 14)}.h-\[80px\]{height:80px}.h-\[84px\]{height:84px}.h-screen{height:100vh}.max-h-\[92vh\]{max-height:92vh}.max-h-\[250px\]{max-height:250px}.max-h-\[260px\]{max-height:260px}.max-h-\[330px\]{max-height:330px}.min-h-\[130px\]{min-height:130px}.min-h-\[150px\]{min-height:150px}.min-h-\[190px\]{min-height:190px}.min-h-screen{min-height:100vh}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-4\.5{width:calc(var(--spacing) * 4.5)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-12{width:calc(var(--spacing) * 12)}.w-64{width:calc(var(--spacing) * 64)}.w-auto{width:auto}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[180px\]{max-width:180px}.max-w-\[220px\]{max-width:220px}.max-w-\[260px\]{max-width:260px}.max-w-\[290px\]{max-width:290px}.max-w-\[300px\]{max-width:300px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:0}.min-w-8{min-width:calc(var(--spacing) * 8)}.min-w-\[280px\]{min-width:280px}.min-w-\[760px\]{min-width:760px}.min-w-\[960px\]{min-width:960px}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0{--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.scroll-mt-28{scroll-margin-top:calc(var(--spacing) * 28)}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-neutral-100>:not(:last-child)){border-color:var(--color-neutral-100)}:where(.divide-neutral-200>:not(:last-child)){border-color:var(--color-neutral-200)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-4{border-top-style:var(--tw-border-style);border-top-width:4px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-4{border-bottom-style:var(--tw-border-style);border-bottom-width:4px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[\#4F758B\]{border-color:#4f758b}.border-\[\#4F758B\]\/10{border-color:#4f758b1a}.border-\[\#4F758B\]\/20{border-color:#4f758b33}.border-\[\#4F758B\]\/25{border-color:#4f758b40}.border-\[\#4F758B\]\/30{border-color:#4f758b4d}.border-\[\#4F758B\]\/40{border-color:#4f758b66}.border-\[\#6CC24A\]{border-color:#6cc24a}.border-\[\#6CC24A\]\/30{border-color:#6cc24a4d}.border-\[\#D0D0D0\]{border-color:#d0d0d0}.border-\[\#D6E8F4\]{border-color:#d6e8f4}.border-amber-200{border-color:var(--color-amber-200)}.border-blue-200{border-color:var(--color-blue-200)}.border-emerald-200{border-color:var(--color-emerald-200)}.border-emerald-700{border-color:var(--color-emerald-700)}.border-neutral-200{border-color:var(--color-neutral-200)}.border-neutral-200\/10{border-color:#e5e5e51a}@supports (color:color-mix(in lab,red,red)){.border-neutral-200\/10{border-color:color-mix(in oklab,var(--color-neutral-200) 10%,transparent)}}.border-neutral-300{border-color:var(--color-neutral-300)}.border-orange-200{border-color:var(--color-orange-200)}.border-red-100{border-color:var(--color-red-100)}.border-red-200{border-color:var(--color-red-200)}.border-red-800{border-color:var(--color-red-800)}.border-slate-700{border-color:var(--color-slate-700)}.border-transparent{border-color:#0000}.border-violet-200{border-color:var(--color-violet-200)}.border-white\/40{border-color:#fff6}@supports (color:color-mix(in lab,red,red)){.border-white\/40{border-color:color-mix(in oklab,var(--color-white) 40%,transparent)}}.border-t-white{border-top-color:var(--color-white)}.bg-\[\#4F758B\]{background-color:#4f758b}.bg-\[\#4F758B\]\/5{background-color:#4f758b0d}.bg-\[\#4F758B\]\/10{background-color:#4f758b1a}.bg-\[\#6CC24A\]{background-color:#6cc24a}.bg-\[\#6CC24A\]\/5{background-color:#6cc24a0d}.bg-\[\#6CC24A\]\/10{background-color:#6cc24a1a}.bg-\[\#D0D0D0\]{background-color:#d0d0d0}.bg-\[\#F5F5F5\]{background-color:#f5f5f5}.bg-\[\#F7FBFD\]{background-color:#f7fbfd}.bg-\[\#ba1a1a\]{background-color:#ba1a1a}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black\/45{background-color:#00000073}@supports (color:color-mix(in lab,red,red)){.bg-black\/45{background-color:color-mix(in oklab,var(--color-black) 45%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-neutral-50{background-color:var(--color-neutral-50)}.bg-neutral-50\/50{background-color:#fafafa80}@supports (color:color-mix(in lab,red,red)){.bg-neutral-50\/50{background-color:color-mix(in oklab,var(--color-neutral-50) 50%,transparent)}}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-orange-50{background-color:var(--color-orange-50)}.bg-red-50{background-color:var(--color-red-50)}.bg-white{background-color:var(--color-white)}.fill-current{fill:currentColor}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-14{padding-block:calc(var(--spacing) * 14)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-5{padding-top:calc(var(--spacing) * 5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.pl-0{padding-left:0}.pl-9{padding-left:calc(var(--spacing) * 9)}.pl-10{padding-left:calc(var(--spacing) * 10)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.18em\]{--tw-tracking:.18em;letter-spacing:.18em}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.text-\[\#4F758B\]{color:#4f758b}.text-\[\#6B8FA3\]{color:#6b8fa3}.text-\[\#6CC24A\]{color:#6cc24a}.text-\[\#ba1a1a\]{color:#ba1a1a}.text-amber-800{color:var(--color-amber-800)}.text-blue-800{color:var(--color-blue-800)}.text-emerald-700{color:var(--color-emerald-700)}.text-emerald-800{color:var(--color-emerald-800)}.text-neutral-300{color:var(--color-neutral-300)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-neutral-600{color:var(--color-neutral-600)}.text-neutral-700{color:var(--color-neutral-700)}.text-neutral-800{color:var(--color-neutral-800)}.text-orange-800{color:var(--color-orange-800)}.text-red-600{color:var(--color-red-600)}.text-violet-800{color:var(--color-violet-800)}.text-white{color:var(--color-white)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.placeholder-neutral-400::placeholder{color:var(--color-neutral-400)}.accent-\[\#6CC24A\]{accent-color:#6cc24a}.opacity-25{opacity:.25}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.selection\:bg-\[\#6CC24A\] ::selection{background-color:#6cc24a}.selection\:bg-\[\#6CC24A\]::selection{background-color:#6cc24a}.selection\:bg-transparent ::selection{background-color:#0000}.selection\:bg-transparent::selection{background-color:#0000}.selection\:text-white ::selection{color:var(--color-white)}.selection\:text-white::selection{color:var(--color-white)}@media(hover:hover){.hover\:border-\[\#4F758B\]:hover{border-color:#4f758b}.hover\:border-\[\#4F758B\]\/40:hover{border-color:#4f758b66}.hover\:border-\[\#4F758B\]\/50:hover{border-color:#4f758b80}.hover\:border-\[\#4F758B\]\/55:hover{border-color:#4f758b8c}.hover\:border-emerald-400:hover{border-color:var(--color-emerald-400)}.hover\:border-orange-300:hover{border-color:var(--color-orange-300)}.hover\:border-red-100:hover{border-color:var(--color-red-100)}.hover\:bg-\[\#3F6174\]:hover{background-color:#3f6174}.hover\:bg-\[\#3d6378\]:hover{background-color:#3d6378}.hover\:bg-\[\#4F758B\]:hover{background-color:#4f758b}.hover\:bg-\[\#4F758B\]\/5:hover{background-color:#4f758b0d}.hover\:bg-\[\#4F758B\]\/\[0\.025\]:hover{background-color:#4f758b06}.hover\:bg-\[\#5aaa3f\]:hover{background-color:#5aaa3f}.hover\:bg-\[\#5bb03c\]:hover{background-color:#5bb03c}.hover\:bg-\[\#41677b\]:hover{background-color:#41677b}.hover\:bg-emerald-100:hover{background-color:var(--color-emerald-100)}.hover\:bg-neutral-50:hover{background-color:var(--color-neutral-50)}.hover\:bg-neutral-50\/70:hover{background-color:#fafafab3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-neutral-50\/70:hover{background-color:color-mix(in oklab,var(--color-neutral-50) 70%,transparent)}}.hover\:bg-neutral-100:hover{background-color:var(--color-neutral-100)}.hover\:bg-neutral-200:hover{background-color:var(--color-neutral-200)}.hover\:bg-orange-100:hover{background-color:var(--color-orange-100)}.hover\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\:bg-white\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/20:hover{background-color:color-mix(in oklab,var(--color-white) 20%,transparent)}}.hover\:text-\[\#3d6378\]:hover{color:#3d6378}.hover\:text-\[\#4F758B\]:hover{color:#4f758b}.hover\:text-emerald-800:hover{color:var(--color-emerald-800)}.hover\:text-neutral-700:hover{color:var(--color-neutral-700)}.hover\:text-neutral-800:hover{color:var(--color-neutral-800)}.hover\:text-red-500:hover{color:var(--color-red-500)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\:border-\[\#4F758B\]:focus{border-color:#4f758b}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-\[\#4F758B\]\/10:focus{--tw-ring-color:oklab(54.2682% -.0318721 -.0447881/.1)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-98:active{--tw-scale-x:98%;--tw-scale-y:98%;--tw-scale-z:98%;scale:var(--tw-scale-x) var(--tw-scale-y)}.active\:scale-\[0\.99\]:active{scale:.99}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:border-neutral-300:disabled{border-color:var(--color-neutral-300)}.disabled\:bg-neutral-50:disabled{background-color:var(--color-neutral-50)}.disabled\:bg-neutral-300:disabled{background-color:var(--color-neutral-300)}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-45:disabled{opacity:.45}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:40rem){.sm\:col-span-2{grid-column:span 2/span 2}.sm\:flex{display:flex}.sm\:inline{display:inline}.sm\:inline-flex{display:inline-flex}.sm\:h-6{height:calc(var(--spacing) * 6)}.sm\:h-10{height:calc(var(--spacing) * 10)}.sm\:w-16{width:calc(var(--spacing) * 16)}.sm\:w-auto{width:auto}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}.sm\:justify-end{justify-content:flex-end}.sm\:gap-2{gap:calc(var(--spacing) * 2)}.sm\:gap-3{gap:calc(var(--spacing) * 3)}.sm\:self-auto{align-self:auto}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:p-9{padding:calc(var(--spacing) * 9)}.sm\:px-3{padding-inline:calc(var(--spacing) * 3)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:px-8{padding-inline:calc(var(--spacing) * 8)}.sm\:text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.sm\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}}@media(min-width:48rem){.md\:block{display:block}.md\:hidden{display:none}.md\:translate-x-0{--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-\[1fr_auto\]{grid-template-columns:1fr auto}.md\:justify-center{justify-content:center}.md\:pl-64{padding-left:calc(var(--spacing) * 64)}.md\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}}@media(min-width:64rem){.lg\:w-auto{width:auto}.lg\:max-w-md{max-width:var(--container-md)}.lg\:max-w-sm{max-width:var(--container-sm)}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:items-start{align-items:flex-start}.lg\:justify-between{justify-content:space-between}.lg\:text-right{text-align:right}.lg\:text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}}@media(min-width:80rem){.xl\:min-w-full{min-width:100%}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.xl\:px-4{padding-inline:calc(var(--spacing) * 4)}}@media(min-width:96rem){.\32xl\:inline{display:inline}}}body{font-family:var(--font-sans);background-color:var(--color-gris-fondo)}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}} diff --git a/dist/assets/index-DGYJf0Q4.js b/dist/assets/index-DGYJf0Q4.js new file mode 100644 index 0000000..f5918e3 --- /dev/null +++ b/dist/assets/index-DGYJf0Q4.js @@ -0,0 +1,270 @@ +(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))a(l);new MutationObserver(l=>{for(const c of l)if(c.type==="childList")for(const u of c.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&a(u)}).observe(document,{childList:!0,subtree:!0});function i(l){const c={};return l.integrity&&(c.integrity=l.integrity),l.referrerPolicy&&(c.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?c.credentials="include":l.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function a(l){if(l.ep)return;l.ep=!0;const c=i(l);fetch(l.href,c)}})();var td={exports:{}},$r={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Gy;function XS(){if(Gy)return $r;Gy=1;var n=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function i(a,l,c){var u=null;if(c!==void 0&&(u=""+c),l.key!==void 0&&(u=""+l.key),"key"in l){c={};for(var d in l)d!=="key"&&(c[d]=l[d])}else c=l;return l=c.ref,{$$typeof:n,type:a,key:u,ref:l!==void 0?l:null,props:c}}return $r.Fragment=e,$r.jsx=i,$r.jsxs=i,$r}var Ky;function JS(){return Ky||(Ky=1,td.exports=XS()),td.exports}var g=JS(),nd={exports:{}},be={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Yy;function QS(){if(Yy)return be;Yy=1;var n=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),l=Symbol.for("react.profiler"),c=Symbol.for("react.consumer"),u=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),m=Symbol.for("react.suspense"),p=Symbol.for("react.memo"),y=Symbol.for("react.lazy"),v=Symbol.for("react.activity"),x=Symbol.iterator;function _(A){return A===null||typeof A!="object"?null:(A=x&&A[x]||A["@@iterator"],typeof A=="function"?A:null)}var S={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},T=Object.assign,j={};function k(A,q,J){this.props=A,this.context=q,this.refs=j,this.updater=J||S}k.prototype.isReactComponent={},k.prototype.setState=function(A,q){if(typeof A!="object"&&typeof A!="function"&&A!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,A,q,"setState")},k.prototype.forceUpdate=function(A){this.updater.enqueueForceUpdate(this,A,"forceUpdate")};function M(){}M.prototype=k.prototype;function C(A,q,J){this.props=A,this.context=q,this.refs=j,this.updater=J||S}var P=C.prototype=new M;P.constructor=C,T(P,k.prototype),P.isPureReactComponent=!0;var K=Array.isArray;function G(){}var H={H:null,A:null,T:null,S:null},Y=Object.prototype.hasOwnProperty;function Z(A,q,J){var ne=J.ref;return{$$typeof:n,type:A,key:q,ref:ne!==void 0?ne:null,props:J}}function se(A,q){return Z(A.type,q,A.props)}function me(A){return typeof A=="object"&&A!==null&&A.$$typeof===n}function ye(A){var q={"=":"=0",":":"=2"};return"$"+A.replace(/[=:]/g,function(J){return q[J]})}var Ae=/\/+/g;function Ne(A,q){return typeof A=="object"&&A!==null&&A.key!=null?ye(""+A.key):q.toString(36)}function Be(A){switch(A.status){case"fulfilled":return A.value;case"rejected":throw A.reason;default:switch(typeof A.status=="string"?A.then(G,G):(A.status="pending",A.then(function(q){A.status==="pending"&&(A.status="fulfilled",A.value=q)},function(q){A.status==="pending"&&(A.status="rejected",A.reason=q)})),A.status){case"fulfilled":return A.value;case"rejected":throw A.reason}}throw A}function L(A,q,J,ne,de){var ge=typeof A;(ge==="undefined"||ge==="boolean")&&(A=null);var we=!1;if(A===null)we=!0;else switch(ge){case"bigint":case"string":case"number":we=!0;break;case"object":switch(A.$$typeof){case n:case e:we=!0;break;case y:return we=A._init,L(we(A._payload),q,J,ne,de)}}if(we)return de=de(A),we=ne===""?"."+Ne(A,0):ne,K(de)?(J="",we!=null&&(J=we.replace(Ae,"$&/")+"/"),L(de,q,J,"",function(at){return at})):de!=null&&(me(de)&&(de=se(de,J+(de.key==null||A&&A.key===de.key?"":(""+de.key).replace(Ae,"$&/")+"/")+we)),q.push(de)),1;we=0;var ke=ne===""?".":ne+":";if(K(A))for(var qe=0;qe>>1,ue=L[le];if(0>>1;lel(J,Q))nel(de,J)?(L[le]=de,L[ne]=Q,le=ne):(L[le]=J,L[q]=Q,le=q);else if(nel(de,Q))L[le]=de,L[ne]=Q,le=ne;else break e}}return W}function l(L,W){var Q=L.sortIndex-W.sortIndex;return Q!==0?Q:L.id-W.id}if(n.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var c=performance;n.unstable_now=function(){return c.now()}}else{var u=Date,d=u.now();n.unstable_now=function(){return u.now()-d}}var m=[],p=[],y=1,v=null,x=3,_=!1,S=!1,T=!1,j=!1,k=typeof setTimeout=="function"?setTimeout:null,M=typeof clearTimeout=="function"?clearTimeout:null,C=typeof setImmediate<"u"?setImmediate:null;function P(L){for(var W=i(p);W!==null;){if(W.callback===null)a(p);else if(W.startTime<=L)a(p),W.sortIndex=W.expirationTime,e(m,W);else break;W=i(p)}}function K(L){if(T=!1,P(L),!S)if(i(m)!==null)S=!0,G||(G=!0,ye());else{var W=i(p);W!==null&&Be(K,W.startTime-L)}}var G=!1,H=-1,Y=5,Z=-1;function se(){return j?!0:!(n.unstable_now()-ZL&&se());){var le=v.callback;if(typeof le=="function"){v.callback=null,x=v.priorityLevel;var ue=le(v.expirationTime<=L);if(L=n.unstable_now(),typeof ue=="function"){v.callback=ue,P(L),W=!0;break t}v===i(m)&&a(m),P(L)}else a(m);v=i(m)}if(v!==null)W=!0;else{var A=i(p);A!==null&&Be(K,A.startTime-L),W=!1}}break e}finally{v=null,x=Q,_=!1}W=void 0}}finally{W?ye():G=!1}}}var ye;if(typeof C=="function")ye=function(){C(me)};else if(typeof MessageChannel<"u"){var Ae=new MessageChannel,Ne=Ae.port2;Ae.port1.onmessage=me,ye=function(){Ne.postMessage(null)}}else ye=function(){k(me,0)};function Be(L,W){H=k(function(){L(n.unstable_now())},W)}n.unstable_IdlePriority=5,n.unstable_ImmediatePriority=1,n.unstable_LowPriority=4,n.unstable_NormalPriority=3,n.unstable_Profiling=null,n.unstable_UserBlockingPriority=2,n.unstable_cancelCallback=function(L){L.callback=null},n.unstable_forceFrameRate=function(L){0>L||125le?(L.sortIndex=Q,e(p,L),i(m)===null&&L===i(p)&&(T?(M(H),H=-1):T=!0,Be(K,Q-le))):(L.sortIndex=ue,e(m,L),S||_||(S=!0,G||(G=!0,ye()))),L},n.unstable_shouldYield=se,n.unstable_wrapCallback=function(L){var W=x;return function(){var Q=x;x=W;try{return L.apply(this,arguments)}finally{x=Q}}}})(ad)),ad}var Qy;function WS(){return Qy||(Qy=1,id.exports=ZS()),id.exports}var rd={exports:{}},zt={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Zy;function e1(){if(Zy)return zt;Zy=1;var n=Sf();function e(m){var p="https://react.dev/errors/"+m;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}return n(),rd.exports=e1(),rd.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var e0;function n1(){if(e0)return qr;e0=1;var n=WS(),e=Sf(),i=t1();function a(t){var s="https://react.dev/errors/"+t;if(1ue||(t.current=le[ue],le[ue]=null,ue--)}function J(t,s){ue++,le[ue]=t.current,t.current=s}var ne=A(null),de=A(null),ge=A(null),we=A(null);function ke(t,s){switch(J(ge,s),J(de,t),J(ne,null),s.nodeType){case 9:case 11:t=(t=s.documentElement)&&(t=t.namespaceURI)?py(t):0;break;default:if(t=s.tagName,s=s.namespaceURI)s=py(s),t=gy(s,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}q(ne),J(ne,t)}function qe(){q(ne),q(de),q(ge)}function at(t){t.memoizedState!==null&&J(we,t);var s=ne.current,r=gy(s,t.type);s!==r&&(J(de,t),J(ne,r))}function jn(t){de.current===t&&(q(ne),q(de)),we.current===t&&(q(we),zr._currentValue=Q)}var Nn,as;function ee(t){if(Nn===void 0)try{throw Error()}catch(r){var s=r.stack.trim().match(/\n( *(at )?)/);Nn=s&&s[1]||"",as=-1)":-1h||E[o]!==U[h]){var $=` +`+E[o].replace(" at new "," at ");return t.displayName&&$.includes("")&&($=$.replace("",t.displayName)),$}while(1<=o&&0<=h);break}}}finally{Ce=!1,Error.prepareStackTrace=r}return(r=t?t.displayName||t.name:"")?ee(r):""}function Re(t,s){switch(t.tag){case 26:case 27:case 5:return ee(t.type);case 16:return ee("Lazy");case 13:return t.child!==s&&s!==null?ee("Suspense Fallback"):ee("Suspense");case 19:return ee("SuspenseList");case 0:case 15:return ze(t.type,!1);case 11:return ze(t.type.render,!1);case 1:return ze(t.type,!0);case 31:return ee("Activity");default:return""}}function rt(t){try{var s="",r=null;do s+=Re(t,r),r=t,t=t.return;while(t);return s}catch(o){return` +Error generating stack: `+o.message+` +`+o.stack}}var st=Object.prototype.hasOwnProperty,ht=n.unstable_scheduleCallback,it=n.unstable_cancelCallback,Qt=n.unstable_shouldYield,$n=n.unstable_requestPaint,Ze=n.unstable_now,ci=n.unstable_getCurrentPriorityLevel,gt=n.unstable_ImmediatePriority,jt=n.unstable_UserBlockingPriority,qn=n.unstable_NormalPriority,Rn=n.unstable_LowPriority,Cs=n.unstable_IdlePriority,$i=n.log,ui=n.unstable_setDisableYieldValue,rs=null,yt=null;function cn(t){if(typeof $i=="function"&&ui(t),yt&&typeof yt.setStrictMode=="function")try{yt.setStrictMode(rs,t)}catch{}}var Vt=Math.clz32?Math.clz32:Ao,Ct=Math.log,Eo=Math.LN2;function Ao(t){return t>>>=0,t===0?32:31-(Ct(t)/Eo|0)|0}var hi=256,Fn=262144,di=4194304;function os(t){var s=t&42;if(s!==0)return s;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function qi(t,s,r){var o=t.pendingLanes;if(o===0)return 0;var h=0,f=t.suspendedLanes,b=t.pingedLanes;t=t.warmLanes;var w=o&134217727;return w!==0?(o=w&~f,o!==0?h=os(o):(b&=w,b!==0?h=os(b):r||(r=w&~t,r!==0&&(h=os(r))))):(w=o&~f,w!==0?h=os(w):b!==0?h=os(b):r||(r=o&~t,r!==0&&(h=os(r)))),h===0?0:s!==0&&s!==h&&(s&f)===0&&(f=h&-h,r=s&-s,f>=r||f===32&&(r&4194048)!==0)?s:h}function fi(t,s){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&s)===0}function Gc(t,s){switch(t){case 1:case 2:case 4:case 8:case 64:return s+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return s+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function jo(){var t=di;return di<<=1,(di&62914560)===0&&(di=4194304),t}function Qa(t){for(var s=[],r=0;31>r;r++)s.push(t);return s}function Os(t,s){t.pendingLanes|=s,s!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function Kc(t,s,r,o,h,f){var b=t.pendingLanes;t.pendingLanes=r,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=r,t.entangledLanes&=r,t.errorRecoveryDisabledLanes&=r,t.shellSuspendCounter=0;var w=t.entanglements,E=t.expirationTimes,U=t.hiddenUpdates;for(r=b&~r;0"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var qw=/[\n"\\]/g;function mn(t){return t.replace(qw,function(s){return"\\"+s.charCodeAt(0).toString(16)+" "})}function Xc(t,s,r,o,h,f,b,w){t.name="",b!=null&&typeof b!="function"&&typeof b!="symbol"&&typeof b!="boolean"?t.type=b:t.removeAttribute("type"),s!=null?b==="number"?(s===0&&t.value===""||t.value!=s)&&(t.value=""+fn(s)):t.value!==""+fn(s)&&(t.value=""+fn(s)):b!=="submit"&&b!=="reset"||t.removeAttribute("value"),s!=null?Jc(t,b,fn(s)):r!=null?Jc(t,b,fn(r)):o!=null&&t.removeAttribute("value"),h==null&&f!=null&&(t.defaultChecked=!!f),h!=null&&(t.checked=h&&typeof h!="function"&&typeof h!="symbol"),w!=null&&typeof w!="function"&&typeof w!="symbol"&&typeof w!="boolean"?t.name=""+fn(w):t.removeAttribute("name")}function cm(t,s,r,o,h,f,b,w){if(f!=null&&typeof f!="function"&&typeof f!="symbol"&&typeof f!="boolean"&&(t.type=f),s!=null||r!=null){if(!(f!=="submit"&&f!=="reset"||s!=null)){Yc(t);return}r=r!=null?""+fn(r):"",s=s!=null?""+fn(s):r,w||s===t.value||(t.value=s),t.defaultValue=s}o=o??h,o=typeof o!="function"&&typeof o!="symbol"&&!!o,t.checked=w?t.checked:!!o,t.defaultChecked=!!o,b!=null&&typeof b!="function"&&typeof b!="symbol"&&typeof b!="boolean"&&(t.name=b),Yc(t)}function Jc(t,s,r){s==="number"&&Mo(t.ownerDocument)===t||t.defaultValue===""+r||(t.defaultValue=""+r)}function Ii(t,s,r,o){if(t=t.options,s){s={};for(var h=0;h"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),tu=!1;if(us)try{var nr={};Object.defineProperty(nr,"passive",{get:function(){tu=!0}}),window.addEventListener("test",nr,nr),window.removeEventListener("test",nr,nr)}catch{tu=!1}var Ds=null,nu=null,Uo=null;function gm(){if(Uo)return Uo;var t,s=nu,r=s.length,o,h="value"in Ds?Ds.value:Ds.textContent,f=h.length;for(t=0;t=ar),_m=" ",Sm=!1;function Tm(t,s){switch(t){case"keyup":return y_.indexOf(s.keyCode)!==-1;case"keydown":return s.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Em(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var Xi=!1;function v_(t,s){switch(t){case"compositionend":return Em(s);case"keypress":return s.which!==32?null:(Sm=!0,_m);case"textInput":return t=s.data,t===_m&&Sm?null:t;default:return null}}function x_(t,s){if(Xi)return t==="compositionend"||!ou&&Tm(t,s)?(t=gm(),Uo=nu=Ds=null,Xi=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(s.ctrlKey||s.altKey||s.metaKey)||s.ctrlKey&&s.altKey){if(s.char&&1=s)return{node:r,offset:s-t};t=o}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=Dm(r)}}function Bm(t,s){return t&&s?t===s?!0:t&&t.nodeType===3?!1:s&&s.nodeType===3?Bm(t,s.parentNode):"contains"in t?t.contains(s):t.compareDocumentPosition?!!(t.compareDocumentPosition(s)&16):!1:!1}function Um(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var s=Mo(t.document);s instanceof t.HTMLIFrameElement;){try{var r=typeof s.contentWindow.location.href=="string"}catch{r=!1}if(r)t=s.contentWindow;else break;s=Mo(t.document)}return s}function uu(t){var s=t&&t.nodeName&&t.nodeName.toLowerCase();return s&&(s==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||s==="textarea"||t.contentEditable==="true")}var N_=us&&"documentMode"in document&&11>=document.documentMode,Ji=null,hu=null,cr=null,du=!1;function Lm(t,s,r){var o=r.window===r?r.document:r.nodeType===9?r:r.ownerDocument;du||Ji==null||Ji!==Mo(o)||(o=Ji,"selectionStart"in o&&uu(o)?o={start:o.selectionStart,end:o.selectionEnd}:(o=(o.ownerDocument&&o.ownerDocument.defaultView||window).getSelection(),o={anchorNode:o.anchorNode,anchorOffset:o.anchorOffset,focusNode:o.focusNode,focusOffset:o.focusOffset}),cr&&lr(cr,o)||(cr=o,o=Rl(hu,"onSelect"),0>=b,h-=b,Gn=1<<32-Vt(s)+h|r<xe?(Ee=ce,ce=null):Ee=ce.sibling;var De=z(O,ce,B[xe],F);if(De===null){ce===null&&(ce=Ee);break}t&&ce&&De.alternate===null&&s(O,ce),N=f(De,N,xe),Oe===null?he=De:Oe.sibling=De,Oe=De,ce=Ee}if(xe===B.length)return r(O,ce),je&&ds(O,xe),he;if(ce===null){for(;xexe?(Ee=ce,ce=null):Ee=ce.sibling;var ti=z(O,ce,De.value,F);if(ti===null){ce===null&&(ce=Ee);break}t&&ce&&ti.alternate===null&&s(O,ce),N=f(ti,N,xe),Oe===null?he=ti:Oe.sibling=ti,Oe=ti,ce=Ee}if(De.done)return r(O,ce),je&&ds(O,xe),he;if(ce===null){for(;!De.done;xe++,De=B.next())De=I(O,De.value,F),De!==null&&(N=f(De,N,xe),Oe===null?he=De:Oe.sibling=De,Oe=De);return je&&ds(O,xe),he}for(ce=o(ce);!De.done;xe++,De=B.next())De=V(ce,O,xe,De.value,F),De!==null&&(t&&De.alternate!==null&&ce.delete(De.key===null?xe:De.key),N=f(De,N,xe),Oe===null?he=De:Oe.sibling=De,Oe=De);return t&&ce.forEach(function(YS){return s(O,YS)}),je&&ds(O,xe),he}function Ge(O,N,B,F){if(typeof B=="object"&&B!==null&&B.type===T&&B.key===null&&(B=B.props.children),typeof B=="object"&&B!==null){switch(B.$$typeof){case _:e:{for(var he=B.key;N!==null;){if(N.key===he){if(he=B.type,he===T){if(N.tag===7){r(O,N.sibling),F=h(N,B.props.children),F.return=O,O=F;break e}}else if(N.elementType===he||typeof he=="object"&&he!==null&&he.$$typeof===Y&&Ti(he)===N.type){r(O,N.sibling),F=h(N,B.props),pr(F,B),F.return=O,O=F;break e}r(O,N);break}else s(O,N);N=N.sibling}B.type===T?(F=vi(B.props.children,O.mode,F,B.key),F.return=O,O=F):(F=Go(B.type,B.key,B.props,null,O.mode,F),pr(F,B),F.return=O,O=F)}return b(O);case S:e:{for(he=B.key;N!==null;){if(N.key===he)if(N.tag===4&&N.stateNode.containerInfo===B.containerInfo&&N.stateNode.implementation===B.implementation){r(O,N.sibling),F=h(N,B.children||[]),F.return=O,O=F;break e}else{r(O,N);break}else s(O,N);N=N.sibling}F=vu(B,O.mode,F),F.return=O,O=F}return b(O);case Y:return B=Ti(B),Ge(O,N,B,F)}if(Be(B))return ie(O,N,B,F);if(ye(B)){if(he=ye(B),typeof he!="function")throw Error(a(150));return B=he.call(B),pe(O,N,B,F)}if(typeof B.then=="function")return Ge(O,N,Wo(B),F);if(B.$$typeof===C)return Ge(O,N,Xo(O,B),F);el(O,B)}return typeof B=="string"&&B!==""||typeof B=="number"||typeof B=="bigint"?(B=""+B,N!==null&&N.tag===6?(r(O,N.sibling),F=h(N,B),F.return=O,O=F):(r(O,N),F=bu(B,O.mode,F),F.return=O,O=F),b(O)):r(O,N)}return function(O,N,B,F){try{mr=0;var he=Ge(O,N,B,F);return oa=null,he}catch(ce){if(ce===ra||ce===Qo)throw ce;var Oe=Wt(29,ce,null,O.mode);return Oe.lanes=F,Oe.return=O,Oe}finally{}}}var Ai=rp(!0),op=rp(!1),zs=!1;function Cu(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ou(t,s){t=t.updateQueue,s.updateQueue===t&&(s.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function Ps(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function Vs(t,s,r){var o=t.updateQueue;if(o===null)return null;if(o=o.shared,(Le&2)!==0){var h=o.pending;return h===null?s.next=s:(s.next=h.next,h.next=s),o.pending=s,s=Io(t),Fm(t,null,r),s}return Fo(t,o,s,r),Io(t)}function gr(t,s,r){if(s=s.updateQueue,s!==null&&(s=s.shared,(r&4194048)!==0)){var o=s.lanes;o&=t.pendingLanes,r|=o,s.lanes=r,Za(t,r)}}function Du(t,s){var r=t.updateQueue,o=t.alternate;if(o!==null&&(o=o.updateQueue,r===o)){var h=null,f=null;if(r=r.firstBaseUpdate,r!==null){do{var b={lane:r.lane,tag:r.tag,payload:r.payload,callback:null,next:null};f===null?h=f=b:f=f.next=b,r=r.next}while(r!==null);f===null?h=f=s:f=f.next=s}else h=f=s;r={baseState:o.baseState,firstBaseUpdate:h,lastBaseUpdate:f,shared:o.shared,callbacks:o.callbacks},t.updateQueue=r;return}t=r.lastBaseUpdate,t===null?r.firstBaseUpdate=s:t.next=s,r.lastBaseUpdate=s}var Mu=!1;function yr(){if(Mu){var t=aa;if(t!==null)throw t}}function br(t,s,r,o){Mu=!1;var h=t.updateQueue;zs=!1;var f=h.firstBaseUpdate,b=h.lastBaseUpdate,w=h.shared.pending;if(w!==null){h.shared.pending=null;var E=w,U=E.next;E.next=null,b===null?f=U:b.next=U,b=E;var $=t.alternate;$!==null&&($=$.updateQueue,w=$.lastBaseUpdate,w!==b&&(w===null?$.firstBaseUpdate=U:w.next=U,$.lastBaseUpdate=E))}if(f!==null){var I=h.baseState;b=0,$=U=E=null,w=f;do{var z=w.lane&-536870913,V=z!==w.lane;if(V?(Te&z)===z:(o&z)===z){z!==0&&z===ia&&(Mu=!0),$!==null&&($=$.next={lane:0,tag:w.tag,payload:w.payload,callback:null,next:null});e:{var ie=t,pe=w;z=s;var Ge=r;switch(pe.tag){case 1:if(ie=pe.payload,typeof ie=="function"){I=ie.call(Ge,I,z);break e}I=ie;break e;case 3:ie.flags=ie.flags&-65537|128;case 0:if(ie=pe.payload,z=typeof ie=="function"?ie.call(Ge,I,z):ie,z==null)break e;I=v({},I,z);break e;case 2:zs=!0}}z=w.callback,z!==null&&(t.flags|=64,V&&(t.flags|=8192),V=h.callbacks,V===null?h.callbacks=[z]:V.push(z))}else V={lane:z,tag:w.tag,payload:w.payload,callback:w.callback,next:null},$===null?(U=$=V,E=I):$=$.next=V,b|=z;if(w=w.next,w===null){if(w=h.shared.pending,w===null)break;V=w,w=V.next,V.next=null,h.lastBaseUpdate=V,h.shared.pending=null}}while(!0);$===null&&(E=I),h.baseState=E,h.firstBaseUpdate=U,h.lastBaseUpdate=$,f===null&&(h.shared.lanes=0),Is|=b,t.lanes=b,t.memoizedState=I}}function lp(t,s){if(typeof t!="function")throw Error(a(191,t));t.call(s)}function cp(t,s){var r=t.callbacks;if(r!==null)for(t.callbacks=null,t=0;tf?f:8;var b=L.T,w={};L.T=w,Wu(t,!1,s,r);try{var E=h(),U=L.S;if(U!==null&&U(w,E),E!==null&&typeof E=="object"&&typeof E.then=="function"){var $=L_(E,o);wr(t,s,$,an(t))}else wr(t,s,o,an(t))}catch(I){wr(t,s,{then:function(){},status:"rejected",reason:I},an())}finally{W.p=f,b!==null&&w.types!==null&&(b.types=w.types),L.T=b}}function q_(){}function Qu(t,s,r,o){if(t.tag!==5)throw Error(a(476));var h=Hp(t).queue;Vp(t,h,s,Q,r===null?q_:function(){return $p(t),r(o)})}function Hp(t){var s=t.memoizedState;if(s!==null)return s;s={memoizedState:Q,baseState:Q,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:gs,lastRenderedState:Q},next:null};var r={};return s.next={memoizedState:r,baseState:r,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:gs,lastRenderedState:r},next:null},t.memoizedState=s,t=t.alternate,t!==null&&(t.memoizedState=s),s}function $p(t){var s=Hp(t);s.next===null&&(s=t.alternate.memoizedState),wr(t,s.next.queue,{},an())}function Zu(){return Dt(zr)}function qp(){return mt().memoizedState}function Fp(){return mt().memoizedState}function F_(t){for(var s=t.return;s!==null;){switch(s.tag){case 24:case 3:var r=an();t=Ps(r);var o=Vs(s,t,r);o!==null&&(Xt(o,s,r),gr(o,s,r)),s={cache:ju()},t.payload=s;return}s=s.return}}function I_(t,s,r){var o=an();r={lane:o,revertLane:0,gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},ul(t)?Gp(s,r):(r=gu(t,s,r,o),r!==null&&(Xt(r,t,o),Kp(r,s,o)))}function Ip(t,s,r){var o=an();wr(t,s,r,o)}function wr(t,s,r,o){var h={lane:o,revertLane:0,gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null};if(ul(t))Gp(s,h);else{var f=t.alternate;if(t.lanes===0&&(f===null||f.lanes===0)&&(f=s.lastRenderedReducer,f!==null))try{var b=s.lastRenderedState,w=f(b,r);if(h.hasEagerState=!0,h.eagerState=w,Zt(w,b))return Fo(t,s,h,0),Ke===null&&qo(),!1}catch{}finally{}if(r=gu(t,s,h,o),r!==null)return Xt(r,t,o),Kp(r,s,o),!0}return!1}function Wu(t,s,r,o){if(o={lane:2,revertLane:Ch(),gesture:null,action:o,hasEagerState:!1,eagerState:null,next:null},ul(t)){if(s)throw Error(a(479))}else s=gu(t,r,o,2),s!==null&&Xt(s,t,2)}function ul(t){var s=t.alternate;return t===ve||s!==null&&s===ve}function Gp(t,s){ca=sl=!0;var r=t.pending;r===null?s.next=s:(s.next=r.next,r.next=s),t.pending=s}function Kp(t,s,r){if((r&4194048)!==0){var o=s.lanes;o&=t.pendingLanes,r|=o,s.lanes=r,Za(t,r)}}var _r={readContext:Dt,use:rl,useCallback:ot,useContext:ot,useEffect:ot,useImperativeHandle:ot,useLayoutEffect:ot,useInsertionEffect:ot,useMemo:ot,useReducer:ot,useRef:ot,useState:ot,useDebugValue:ot,useDeferredValue:ot,useTransition:ot,useSyncExternalStore:ot,useId:ot,useHostTransitionStatus:ot,useFormState:ot,useActionState:ot,useOptimistic:ot,useMemoCache:ot,useCacheRefresh:ot};_r.useEffectEvent=ot;var Yp={readContext:Dt,use:rl,useCallback:function(t,s){return Ht().memoizedState=[t,s===void 0?null:s],t},useContext:Dt,useEffect:Cp,useImperativeHandle:function(t,s,r){r=r!=null?r.concat([t]):null,ll(4194308,4,Bp.bind(null,s,t),r)},useLayoutEffect:function(t,s){return ll(4194308,4,t,s)},useInsertionEffect:function(t,s){ll(4,2,t,s)},useMemo:function(t,s){var r=Ht();s=s===void 0?null:s;var o=t();if(ji){cn(!0);try{t()}finally{cn(!1)}}return r.memoizedState=[o,s],o},useReducer:function(t,s,r){var o=Ht();if(r!==void 0){var h=r(s);if(ji){cn(!0);try{r(s)}finally{cn(!1)}}}else h=s;return o.memoizedState=o.baseState=h,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:h},o.queue=t,t=t.dispatch=I_.bind(null,ve,t),[o.memoizedState,t]},useRef:function(t){var s=Ht();return t={current:t},s.memoizedState=t},useState:function(t){t=Gu(t);var s=t.queue,r=Ip.bind(null,ve,s);return s.dispatch=r,[t.memoizedState,r]},useDebugValue:Xu,useDeferredValue:function(t,s){var r=Ht();return Ju(r,t,s)},useTransition:function(){var t=Gu(!1);return t=Vp.bind(null,ve,t.queue,!0,!1),Ht().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,s,r){var o=ve,h=Ht();if(je){if(r===void 0)throw Error(a(407));r=r()}else{if(r=s(),Ke===null)throw Error(a(349));(Te&127)!==0||pp(o,s,r)}h.memoizedState=r;var f={value:r,getSnapshot:s};return h.queue=f,Cp(yp.bind(null,o,f,t),[t]),o.flags|=2048,ha(9,{destroy:void 0},gp.bind(null,o,f,r,s),null),r},useId:function(){var t=Ht(),s=Ke.identifierPrefix;if(je){var r=Kn,o=Gn;r=(o&~(1<<32-Vt(o)-1)).toString(32)+r,s="_"+s+"R_"+r,r=il++,0<\/script>",f=f.removeChild(f.firstChild);break;case"select":f=typeof o.is=="string"?b.createElement("select",{is:o.is}):b.createElement("select"),o.multiple?f.multiple=!0:o.size&&(f.size=o.size);break;default:f=typeof o.is=="string"?b.createElement(h,{is:o.is}):b.createElement(h)}}f[R]=s,f[X]=o;e:for(b=s.child;b!==null;){if(b.tag===5||b.tag===6)f.appendChild(b.stateNode);else if(b.tag!==4&&b.tag!==27&&b.child!==null){b.child.return=b,b=b.child;continue}if(b===s)break e;for(;b.sibling===null;){if(b.return===null||b.return===s)break e;b=b.return}b.sibling.return=b.return,b=b.sibling}s.stateNode=f;e:switch(Bt(f,h,o),h){case"button":case"input":case"select":case"textarea":o=!!o.autoFocus;break e;case"img":o=!0;break e;default:o=!1}o&&bs(s)}}return et(s),fh(s,s.type,t===null?null:t.memoizedProps,s.pendingProps,r),null;case 6:if(t&&s.stateNode!=null)t.memoizedProps!==o&&bs(s);else{if(typeof o!="string"&&s.stateNode===null)throw Error(a(166));if(t=ge.current,na(s)){if(t=s.stateNode,r=s.memoizedProps,o=null,h=Ot,h!==null)switch(h.tag){case 27:case 5:o=h.memoizedProps}t[R]=s,t=!!(t.nodeValue===r||o!==null&&o.suppressHydrationWarning===!0||fy(t.nodeValue,r)),t||Us(s,!0)}else t=kl(t).createTextNode(o),t[R]=s,s.stateNode=t}return et(s),null;case 31:if(r=s.memoizedState,t===null||t.memoizedState!==null){if(o=na(s),r!==null){if(t===null){if(!o)throw Error(a(318));if(t=s.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(a(557));t[R]=s}else xi(),(s.flags&128)===0&&(s.memoizedState=null),s.flags|=4;et(s),t=!1}else r=Su(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=r),t=!0;if(!t)return s.flags&256?(tn(s),s):(tn(s),null);if((s.flags&128)!==0)throw Error(a(558))}return et(s),null;case 13:if(o=s.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(h=na(s),o!==null&&o.dehydrated!==null){if(t===null){if(!h)throw Error(a(318));if(h=s.memoizedState,h=h!==null?h.dehydrated:null,!h)throw Error(a(317));h[R]=s}else xi(),(s.flags&128)===0&&(s.memoizedState=null),s.flags|=4;et(s),h=!1}else h=Su(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=h),h=!0;if(!h)return s.flags&256?(tn(s),s):(tn(s),null)}return tn(s),(s.flags&128)!==0?(s.lanes=r,s):(r=o!==null,t=t!==null&&t.memoizedState!==null,r&&(o=s.child,h=null,o.alternate!==null&&o.alternate.memoizedState!==null&&o.alternate.memoizedState.cachePool!==null&&(h=o.alternate.memoizedState.cachePool.pool),f=null,o.memoizedState!==null&&o.memoizedState.cachePool!==null&&(f=o.memoizedState.cachePool.pool),f!==h&&(o.flags|=2048)),r!==t&&r&&(s.child.flags|=8192),pl(s,s.updateQueue),et(s),null);case 4:return qe(),t===null&&Bh(s.stateNode.containerInfo),et(s),null;case 10:return ms(s.type),et(s),null;case 19:if(q(ft),o=s.memoizedState,o===null)return et(s),null;if(h=(s.flags&128)!==0,f=o.rendering,f===null)if(h)Tr(o,!1);else{if(lt!==0||t!==null&&(t.flags&128)!==0)for(t=s.child;t!==null;){if(f=nl(t),f!==null){for(s.flags|=128,Tr(o,!1),t=f.updateQueue,s.updateQueue=t,pl(s,t),s.subtreeFlags=0,t=r,r=s.child;r!==null;)Im(r,t),r=r.sibling;return J(ft,ft.current&1|2),je&&ds(s,o.treeForkCount),s.child}t=t.sibling}o.tail!==null&&Ze()>xl&&(s.flags|=128,h=!0,Tr(o,!1),s.lanes=4194304)}else{if(!h)if(t=nl(f),t!==null){if(s.flags|=128,h=!0,t=t.updateQueue,s.updateQueue=t,pl(s,t),Tr(o,!0),o.tail===null&&o.tailMode==="hidden"&&!f.alternate&&!je)return et(s),null}else 2*Ze()-o.renderingStartTime>xl&&r!==536870912&&(s.flags|=128,h=!0,Tr(o,!1),s.lanes=4194304);o.isBackwards?(f.sibling=s.child,s.child=f):(t=o.last,t!==null?t.sibling=f:s.child=f,o.last=f)}return o.tail!==null?(t=o.tail,o.rendering=t,o.tail=t.sibling,o.renderingStartTime=Ze(),t.sibling=null,r=ft.current,J(ft,h?r&1|2:r&1),je&&ds(s,o.treeForkCount),t):(et(s),null);case 22:case 23:return tn(s),Uu(),o=s.memoizedState!==null,t!==null?t.memoizedState!==null!==o&&(s.flags|=8192):o&&(s.flags|=8192),o?(r&536870912)!==0&&(s.flags&128)===0&&(et(s),s.subtreeFlags&6&&(s.flags|=8192)):et(s),r=s.updateQueue,r!==null&&pl(s,r.retryQueue),r=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),o=null,s.memoizedState!==null&&s.memoizedState.cachePool!==null&&(o=s.memoizedState.cachePool.pool),o!==r&&(s.flags|=2048),t!==null&&q(Si),null;case 24:return r=null,t!==null&&(r=t.memoizedState.cache),s.memoizedState.cache!==r&&(s.flags|=2048),ms(bt),et(s),null;case 25:return null;case 30:return null}throw Error(a(156,s.tag))}function J_(t,s){switch(wu(s),s.tag){case 1:return t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 3:return ms(bt),qe(),t=s.flags,(t&65536)!==0&&(t&128)===0?(s.flags=t&-65537|128,s):null;case 26:case 27:case 5:return jn(s),null;case 31:if(s.memoizedState!==null){if(tn(s),s.alternate===null)throw Error(a(340));xi()}return t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 13:if(tn(s),t=s.memoizedState,t!==null&&t.dehydrated!==null){if(s.alternate===null)throw Error(a(340));xi()}return t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 19:return q(ft),null;case 4:return qe(),null;case 10:return ms(s.type),null;case 22:case 23:return tn(s),Uu(),t!==null&&q(Si),t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 24:return ms(bt),null;case 25:return null;default:return null}}function bg(t,s){switch(wu(s),s.tag){case 3:ms(bt),qe();break;case 26:case 27:case 5:jn(s);break;case 4:qe();break;case 31:s.memoizedState!==null&&tn(s);break;case 13:tn(s);break;case 19:q(ft);break;case 10:ms(s.type);break;case 22:case 23:tn(s),Uu(),t!==null&&q(Si);break;case 24:ms(bt)}}function Er(t,s){try{var r=s.updateQueue,o=r!==null?r.lastEffect:null;if(o!==null){var h=o.next;r=h;do{if((r.tag&t)===t){o=void 0;var f=r.create,b=r.inst;o=f(),b.destroy=o}r=r.next}while(r!==h)}}catch(w){$e(s,s.return,w)}}function qs(t,s,r){try{var o=s.updateQueue,h=o!==null?o.lastEffect:null;if(h!==null){var f=h.next;o=f;do{if((o.tag&t)===t){var b=o.inst,w=b.destroy;if(w!==void 0){b.destroy=void 0,h=s;var E=r,U=w;try{U()}catch($){$e(h,E,$)}}}o=o.next}while(o!==f)}}catch($){$e(s,s.return,$)}}function vg(t){var s=t.updateQueue;if(s!==null){var r=t.stateNode;try{cp(s,r)}catch(o){$e(t,t.return,o)}}}function xg(t,s,r){r.props=Ni(t.type,t.memoizedProps),r.state=t.memoizedState;try{r.componentWillUnmount()}catch(o){$e(t,s,o)}}function Ar(t,s){try{var r=t.ref;if(r!==null){switch(t.tag){case 26:case 27:case 5:var o=t.stateNode;break;case 30:o=t.stateNode;break;default:o=t.stateNode}typeof r=="function"?t.refCleanup=r(o):r.current=o}}catch(h){$e(t,s,h)}}function Yn(t,s){var r=t.ref,o=t.refCleanup;if(r!==null)if(typeof o=="function")try{o()}catch(h){$e(t,s,h)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof r=="function")try{r(null)}catch(h){$e(t,s,h)}else r.current=null}function wg(t){var s=t.type,r=t.memoizedProps,o=t.stateNode;try{e:switch(s){case"button":case"input":case"select":case"textarea":r.autoFocus&&o.focus();break e;case"img":r.src?o.src=r.src:r.srcSet&&(o.srcset=r.srcSet)}}catch(h){$e(t,t.return,h)}}function mh(t,s,r){try{var o=t.stateNode;bS(o,t.type,r,s),o[X]=s}catch(h){$e(t,t.return,h)}}function _g(t){return t.tag===5||t.tag===3||t.tag===26||t.tag===27&&Js(t.type)||t.tag===4}function ph(t){e:for(;;){for(;t.sibling===null;){if(t.return===null||_g(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.tag===27&&Js(t.type)||t.flags&2||t.child===null||t.tag===4)continue e;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function gh(t,s,r){var o=t.tag;if(o===5||o===6)t=t.stateNode,s?(r.nodeType===9?r.body:r.nodeName==="HTML"?r.ownerDocument.body:r).insertBefore(t,s):(s=r.nodeType===9?r.body:r.nodeName==="HTML"?r.ownerDocument.body:r,s.appendChild(t),r=r._reactRootContainer,r!=null||s.onclick!==null||(s.onclick=cs));else if(o!==4&&(o===27&&Js(t.type)&&(r=t.stateNode,s=null),t=t.child,t!==null))for(gh(t,s,r),t=t.sibling;t!==null;)gh(t,s,r),t=t.sibling}function gl(t,s,r){var o=t.tag;if(o===5||o===6)t=t.stateNode,s?r.insertBefore(t,s):r.appendChild(t);else if(o!==4&&(o===27&&Js(t.type)&&(r=t.stateNode),t=t.child,t!==null))for(gl(t,s,r),t=t.sibling;t!==null;)gl(t,s,r),t=t.sibling}function Sg(t){var s=t.stateNode,r=t.memoizedProps;try{for(var o=t.type,h=s.attributes;h.length;)s.removeAttributeNode(h[0]);Bt(s,o,r),s[R]=t,s[X]=r}catch(f){$e(t,t.return,f)}}var vs=!1,wt=!1,yh=!1,Tg=typeof WeakSet=="function"?WeakSet:Set,Rt=null;function Q_(t,s){if(t=t.containerInfo,zh=Ll,t=Um(t),uu(t)){if("selectionStart"in t)var r={start:t.selectionStart,end:t.selectionEnd};else e:{r=(r=t.ownerDocument)&&r.defaultView||window;var o=r.getSelection&&r.getSelection();if(o&&o.rangeCount!==0){r=o.anchorNode;var h=o.anchorOffset,f=o.focusNode;o=o.focusOffset;try{r.nodeType,f.nodeType}catch{r=null;break e}var b=0,w=-1,E=-1,U=0,$=0,I=t,z=null;t:for(;;){for(var V;I!==r||h!==0&&I.nodeType!==3||(w=b+h),I!==f||o!==0&&I.nodeType!==3||(E=b+o),I.nodeType===3&&(b+=I.nodeValue.length),(V=I.firstChild)!==null;)z=I,I=V;for(;;){if(I===t)break t;if(z===r&&++U===h&&(w=b),z===f&&++$===o&&(E=b),(V=I.nextSibling)!==null)break;I=z,z=I.parentNode}I=V}r=w===-1||E===-1?null:{start:w,end:E}}else r=null}r=r||{start:0,end:0}}else r=null;for(Ph={focusedElem:t,selectionRange:r},Ll=!1,Rt=s;Rt!==null;)if(s=Rt,t=s.child,(s.subtreeFlags&1028)!==0&&t!==null)t.return=s,Rt=t;else for(;Rt!==null;){switch(s=Rt,f=s.alternate,t=s.flags,s.tag){case 0:if((t&4)!==0&&(t=s.updateQueue,t=t!==null?t.events:null,t!==null))for(r=0;r title"))),Bt(f,o,r),f[R]=t,Ve(f),o=f;break e;case"link":var b=ky("link","href",h).get(o+(r.href||""));if(b){for(var w=0;wGe&&(b=Ge,Ge=pe,pe=b);var O=Mm(w,pe),N=Mm(w,Ge);if(O&&N&&(V.rangeCount!==1||V.anchorNode!==O.node||V.anchorOffset!==O.offset||V.focusNode!==N.node||V.focusOffset!==N.offset)){var B=I.createRange();B.setStart(O.node,O.offset),V.removeAllRanges(),pe>Ge?(V.addRange(B),V.extend(N.node,N.offset)):(B.setEnd(N.node,N.offset),V.addRange(B))}}}}for(I=[],V=w;V=V.parentNode;)V.nodeType===1&&I.push({element:V,left:V.scrollLeft,top:V.scrollTop});for(typeof w.focus=="function"&&w.focus(),w=0;wr?32:r,L.T=null,r=Th,Th=null;var f=Ks,b=Ts;if(Tt=0,ga=Ks=null,Ts=0,(Le&6)!==0)throw Error(a(331));var w=Le;if(Le|=4,Bg(f.current),Og(f,f.current,b,r),Le=w,Or(0,!1),yt&&typeof yt.onPostCommitFiberRoot=="function")try{yt.onPostCommitFiberRoot(rs,f)}catch{}return!0}finally{W.p=h,L.T=o,Wg(t,s)}}function ty(t,s,r){s=gn(r,s),s=sh(t.stateNode,s,2),t=Vs(t,s,2),t!==null&&(Os(t,2),Xn(t))}function $e(t,s,r){if(t.tag===3)ty(t,t,r);else for(;s!==null;){if(s.tag===3){ty(s,t,r);break}else if(s.tag===1){var o=s.stateNode;if(typeof s.type.getDerivedStateFromError=="function"||typeof o.componentDidCatch=="function"&&(Gs===null||!Gs.has(o))){t=gn(r,t),r=ng(2),o=Vs(s,r,2),o!==null&&(sg(r,o,s,t),Os(o,2),Xn(o));break}}s=s.return}}function Nh(t,s,r){var o=t.pingCache;if(o===null){o=t.pingCache=new eS;var h=new Set;o.set(s,h)}else h=o.get(s),h===void 0&&(h=new Set,o.set(s,h));h.has(r)||(xh=!0,h.add(r),t=aS.bind(null,t,s,r),s.then(t,t))}function aS(t,s,r){var o=t.pingCache;o!==null&&o.delete(s),t.pingedLanes|=t.suspendedLanes&r,t.warmLanes&=~r,Ke===t&&(Te&r)===r&&(lt===4||lt===3&&(Te&62914560)===Te&&300>Ze()-vl?(Le&2)===0&&ya(t,0):wh|=r,pa===Te&&(pa=0)),Xn(t)}function ny(t,s){s===0&&(s=jo()),t=bi(t,s),t!==null&&(Os(t,s),Xn(t))}function rS(t){var s=t.memoizedState,r=0;s!==null&&(r=s.retryLane),ny(t,r)}function oS(t,s){var r=0;switch(t.tag){case 31:case 13:var o=t.stateNode,h=t.memoizedState;h!==null&&(r=h.retryLane);break;case 19:o=t.stateNode;break;case 22:o=t.stateNode._retryCache;break;default:throw Error(a(314))}o!==null&&o.delete(s),ny(t,r)}function lS(t,s){return ht(t,s)}var Al=null,va=null,Rh=!1,jl=!1,kh=!1,Xs=0;function Xn(t){t!==va&&t.next===null&&(va===null?Al=va=t:va=va.next=t),jl=!0,Rh||(Rh=!0,uS())}function Or(t,s){if(!kh&&jl){kh=!0;do for(var r=!1,o=Al;o!==null;){if(t!==0){var h=o.pendingLanes;if(h===0)var f=0;else{var b=o.suspendedLanes,w=o.pingedLanes;f=(1<<31-Vt(42|t)+1)-1,f&=h&~(b&~w),f=f&201326741?f&201326741|1:f?f|2:0}f!==0&&(r=!0,ry(o,f))}else f=Te,f=qi(o,o===Ke?f:0,o.cancelPendingCommit!==null||o.timeoutHandle!==-1),(f&3)===0||fi(o,f)||(r=!0,ry(o,f));o=o.next}while(r);kh=!1}}function cS(){sy()}function sy(){jl=Rh=!1;var t=0;Xs!==0&&xS()&&(t=Xs);for(var s=Ze(),r=null,o=Al;o!==null;){var h=o.next,f=iy(o,s);f===0?(o.next=null,r===null?Al=h:r.next=h,h===null&&(va=r)):(r=o,(t!==0||(f&3)!==0)&&(jl=!0)),o=h}Tt!==0&&Tt!==5||Or(t),Xs!==0&&(Xs=0)}function iy(t,s){for(var r=t.suspendedLanes,o=t.pingedLanes,h=t.expirationTimes,f=t.pendingLanes&-62914561;0w)break;var $=E.transferSize,I=E.initiatorType;$&&my(I)&&(E=E.responseEnd,b+=$*(E"u"?null:document;function Ay(t,s,r){var o=xa;if(o&&typeof s=="string"&&s){var h=mn(s);h='link[rel="'+t+'"][href="'+h+'"]',typeof r=="string"&&(h+='[crossorigin="'+r+'"]'),Ey.has(h)||(Ey.add(h),t={rel:t,crossOrigin:r,href:s},o.querySelector(h)===null&&(s=o.createElement("link"),Bt(s,"link",t),Ve(s),o.head.appendChild(s)))}}function RS(t){Es.D(t),Ay("dns-prefetch",t,null)}function kS(t,s){Es.C(t,s),Ay("preconnect",t,s)}function CS(t,s,r){Es.L(t,s,r);var o=xa;if(o&&t&&s){var h='link[rel="preload"][as="'+mn(s)+'"]';s==="image"&&r&&r.imageSrcSet?(h+='[imagesrcset="'+mn(r.imageSrcSet)+'"]',typeof r.imageSizes=="string"&&(h+='[imagesizes="'+mn(r.imageSizes)+'"]')):h+='[href="'+mn(t)+'"]';var f=h;switch(s){case"style":f=wa(t);break;case"script":f=_a(t)}_n.has(f)||(t=v({rel:"preload",href:s==="image"&&r&&r.imageSrcSet?void 0:t,as:s},r),_n.set(f,t),o.querySelector(h)!==null||s==="style"&&o.querySelector(Ur(f))||s==="script"&&o.querySelector(Lr(f))||(s=o.createElement("link"),Bt(s,"link",t),Ve(s),o.head.appendChild(s)))}}function OS(t,s){Es.m(t,s);var r=xa;if(r&&t){var o=s&&typeof s.as=="string"?s.as:"script",h='link[rel="modulepreload"][as="'+mn(o)+'"][href="'+mn(t)+'"]',f=h;switch(o){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":f=_a(t)}if(!_n.has(f)&&(t=v({rel:"modulepreload",href:t},s),_n.set(f,t),r.querySelector(h)===null)){switch(o){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(r.querySelector(Lr(f)))return}o=r.createElement("link"),Bt(o,"link",t),Ve(o),r.head.appendChild(o)}}}function DS(t,s,r){Es.S(t,s,r);var o=xa;if(o&&t){var h=Ue(o).hoistableStyles,f=wa(t);s=s||"default";var b=h.get(f);if(!b){var w={loading:0,preload:null};if(b=o.querySelector(Ur(f)))w.loading=5;else{t=v({rel:"stylesheet",href:t,"data-precedence":s},r),(r=_n.get(f))&&Gh(t,r);var E=b=o.createElement("link");Ve(E),Bt(E,"link",t),E._p=new Promise(function(U,$){E.onload=U,E.onerror=$}),E.addEventListener("load",function(){w.loading|=1}),E.addEventListener("error",function(){w.loading|=2}),w.loading|=4,Ol(b,s,o)}b={type:"stylesheet",instance:b,count:1,state:w},h.set(f,b)}}}function MS(t,s){Es.X(t,s);var r=xa;if(r&&t){var o=Ue(r).hoistableScripts,h=_a(t),f=o.get(h);f||(f=r.querySelector(Lr(h)),f||(t=v({src:t,async:!0},s),(s=_n.get(h))&&Kh(t,s),f=r.createElement("script"),Ve(f),Bt(f,"link",t),r.head.appendChild(f)),f={type:"script",instance:f,count:1,state:null},o.set(h,f))}}function BS(t,s){Es.M(t,s);var r=xa;if(r&&t){var o=Ue(r).hoistableScripts,h=_a(t),f=o.get(h);f||(f=r.querySelector(Lr(h)),f||(t=v({src:t,async:!0,type:"module"},s),(s=_n.get(h))&&Kh(t,s),f=r.createElement("script"),Ve(f),Bt(f,"link",t),r.head.appendChild(f)),f={type:"script",instance:f,count:1,state:null},o.set(h,f))}}function jy(t,s,r,o){var h=(h=ge.current)?Cl(h):null;if(!h)throw Error(a(446));switch(t){case"meta":case"title":return null;case"style":return typeof r.precedence=="string"&&typeof r.href=="string"?(s=wa(r.href),r=Ue(h).hoistableStyles,o=r.get(s),o||(o={type:"style",instance:null,count:0,state:null},r.set(s,o)),o):{type:"void",instance:null,count:0,state:null};case"link":if(r.rel==="stylesheet"&&typeof r.href=="string"&&typeof r.precedence=="string"){t=wa(r.href);var f=Ue(h).hoistableStyles,b=f.get(t);if(b||(h=h.ownerDocument||h,b={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},f.set(t,b),(f=h.querySelector(Ur(t)))&&!f._p&&(b.instance=f,b.state.loading=5),_n.has(t)||(r={rel:"preload",as:"style",href:r.href,crossOrigin:r.crossOrigin,integrity:r.integrity,media:r.media,hrefLang:r.hrefLang,referrerPolicy:r.referrerPolicy},_n.set(t,r),f||US(h,t,r,b.state))),s&&o===null)throw Error(a(528,""));return b}if(s&&o!==null)throw Error(a(529,""));return null;case"script":return s=r.async,r=r.src,typeof r=="string"&&s&&typeof s!="function"&&typeof s!="symbol"?(s=_a(r),r=Ue(h).hoistableScripts,o=r.get(s),o||(o={type:"script",instance:null,count:0,state:null},r.set(s,o)),o):{type:"void",instance:null,count:0,state:null};default:throw Error(a(444,t))}}function wa(t){return'href="'+mn(t)+'"'}function Ur(t){return'link[rel="stylesheet"]['+t+"]"}function Ny(t){return v({},t,{"data-precedence":t.precedence,precedence:null})}function US(t,s,r,o){t.querySelector('link[rel="preload"][as="style"]['+s+"]")?o.loading=1:(s=t.createElement("link"),o.preload=s,s.addEventListener("load",function(){return o.loading|=1}),s.addEventListener("error",function(){return o.loading|=2}),Bt(s,"link",r),Ve(s),t.head.appendChild(s))}function _a(t){return'[src="'+mn(t)+'"]'}function Lr(t){return"script[async]"+t}function Ry(t,s,r){if(s.count++,s.instance===null)switch(s.type){case"style":var o=t.querySelector('style[data-href~="'+mn(r.href)+'"]');if(o)return s.instance=o,Ve(o),o;var h=v({},r,{"data-href":r.href,"data-precedence":r.precedence,href:null,precedence:null});return o=(t.ownerDocument||t).createElement("style"),Ve(o),Bt(o,"style",h),Ol(o,r.precedence,t),s.instance=o;case"stylesheet":h=wa(r.href);var f=t.querySelector(Ur(h));if(f)return s.state.loading|=4,s.instance=f,Ve(f),f;o=Ny(r),(h=_n.get(h))&&Gh(o,h),f=(t.ownerDocument||t).createElement("link"),Ve(f);var b=f;return b._p=new Promise(function(w,E){b.onload=w,b.onerror=E}),Bt(f,"link",o),s.state.loading|=4,Ol(f,r.precedence,t),s.instance=f;case"script":return f=_a(r.src),(h=t.querySelector(Lr(f)))?(s.instance=h,Ve(h),h):(o=r,(h=_n.get(f))&&(o=v({},r),Kh(o,h)),t=t.ownerDocument||t,h=t.createElement("script"),Ve(h),Bt(h,"link",o),t.head.appendChild(h),s.instance=h);case"void":return null;default:throw Error(a(443,s.type))}else s.type==="stylesheet"&&(s.state.loading&4)===0&&(o=s.instance,s.state.loading|=4,Ol(o,r.precedence,t));return s.instance}function Ol(t,s,r){for(var o=r.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),h=o.length?o[o.length-1]:null,f=h,b=0;b title"):null)}function LS(t,s,r){if(r===1||s.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof s.precedence!="string"||typeof s.href!="string"||s.href==="")break;return!0;case"link":if(typeof s.rel!="string"||typeof s.href!="string"||s.href===""||s.onLoad||s.onError)break;switch(s.rel){case"stylesheet":return t=s.disabled,typeof s.precedence=="string"&&t==null;default:return!0}case"script":if(s.async&&typeof s.async!="function"&&typeof s.async!="symbol"&&!s.onLoad&&!s.onError&&s.src&&typeof s.src=="string")return!0}return!1}function Oy(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function zS(t,s,r,o){if(r.type==="stylesheet"&&(typeof o.media!="string"||matchMedia(o.media).matches!==!1)&&(r.state.loading&4)===0){if(r.instance===null){var h=wa(o.href),f=s.querySelector(Ur(h));if(f){s=f._p,s!==null&&typeof s=="object"&&typeof s.then=="function"&&(t.count++,t=Ml.bind(t),s.then(t,t)),r.state.loading|=4,r.instance=f,Ve(f);return}f=s.ownerDocument||s,o=Ny(o),(h=_n.get(h))&&Gh(o,h),f=f.createElement("link"),Ve(f);var b=f;b._p=new Promise(function(w,E){b.onload=w,b.onerror=E}),Bt(f,"link",o),r.instance=f}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(r,s),(s=r.state.preload)&&(r.state.loading&3)===0&&(t.count++,r=Ml.bind(t),s.addEventListener("load",r),s.addEventListener("error",r))}}var Yh=0;function PS(t,s){return t.stylesheets&&t.count===0&&Ul(t,t.stylesheets),0Yh?50:800)+s);return t.unsuspend=r,function(){t.unsuspend=null,clearTimeout(o),clearTimeout(h)}}:null}function Ml(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Ul(this,this.stylesheets);else if(this.unsuspend){var t=this.unsuspend;this.unsuspend=null,t()}}}var Bl=null;function Ul(t,s){t.stylesheets=null,t.unsuspend!==null&&(t.count++,Bl=new Map,s.forEach(VS,t),Bl=null,Ml.call(t))}function VS(t,s){if(!(s.state.loading&4)){var r=Bl.get(t);if(r)var o=r.get(null);else{r=new Map,Bl.set(t,r);for(var h=t.querySelectorAll("link[data-precedence],style[data-precedence]"),f=0;f"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}return n(),sd.exports=n1(),sd.exports}var i1=s1();const Tf=D.createContext({});function Ef(n){const e=D.useRef(null);return e.current===null&&(e.current=n()),e.current}const a1=typeof window<"u",Af=a1?D.useLayoutEffect:D.useEffect,Uc=D.createContext(null);function jf(n,e){n.indexOf(e)===-1&&n.push(e)}function pc(n,e){const i=n.indexOf(e);i>-1&&n.splice(i,1)}const ns=(n,e,i)=>i>e?e:i{};const ri={},Tv=n=>/^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(n),Ev=n=>typeof n=="object"&&n!==null,Av=n=>/^0[^.\s]+$/u.test(n);function jv(n){let e;return()=>(e===void 0&&(e=n()),e)}const An=n=>n,xo=(...n)=>n.reduce((e,i)=>a=>i(e(a))),ro=(n,e,i)=>{const a=e-n;return a?(i-n)/a:1};class Rf{constructor(){this.subscriptions=[]}add(e){return jf(this.subscriptions,e),()=>pc(this.subscriptions,e)}notify(e,i,a){const l=this.subscriptions.length;if(l)if(l===1)this.subscriptions[0](e,i,a);else for(let c=0;cn*1e3,En=n=>n/1e3,Nv=(n,e)=>e?n*(1e3/e):0,Rv=(n,e,i)=>(((1-3*i+3*e)*n+(3*i-6*e))*n+3*e)*n,r1=1e-7,o1=12;function l1(n,e,i,a,l){let c,u,d=0;do u=e+(i-e)/2,c=Rv(u,a,l)-n,c>0?i=u:e=u;while(Math.abs(c)>r1&&++dl1(c,0,1,n,i);return c=>c===0||c===1?c:Rv(l(c),e,a)}const kv=n=>e=>e<=.5?n(2*e)/2:(2-n(2*(1-e)))/2,Cv=n=>e=>1-n(1-e),Ov=wo(.33,1.53,.69,.99),kf=Cv(Ov),Dv=kv(kf),Mv=n=>n>=1?1:(n*=2)<1?.5*kf(n):.5*(2-Math.pow(2,-10*(n-1))),Cf=n=>1-Math.sin(Math.acos(n)),Bv=Cv(Cf),Uv=kv(Cf),c1=wo(.42,0,1,1),u1=wo(0,0,.58,1),Lv=wo(.42,0,.58,1),h1=n=>Array.isArray(n)&&typeof n[0]!="number",zv=n=>Array.isArray(n)&&typeof n[0]=="number",d1={linear:An,easeIn:c1,easeInOut:Lv,easeOut:u1,circIn:Cf,circInOut:Uv,circOut:Bv,backIn:kf,backInOut:Dv,backOut:Ov,anticipate:Mv},f1=n=>typeof n=="string",n0=n=>{if(zv(n)){Nf(n.length===4);const[e,i,a,l]=n;return wo(e,i,a,l)}else if(f1(n))return d1[n];return n},Fl=["setup","read","resolveKeyframes","preUpdate","update","preRender","render","postRender"];function m1(n){let e=new Set,i=new Set,a=!1,l=!1;const c=new WeakSet;let u={delta:0,timestamp:0,isProcessing:!1};function d(p){c.has(p)&&(m.schedule(p),n()),p(u)}const m={schedule:(p,y=!1,v=!1)=>{const _=v&&a?e:i;return y&&c.add(p),_.add(p),p},cancel:p=>{i.delete(p),c.delete(p)},process:p=>{if(u=p,a){l=!0;return}a=!0;const y=e;e=i,i=y,e.forEach(d),e.clear(),a=!1,l&&(l=!1,m.process(p))}};return m}const p1=40;function Pv(n,e){let i=!1,a=!0;const l={delta:0,timestamp:0,isProcessing:!1},c=()=>i=!0,u=Fl.reduce((C,P)=>(C[P]=m1(c),C),{}),{setup:d,read:m,resolveKeyframes:p,preUpdate:y,update:v,preRender:x,render:_,postRender:S}=u,T=()=>{const C=ri.useManualTiming,P=C?l.timestamp:performance.now();i=!1,C||(l.delta=a?1e3/60:Math.max(Math.min(P-l.timestamp,p1),1)),l.timestamp=P,l.isProcessing=!0,d.process(l),m.process(l),p.process(l),y.process(l),v.process(l),x.process(l),_.process(l),S.process(l),l.isProcessing=!1,i&&e&&(a=!1,n(T))},j=()=>{i=!0,a=!0,l.isProcessing||n(T)};return{schedule:Fl.reduce((C,P)=>{const K=u[P];return C[P]=(G,H=!1,Y=!1)=>(i||j(),K.schedule(G,H,Y)),C},{}),cancel:C=>{for(let P=0;P(rc===void 0&&$t.set(Ut.isProcessing||ri.useManualTiming?Ut.timestamp:performance.now()),rc),set:n=>{rc=n,queueMicrotask(g1)}},Vv=n=>e=>typeof e=="string"&&e.startsWith(n),Hv=Vv("--"),y1=Vv("var(--"),Of=n=>y1(n)?b1.test(n.split("/*")[0].trim()):!1,b1=/var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;function s0(n){return typeof n!="string"?!1:n.split("/*")[0].includes("var(--")}const Ka={test:n=>typeof n=="number",parse:parseFloat,transform:n=>n},oo={...Ka,transform:n=>ns(0,1,n)},Il={...Ka,default:1},Wr=n=>Math.round(n*1e5)/1e5,Df=/-?(?:\d+(?:\.\d+)?|\.\d+)/gu;function v1(n){return n==null}const x1=/^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu,Mf=(n,e)=>i=>!!(typeof i=="string"&&x1.test(i)&&i.startsWith(n)||e&&!v1(i)&&Object.prototype.hasOwnProperty.call(i,e)),$v=(n,e,i)=>a=>{if(typeof a!="string")return a;const[l,c,u,d]=a.match(Df);return{[n]:parseFloat(l),[e]:parseFloat(c),[i]:parseFloat(u),alpha:d!==void 0?parseFloat(d):1}},w1=n=>ns(0,255,n),ld={...Ka,transform:n=>Math.round(w1(n))},Ui={test:Mf("rgb","red"),parse:$v("red","green","blue"),transform:({red:n,green:e,blue:i,alpha:a=1})=>"rgba("+ld.transform(n)+", "+ld.transform(e)+", "+ld.transform(i)+", "+Wr(oo.transform(a))+")"};function _1(n){let e="",i="",a="",l="";return n.length>5?(e=n.substring(1,3),i=n.substring(3,5),a=n.substring(5,7),l=n.substring(7,9)):(e=n.substring(1,2),i=n.substring(2,3),a=n.substring(3,4),l=n.substring(4,5),e+=e,i+=i,a+=a,l+=l),{red:parseInt(e,16),green:parseInt(i,16),blue:parseInt(a,16),alpha:l?parseInt(l,16)/255:1}}const Ud={test:Mf("#"),parse:_1,transform:Ui.transform},_o=n=>({test:e=>typeof e=="string"&&e.endsWith(n)&&e.split(" ").length===1,parse:parseFloat,transform:e=>`${e}${n}`}),js=_o("deg"),ts=_o("%"),re=_o("px"),S1=_o("vh"),T1=_o("vw"),i0={...ts,parse:n=>ts.parse(n)/100,transform:n=>ts.transform(n*100)},Ua={test:Mf("hsl","hue"),parse:$v("hue","saturation","lightness"),transform:({hue:n,saturation:e,lightness:i,alpha:a=1})=>"hsla("+Math.round(n)+", "+ts.transform(Wr(e))+", "+ts.transform(Wr(i))+", "+Wr(oo.transform(a))+")"},St={test:n=>Ui.test(n)||Ud.test(n)||Ua.test(n),parse:n=>Ui.test(n)?Ui.parse(n):Ua.test(n)?Ua.parse(n):Ud.parse(n),transform:n=>typeof n=="string"?n:n.hasOwnProperty("red")?Ui.transform(n):Ua.transform(n),getAnimatableNone:n=>{const e=St.parse(n);return e.alpha=0,St.transform(e)}},E1=/(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;function A1(n){var e,i;return isNaN(n)&&typeof n=="string"&&(((e=n.match(Df))==null?void 0:e.length)||0)+(((i=n.match(E1))==null?void 0:i.length)||0)>0}const qv="number",Fv="color",j1="var",N1="var(",a0="${}",R1=/var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;function Fa(n){const e=n.toString(),i=[],a={color:[],number:[],var:[]},l=[];let c=0;const d=e.replace(R1,m=>(St.test(m)?(a.color.push(c),l.push(Fv),i.push(St.parse(m))):m.startsWith(N1)?(a.var.push(c),l.push(j1),i.push(m)):(a.number.push(c),l.push(qv),i.push(parseFloat(m))),++c,a0)).split(a0);return{values:i,split:d,indexes:a,types:l}}function k1(n){return Fa(n).values}function Iv({split:n,types:e}){const i=n.length;return a=>{let l="";for(let c=0;ctypeof n=="number"?0:St.test(n)?St.getAnimatableNone(n):n,D1=(n,e)=>typeof n=="number"?e!=null&&e.trim().endsWith("/")?n:0:O1(n);function M1(n){const e=Fa(n);return Iv(e)(e.values.map((a,l)=>D1(a,e.split[l])))}const Hn={test:A1,parse:k1,createTransformer:C1,getAnimatableNone:M1};function cd(n,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?n+(e-n)*6*i:i<1/2?e:i<2/3?n+(e-n)*(2/3-i)*6:n}function B1({hue:n,saturation:e,lightness:i,alpha:a}){n/=360,e/=100,i/=100;let l=0,c=0,u=0;if(!e)l=c=u=i;else{const d=i<.5?i*(1+e):i+e-i*e,m=2*i-d;l=cd(m,d,n+1/3),c=cd(m,d,n),u=cd(m,d,n-1/3)}return{red:Math.round(l*255),green:Math.round(c*255),blue:Math.round(u*255),alpha:a}}function gc(n,e){return i=>i>0?e:n}const Ye=(n,e,i)=>n+(e-n)*i,ud=(n,e,i)=>{const a=n*n,l=i*(e*e-a)+a;return l<0?0:Math.sqrt(l)},U1=[Ud,Ui,Ua],L1=n=>U1.find(e=>e.test(n));function r0(n){const e=L1(n);if(!e)return!1;let i=e.parse(n);return e===Ua&&(i=B1(i)),i}const o0=(n,e)=>{const i=r0(n),a=r0(e);if(!i||!a)return gc(n,e);const l={...i};return c=>(l.red=ud(i.red,a.red,c),l.green=ud(i.green,a.green,c),l.blue=ud(i.blue,a.blue,c),l.alpha=Ye(i.alpha,a.alpha,c),Ui.transform(l))},Ld=new Set(["none","hidden"]);function z1(n,e){return Ld.has(n)?i=>i<=0?n:e:i=>i>=1?e:n}function P1(n,e){return i=>Ye(n,e,i)}function Bf(n){return typeof n=="number"?P1:typeof n=="string"?Of(n)?gc:St.test(n)?o0:$1:Array.isArray(n)?Gv:typeof n=="object"?St.test(n)?o0:V1:gc}function Gv(n,e){const i=[...n],a=i.length,l=n.map((c,u)=>Bf(c)(c,e[u]));return c=>{for(let u=0;u{for(const c in a)i[c]=a[c](l);return i}}function H1(n,e){const i=[],a={color:0,var:0,number:0};for(let l=0;l{const i=Hn.createTransformer(e),a=Fa(n),l=Fa(e);return a.indexes.var.length===l.indexes.var.length&&a.indexes.color.length===l.indexes.color.length&&a.indexes.number.length>=l.indexes.number.length?Ld.has(n)&&!l.values.length||Ld.has(e)&&!a.values.length?z1(n,e):xo(Gv(H1(a,l),l.values),i):gc(n,e)};function Kv(n,e,i){return typeof n=="number"&&typeof e=="number"&&typeof i=="number"?Ye(n,e,i):Bf(n)(n,e)}const q1=n=>{const e=({timestamp:i})=>n(i);return{start:(i=!0)=>Xe.update(e,i),stop:()=>oi(e),now:()=>Ut.isProcessing?Ut.timestamp:$t.now()}},Yv=(n,e,i=10)=>{let a="";const l=Math.max(Math.round(e/i),2);for(let c=0;c=yc?1/0:e}function F1(n,e=100,i){const a=i({...n,keyframes:[0,e]}),l=Math.min(Uf(a),yc);return{type:"keyframes",ease:c=>a.next(l*c).value/e,duration:En(l)}}const ut={stiffness:100,damping:10,mass:1,velocity:0,duration:800,bounce:.3,visualDuration:.3,restSpeed:{granular:.01,default:2},restDelta:{granular:.005,default:.5},minDuration:.01,maxDuration:10,minDamping:.05,maxDamping:1};function zd(n,e){return n*Math.sqrt(1-e*e)}const I1=12;function G1(n,e,i){let a=i;for(let l=1;l{const y=p*u,v=y*n,x=y-i,_=zd(p,u),S=Math.exp(-v);return hd-x/_*S},c=p=>{const v=p*u*n,x=v*i+i,_=Math.pow(u,2)*Math.pow(p,2)*n,S=Math.exp(-v),T=zd(Math.pow(p,2),u);return(-l(p)+hd>0?-1:1)*((x-_)*S)/T}):(l=p=>{const y=Math.exp(-p*n),v=(p-i)*n+1;return-hd+y*v},c=p=>{const y=Math.exp(-p*n),v=(i-p)*(n*n);return y*v});const d=5/n,m=G1(l,c,d);if(n=ln(n),isNaN(m))return{stiffness:ut.stiffness,damping:ut.damping,duration:n};{const p=Math.pow(m,2)*a;return{stiffness:p,damping:u*2*Math.sqrt(a*p),duration:n}}}const Y1=["duration","bounce"],X1=["stiffness","damping","mass"];function l0(n,e){return e.some(i=>n[i]!==void 0)}function J1(n){let e={velocity:ut.velocity,stiffness:ut.stiffness,damping:ut.damping,mass:ut.mass,isResolvedFromDuration:!1,...n};if(!l0(n,X1)&&l0(n,Y1))if(e.velocity=0,n.visualDuration){const i=n.visualDuration,a=2*Math.PI/(i*1.2),l=a*a,c=2*ns(.05,1,1-(n.bounce||0))*Math.sqrt(l);e={...e,mass:ut.mass,stiffness:l,damping:c}}else{const i=K1({...n,velocity:0});e={...e,...i,mass:ut.mass},e.isResolvedFromDuration=!0}return e}function bc(n=ut.visualDuration,e=ut.bounce){const i=typeof n!="object"?{visualDuration:n,keyframes:[0,1],bounce:e}:n;let{restSpeed:a,restDelta:l}=i;const c=i.keyframes[0],u=i.keyframes[i.keyframes.length-1],d={done:!1,value:c},{stiffness:m,damping:p,mass:y,duration:v,velocity:x,isResolvedFromDuration:_}=J1({...i,velocity:-En(i.velocity||0)}),S=x||0,T=p/(2*Math.sqrt(m*y)),j=u-c,k=En(Math.sqrt(m/y)),M=Math.abs(j)<5;a||(a=M?ut.restSpeed.granular:ut.restSpeed.default),l||(l=M?ut.restDelta.granular:ut.restDelta.default);let C,P,K,G,H,Y;if(T<1)K=zd(k,T),G=(S+T*k*j)/K,C=se=>{const me=Math.exp(-T*k*se);return u-me*(G*Math.sin(K*se)+j*Math.cos(K*se))},H=T*k*G+j*K,Y=T*k*j-G*K,P=se=>Math.exp(-T*k*se)*(H*Math.sin(K*se)+Y*Math.cos(K*se));else if(T===1){C=me=>u-Math.exp(-k*me)*(j+(S+k*j)*me);const se=S+k*j;P=me=>Math.exp(-k*me)*(k*se*me-S)}else{const se=k*Math.sqrt(T*T-1);C=Ne=>{const Be=Math.exp(-T*k*Ne),L=Math.min(se*Ne,300);return u-Be*((S+T*k*j)*Math.sinh(L)+se*j*Math.cosh(L))/se};const me=(S+T*k*j)/se,ye=T*k*me-j*se,Ae=T*k*j-me*se;P=Ne=>{const Be=Math.exp(-T*k*Ne),L=Math.min(se*Ne,300);return Be*(ye*Math.sinh(L)+Ae*Math.cosh(L))}}const Z={calculatedDuration:_&&v||null,velocity:se=>ln(P(se)),next:se=>{if(!_&&T<1){const ye=Math.exp(-T*k*se),Ae=Math.sin(K*se),Ne=Math.cos(K*se),Be=u-ye*(G*Ae+j*Ne),L=ln(ye*(H*Ae+Y*Ne));return d.done=Math.abs(L)<=a&&Math.abs(u-Be)<=l,d.value=d.done?u:Be,d}const me=C(se);if(_)d.done=se>=v;else{const ye=ln(P(se));d.done=Math.abs(ye)<=a&&Math.abs(u-me)<=l}return d.value=d.done?u:me,d},toString:()=>{const se=Math.min(Uf(Z),yc),me=Yv(ye=>Z.next(se*ye).value,se,30);return se+"ms "+me},toTransition:()=>{}};return Z}bc.applyToOptions=n=>{const e=F1(n,100,bc);return n.ease=e.ease,n.duration=ln(e.duration),n.type="keyframes",n};const Q1=5;function Xv(n,e,i){const a=Math.max(e-Q1,0);return Nv(i-n(a),e-a)}function Pd({keyframes:n,velocity:e=0,power:i=.8,timeConstant:a=325,bounceDamping:l=10,bounceStiffness:c=500,modifyTarget:u,min:d,max:m,restDelta:p=.5,restSpeed:y}){const v=n[0],x={done:!1,value:v},_=Y=>d!==void 0&&Ym,S=Y=>d===void 0?m:m===void 0||Math.abs(d-Y)-T*Math.exp(-Y/a),C=Y=>k+M(Y),P=Y=>{const Z=M(Y),se=C(Y);x.done=Math.abs(Z)<=p,x.value=x.done?k:se};let K,G;const H=Y=>{_(x.value)&&(K=Y,G=bc({keyframes:[x.value,S(x.value)],velocity:Xv(C,Y,x.value),damping:l,stiffness:c,restDelta:p,restSpeed:y}))};return H(0),{calculatedDuration:null,next:Y=>{let Z=!1;return!G&&K===void 0&&(Z=!0,P(Y),H(Y)),K!==void 0&&Y>=K?G.next(Y-K):(!Z&&P(Y),x)}}}function Z1(n,e,i){const a=[],l=i||ri.mix||Kv,c=n.length-1;for(let u=0;ue[0];if(c===2&&e[0]===e[1])return()=>e[1];const u=n[0]===n[1];n[0]>n[c-1]&&(n=[...n].reverse(),e=[...e].reverse());const d=Z1(e,a,l),m=d.length,p=y=>{if(u&&y1)for(;vp(ns(n[0],n[c-1],y)):p}function eT(n,e){const i=n[n.length-1];for(let a=1;a<=e;a++){const l=ro(0,e,a);n.push(Ye(i,1,l))}}function tT(n){const e=[0];return eT(e,n.length-1),e}function nT(n,e){return n.map(i=>i*e)}function sT(n,e){return n.map(()=>e||Lv).splice(0,n.length-1)}function eo({duration:n=300,keyframes:e,times:i,ease:a="easeInOut"}){const l=h1(a)?a.map(n0):n0(a),c={done:!1,value:e[0]},u=nT(i&&i.length===e.length?i:tT(e),n),d=W1(u,e,{ease:Array.isArray(l)?l:sT(e,l)});return{calculatedDuration:n,next:m=>(c.value=d(m),c.done=m>=n,c)}}const iT=n=>n!==null;function Lc(n,{repeat:e,repeatType:i="loop"},a,l=1){const c=n.filter(iT),d=l<0||e&&i!=="loop"&&e%2===1?0:c.length-1;return!d||a===void 0?c[d]:a}const aT={decay:Pd,inertia:Pd,tween:eo,keyframes:eo,spring:bc};function Jv(n){typeof n.type=="string"&&(n.type=aT[n.type])}class Lf{constructor(){this.updateFinished()}get finished(){return this._finished}updateFinished(){this._finished=new Promise(e=>{this.resolve=e})}notifyFinished(){this.resolve()}then(e,i){return this.finished.then(e,i)}}const rT=n=>n/100;class vc extends Lf{constructor(e){super(),this.state="idle",this.startTime=null,this.isStopped=!1,this.currentTime=0,this.holdTime=null,this.playbackSpeed=1,this.delayState={done:!1,value:void 0},this.stop=()=>{var a,l;const{motionValue:i}=this.options;i&&i.updatedAt!==$t.now()&&this.tick($t.now()),this.isStopped=!0,this.state!=="idle"&&(this.teardown(),(l=(a=this.options).onStop)==null||l.call(a))},this.options=e,this.initAnimation(),this.play(),e.autoplay===!1&&this.pause()}initAnimation(){const{options:e}=this;Jv(e);const{type:i=eo,repeat:a=0,repeatDelay:l=0,repeatType:c,velocity:u=0}=e;let{keyframes:d}=e;const m=i||eo;m!==eo&&typeof d[0]!="number"&&(this.mixKeyframes=xo(rT,Kv(d[0],d[1])),d=[0,100]);const p=m({...e,keyframes:d});c==="mirror"&&(this.mirroredGenerator=m({...e,keyframes:[...d].reverse(),velocity:-u})),p.calculatedDuration===null&&(p.calculatedDuration=Uf(p));const{calculatedDuration:y}=p;this.calculatedDuration=y,this.resolvedDuration=y+l,this.totalDuration=this.resolvedDuration*(a+1)-l,this.generator=p}updateTime(e){const i=Math.round(e-this.startTime)*this.playbackSpeed;this.holdTime!==null?this.currentTime=this.holdTime:this.currentTime=i}tick(e,i=!1){const{generator:a,totalDuration:l,mixKeyframes:c,mirroredGenerator:u,resolvedDuration:d,calculatedDuration:m}=this;if(this.startTime===null)return a.next(0);const{delay:p=0,keyframes:y,repeat:v,repeatType:x,repeatDelay:_,type:S,onUpdate:T,finalKeyframe:j}=this.options;this.speed>0?this.startTime=Math.min(this.startTime,e):this.speed<0&&(this.startTime=Math.min(e-l/this.speed,this.startTime)),i?this.currentTime=e:this.updateTime(e);const k=this.currentTime-p*(this.playbackSpeed>=0?1:-1),M=this.playbackSpeed>=0?k<0:k>l;this.currentTime=Math.max(k,0),this.state==="finished"&&this.holdTime===null&&(this.currentTime=l);let C=this.currentTime,P=a;if(v){const Y=Math.min(this.currentTime,l)/d;let Z=Math.floor(Y),se=Y%1;!se&&Y>=1&&(se=1),se===1&&Z--,Z=Math.min(Z,v+1),!!(Z%2)&&(x==="reverse"?(se=1-se,_&&(se-=_/d)):x==="mirror"&&(P=u)),C=ns(0,1,se)*d}let K;M?(this.delayState.value=y[0],K=this.delayState):K=P.next(C),c&&!M&&(K.value=c(K.value));let{done:G}=K;!M&&m!==null&&(G=this.playbackSpeed>=0?this.currentTime>=l:this.currentTime<=0);const H=this.holdTime===null&&(this.state==="finished"||this.state==="running"&&G);return H&&S!==Pd&&(K.value=Lc(y,this.options,j,this.speed)),T&&T(K.value),H&&this.finish(),K}then(e,i){return this.finished.then(e,i)}get duration(){return En(this.calculatedDuration)}get iterationDuration(){const{delay:e=0}=this.options||{};return this.duration+En(e)}get time(){return En(this.currentTime)}set time(e){e=ln(e),this.currentTime=e,this.startTime===null||this.holdTime!==null||this.playbackSpeed===0?this.holdTime=e:this.driver&&(this.startTime=this.driver.now()-e/this.playbackSpeed),this.driver?this.driver.start(!1):(this.startTime=0,this.state="paused",this.holdTime=e,this.tick(e))}getGeneratorVelocity(){const e=this.currentTime;if(e<=0)return this.options.velocity||0;if(this.generator.velocity)return this.generator.velocity(e);const i=this.generator.next(e).value;return Xv(a=>this.generator.next(a).value,e,i)}get speed(){return this.playbackSpeed}set speed(e){const i=this.playbackSpeed!==e;i&&this.driver&&this.updateTime($t.now()),this.playbackSpeed=e,i&&this.driver&&(this.time=En(this.currentTime))}play(){var l,c;if(this.isStopped)return;const{driver:e=q1,startTime:i}=this.options;this.driver||(this.driver=e(u=>this.tick(u))),(c=(l=this.options).onPlay)==null||c.call(l);const a=this.driver.now();this.state==="finished"?(this.updateFinished(),this.startTime=a):this.holdTime!==null?this.startTime=a-this.holdTime:this.startTime||(this.startTime=i??a),this.state==="finished"&&this.speed<0&&(this.startTime+=this.calculatedDuration),this.holdTime=null,this.state="running",this.driver.start()}pause(){this.state="paused",this.updateTime($t.now()),this.holdTime=this.currentTime}complete(){this.state!=="running"&&this.play(),this.state="finished",this.holdTime=null}finish(){var e,i;this.notifyFinished(),this.teardown(),this.state="finished",(i=(e=this.options).onComplete)==null||i.call(e)}cancel(){var e,i;this.holdTime=null,this.startTime=0,this.tick(0),this.teardown(),(i=(e=this.options).onCancel)==null||i.call(e)}teardown(){this.state="idle",this.stopDriver(),this.startTime=this.holdTime=null}stopDriver(){this.driver&&(this.driver.stop(),this.driver=void 0)}sample(e){return this.startTime=0,this.tick(e,!0)}attachTimeline(e){var i;return this.options.allowFlatten&&(this.options.type="keyframes",this.options.ease="linear",this.initAnimation()),(i=this.driver)==null||i.stop(),e.observe(this)}}function oT(n){for(let e=1;en*180/Math.PI,Vd=n=>{const e=Li(Math.atan2(n[1],n[0]));return Hd(e)},lT={x:4,y:5,translateX:4,translateY:5,scaleX:0,scaleY:3,scale:n=>(Math.abs(n[0])+Math.abs(n[3]))/2,rotate:Vd,rotateZ:Vd,skewX:n=>Li(Math.atan(n[1])),skewY:n=>Li(Math.atan(n[2])),skew:n=>(Math.abs(n[1])+Math.abs(n[2]))/2},Hd=n=>(n=n%360,n<0&&(n+=360),n),c0=Vd,u0=n=>Math.sqrt(n[0]*n[0]+n[1]*n[1]),h0=n=>Math.sqrt(n[4]*n[4]+n[5]*n[5]),cT={x:12,y:13,z:14,translateX:12,translateY:13,translateZ:14,scaleX:u0,scaleY:h0,scale:n=>(u0(n)+h0(n))/2,rotateX:n=>Hd(Li(Math.atan2(n[6],n[5]))),rotateY:n=>Hd(Li(Math.atan2(-n[2],n[0]))),rotateZ:c0,rotate:c0,skewX:n=>Li(Math.atan(n[4])),skewY:n=>Li(Math.atan(n[1])),skew:n=>(Math.abs(n[1])+Math.abs(n[4]))/2};function $d(n){return n.includes("scale")?1:0}function qd(n,e){if(!n||n==="none")return $d(e);const i=n.match(/^matrix3d\(([-\d.e\s,]+)\)$/u);let a,l;if(i)a=cT,l=i;else{const d=n.match(/^matrix\(([-\d.e\s,]+)\)$/u);a=lT,l=d}if(!l)return $d(e);const c=a[e],u=l[1].split(",").map(hT);return typeof c=="function"?c(u):u[c]}const uT=(n,e)=>{const{transform:i="none"}=getComputedStyle(n);return qd(i,e)};function hT(n){return parseFloat(n.trim())}const Ya=["transformPerspective","x","y","z","translateX","translateY","translateZ","scale","scaleX","scaleY","rotate","rotateX","rotateY","rotateZ","skew","skewX","skewY"],Xa=new Set([...Ya,"pathRotation"]),d0=n=>n===Ka||n===re,dT=new Set(["x","y","z"]),fT=Ya.filter(n=>!dT.has(n));function mT(n){const e=[];return fT.forEach(i=>{const a=n.getValue(i);a!==void 0&&(e.push([i,a.get()]),a.set(i.startsWith("scale")?1:0))}),e}const ai={width:({x:n},{paddingLeft:e="0",paddingRight:i="0",boxSizing:a})=>{const l=n.max-n.min;return a==="border-box"?l:l-parseFloat(e)-parseFloat(i)},height:({y:n},{paddingTop:e="0",paddingBottom:i="0",boxSizing:a})=>{const l=n.max-n.min;return a==="border-box"?l:l-parseFloat(e)-parseFloat(i)},top:(n,{top:e})=>parseFloat(e),left:(n,{left:e})=>parseFloat(e),bottom:({y:n},{top:e})=>parseFloat(e)+(n.max-n.min),right:({x:n},{left:e})=>parseFloat(e)+(n.max-n.min),x:(n,{transform:e})=>qd(e,"x"),y:(n,{transform:e})=>qd(e,"y")};ai.translateX=ai.x;ai.translateY=ai.y;const Vi=new Set;let Fd=!1,Id=!1,Gd=!1;function Qv(){if(Id){const n=Array.from(Vi).filter(a=>a.needsMeasurement),e=new Set(n.map(a=>a.element)),i=new Map;e.forEach(a=>{const l=mT(a);l.length&&(i.set(a,l),a.render())}),n.forEach(a=>a.measureInitialState()),e.forEach(a=>{a.render();const l=i.get(a);l&&l.forEach(([c,u])=>{var d;(d=a.getValue(c))==null||d.set(u)})}),n.forEach(a=>a.measureEndState()),n.forEach(a=>{a.suspendedScrollY!==void 0&&window.scrollTo(0,a.suspendedScrollY)})}Id=!1,Fd=!1,Vi.forEach(n=>n.complete(Gd)),Vi.clear()}function Zv(){Vi.forEach(n=>{n.readKeyframes(),n.needsMeasurement&&(Id=!0)})}function pT(){Gd=!0,Zv(),Qv(),Gd=!1}class zf{constructor(e,i,a,l,c,u=!1){this.state="pending",this.isAsync=!1,this.needsMeasurement=!1,this.unresolvedKeyframes=[...e],this.onComplete=i,this.name=a,this.motionValue=l,this.element=c,this.isAsync=u}scheduleResolve(){this.state="scheduled",this.isAsync?(Vi.add(this),Fd||(Fd=!0,Xe.read(Zv),Xe.resolveKeyframes(Qv))):(this.readKeyframes(),this.complete())}readKeyframes(){const{unresolvedKeyframes:e,name:i,element:a,motionValue:l}=this;if(e[0]===null){const c=l==null?void 0:l.get(),u=e[e.length-1];if(c!==void 0)e[0]=c;else if(a&&i){const d=a.readValue(i,u);d!=null&&(e[0]=d)}e[0]===void 0&&(e[0]=u),l&&c===void 0&&l.set(e[0])}oT(e)}setFinalKeyframe(){}measureInitialState(){}renderEndStyles(){}measureEndState(){}complete(e=!1){this.state="complete",this.onComplete(this.unresolvedKeyframes,this.finalKeyframe,e),Vi.delete(this)}cancel(){this.state==="scheduled"&&(Vi.delete(this),this.state="pending")}resume(){this.state==="pending"&&this.scheduleResolve()}}const gT=n=>n.startsWith("--");function Wv(n,e,i){gT(e)?n.style.setProperty(e,i):n.style[e]=i}const yT={};function ex(n,e){const i=jv(n);return()=>yT[e]??i()}const bT=ex(()=>window.ScrollTimeline!==void 0,"scrollTimeline"),tx=ex(()=>{try{document.createElement("div").animate({opacity:0},{easing:"linear(0, 1)"})}catch{return!1}return!0},"linearEasing"),Yr=([n,e,i,a])=>`cubic-bezier(${n}, ${e}, ${i}, ${a})`,f0={linear:"linear",ease:"ease",easeIn:"ease-in",easeOut:"ease-out",easeInOut:"ease-in-out",circIn:Yr([0,.65,.55,1]),circOut:Yr([.55,0,1,.45]),backIn:Yr([.31,.01,.66,-.59]),backOut:Yr([.33,1.53,.69,.99])};function nx(n,e){if(n)return typeof n=="function"?tx()?Yv(n,e):"ease-out":zv(n)?Yr(n):Array.isArray(n)?n.map(i=>nx(i,e)||f0.easeOut):f0[n]}function vT(n,e,i,{delay:a=0,duration:l=300,repeat:c=0,repeatType:u="loop",ease:d="easeOut",times:m}={},p=void 0){const y={[e]:i};m&&(y.offset=m);const v=nx(d,l);Array.isArray(v)&&(y.easing=v);const x={delay:a,duration:l,easing:Array.isArray(v)?"linear":v,fill:"both",iterations:c+1,direction:u==="reverse"?"alternate":"normal"};return p&&(x.pseudoElement=p),n.animate(y,x)}function sx(n){return typeof n=="function"&&"applyToOptions"in n}function xT({type:n,...e}){return sx(n)&&tx()?n.applyToOptions(e):(e.duration??(e.duration=300),e.ease??(e.ease="easeOut"),e)}class ix extends Lf{constructor(e){if(super(),this.finishedTime=null,this.isStopped=!1,this.manualStartTime=null,!e)return;const{element:i,name:a,keyframes:l,pseudoElement:c,allowFlatten:u=!1,finalKeyframe:d,onComplete:m}=e;this.isPseudoElement=!!c,this.allowFlatten=u,this.options=e,Nf(typeof e.type!="string");const p=xT(e);this.animation=vT(i,a,l,p,c),p.autoplay===!1&&this.animation.pause(),this.animation.onfinish=()=>{if(this.finishedTime=this.time,!c){const y=Lc(l,this.options,d,this.speed);this.updateMotionValue&&this.updateMotionValue(y),Wv(i,a,y),this.animation.cancel()}m==null||m(),this.notifyFinished()}}play(){this.isStopped||(this.manualStartTime=null,this.animation.play(),this.state==="finished"&&this.updateFinished())}pause(){this.animation.pause()}complete(){var e,i;(i=(e=this.animation).finish)==null||i.call(e)}cancel(){try{this.animation.cancel()}catch{}}stop(){if(this.isStopped)return;this.isStopped=!0;const{state:e}=this;e==="idle"||e==="finished"||(this.updateMotionValue?this.updateMotionValue():this.commitStyles(),this.isPseudoElement||this.cancel())}commitStyles(){var i,a,l;const e=(i=this.options)==null?void 0:i.element;!this.isPseudoElement&&(e!=null&&e.isConnected)&&((l=(a=this.animation).commitStyles)==null||l.call(a))}get duration(){var i,a;const e=((a=(i=this.animation.effect)==null?void 0:i.getComputedTiming)==null?void 0:a.call(i).duration)||0;return En(Number(e))}get iterationDuration(){const{delay:e=0}=this.options||{};return this.duration+En(e)}get time(){return En(Number(this.animation.currentTime)||0)}set time(e){const i=this.finishedTime!==null;this.manualStartTime=null,this.finishedTime=null,this.animation.currentTime=ln(e),i&&this.animation.pause()}get speed(){return this.animation.playbackRate}set speed(e){e<0&&(this.finishedTime=null),this.animation.playbackRate=e}get state(){return this.finishedTime!==null?"finished":this.animation.playState}get startTime(){return this.manualStartTime??Number(this.animation.startTime)}set startTime(e){this.manualStartTime=this.animation.startTime=e}attachTimeline({timeline:e,rangeStart:i,rangeEnd:a,observe:l}){var c;return this.allowFlatten&&((c=this.animation.effect)==null||c.updateTiming({easing:"linear"})),this.animation.onfinish=null,e&&bT()?(this.animation.timeline=e,i&&(this.animation.rangeStart=i),a&&(this.animation.rangeEnd=a),An):l(this)}}const ax={anticipate:Mv,backInOut:Dv,circInOut:Uv};function wT(n){return n in ax}function _T(n){typeof n.ease=="string"&&wT(n.ease)&&(n.ease=ax[n.ease])}const dd=10;class ST extends ix{constructor(e){_T(e),Jv(e),super(e),e.startTime!==void 0&&e.autoplay!==!1&&(this.startTime=e.startTime),this.options=e}updateMotionValue(e){const{motionValue:i,onUpdate:a,onComplete:l,element:c,...u}=this.options;if(!i)return;if(e!==void 0){i.set(e);return}const d=new vc({...u,autoplay:!1}),m=Math.max(dd,$t.now()-this.startTime),p=ns(0,dd,m-dd),y=d.sample(m).value,{name:v}=this.options;c&&v&&Wv(c,v,y),i.setWithVelocity(d.sample(Math.max(0,m-p)).value,y,p),d.stop()}}const m0=(n,e)=>e==="zIndex"?!1:!!(typeof n=="number"||Array.isArray(n)||typeof n=="string"&&(Hn.test(n)||n==="0")&&!n.startsWith("url("));function TT(n){const e=n[0];if(n.length===1)return!0;for(let i=0;iObject.hasOwnProperty.call(Element.prototype,"animate"));function kT(n){var v;const{motionValue:e,name:i,repeatDelay:a,repeatType:l,damping:c,type:u,keyframes:d}=n;if(!(((v=e==null?void 0:e.owner)==null?void 0:v.current)instanceof HTMLElement))return!1;const{onUpdate:p,transformTemplate:y}=e.owner.getProps();return RT()&&i&&(rx.has(i)||NT.has(i)&&jT(d))&&(i!=="transform"||!y)&&!p&&!a&&l!=="mirror"&&c!==0&&u!=="inertia"}const CT=40;class OT extends Lf{constructor({autoplay:e=!0,delay:i=0,type:a="keyframes",repeat:l=0,repeatDelay:c=0,repeatType:u="loop",keyframes:d,name:m,motionValue:p,element:y,...v}){var S;super(),this.stop=()=>{var T,j;this._animation&&(this._animation.stop(),(T=this.stopTimeline)==null||T.call(this)),(j=this.keyframeResolver)==null||j.cancel()},this.createdAt=$t.now();const x={autoplay:e,delay:i,type:a,repeat:l,repeatDelay:c,repeatType:u,name:m,motionValue:p,element:y,...v},_=(y==null?void 0:y.KeyframeResolver)||zf;this.keyframeResolver=new _(d,(T,j,k)=>this.onKeyframesResolved(T,j,x,!k),m,p,y),(S=this.keyframeResolver)==null||S.scheduleResolve()}onKeyframesResolved(e,i,a,l){var k,M;this.keyframeResolver=void 0;const{name:c,type:u,velocity:d,delay:m,isHandoff:p,onUpdate:y}=a;this.resolvedAt=$t.now();let v=!0;ET(e,c,u,d)||(v=!1,(ri.instantAnimations||!m)&&(y==null||y(Lc(e,a,i))),e[0]=e[e.length-1],Kd(a),a.repeat=0);const _={startTime:l?this.resolvedAt?this.resolvedAt-this.createdAt>CT?this.resolvedAt:this.createdAt:this.createdAt:void 0,finalKeyframe:i,...a,keyframes:e},S=v&&!p&&kT(_),T=(M=(k=_.motionValue)==null?void 0:k.owner)==null?void 0:M.current;let j;if(S)try{j=new ST({..._,element:T})}catch{j=new vc(_)}else j=new vc(_);j.finished.then(()=>{this.notifyFinished()}).catch(An),this.pendingTimeline&&(this.stopTimeline=j.attachTimeline(this.pendingTimeline),this.pendingTimeline=void 0),this._animation=j}get finished(){return this._animation?this.animation.finished:this._finished}then(e,i){return this.finished.finally(e).then(()=>{})}get animation(){var e;return this._animation||((e=this.keyframeResolver)==null||e.resume(),pT()),this._animation}get duration(){return this.animation.duration}get iterationDuration(){return this.animation.iterationDuration}get time(){return this.animation.time}set time(e){this.animation.time=e}get speed(){return this.animation.speed}get state(){return this.animation.state}set speed(e){this.animation.speed=e}get startTime(){return this.animation.startTime}attachTimeline(e){return this._animation?this.stopTimeline=this.animation.attachTimeline(e):this.pendingTimeline=e,()=>this.stop()}play(){this.animation.play()}pause(){this.animation.pause()}complete(){this.animation.complete()}cancel(){var e;this._animation&&this.animation.cancel(),(e=this.keyframeResolver)==null||e.cancel()}}function ox(n,e,i,a=0,l=1){const c=Array.from(n).sort((p,y)=>p.sortNodePosition(y)).indexOf(e),u=n.size,d=(u-1)*a;return typeof i=="function"?i(c,u):l===1?c*a:d-c*a}const p0=30,DT=n=>!isNaN(parseFloat(n));class MT{constructor(e,i={}){this.canTrackVelocity=null,this.events={},this.updateAndNotify=a=>{var c;const l=$t.now();if(this.updatedAt!==l&&this.setPrevFrameValue(),this.prev=this.current,this.setCurrent(a),this.current!==this.prev&&((c=this.events.change)==null||c.notify(this.current),this.dependents))for(const u of this.dependents)u.dirty()},this.hasAnimated=!1,this.setCurrent(e),this.owner=i.owner}setCurrent(e){this.current=e,this.updatedAt=$t.now(),this.canTrackVelocity===null&&e!==void 0&&(this.canTrackVelocity=DT(this.current))}setPrevFrameValue(e=this.current){this.prevFrameValue=e,this.prevUpdatedAt=this.updatedAt}onChange(e){return this.on("change",e)}on(e,i){this.events[e]||(this.events[e]=new Rf);const a=this.events[e].add(i);return e==="change"?()=>{a(),Xe.read(()=>{this.events.change.getSize()||this.stop()})}:a}clearListeners(){for(const e in this.events)this.events[e].clear()}attach(e,i){this.passiveEffect=e,this.stopPassiveEffect=i}set(e){this.passiveEffect?this.passiveEffect(e,this.updateAndNotify):this.updateAndNotify(e)}setWithVelocity(e,i,a){this.set(i),this.prev=void 0,this.prevFrameValue=e,this.prevUpdatedAt=this.updatedAt-a}jump(e,i=!0){this.updateAndNotify(e),this.prev=e,this.prevUpdatedAt=this.prevFrameValue=void 0,i&&this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}dirty(){var e;(e=this.events.change)==null||e.notify(this.current)}addDependent(e){this.dependents||(this.dependents=new Set),this.dependents.add(e)}removeDependent(e){this.dependents&&this.dependents.delete(e)}get(){return this.current}getPrevious(){return this.prev}getVelocity(){const e=$t.now();if(!this.canTrackVelocity||this.prevFrameValue===void 0||e-this.updatedAt>p0)return 0;const i=Math.min(this.updatedAt-this.prevUpdatedAt,p0);return Nv(parseFloat(this.current)-parseFloat(this.prevFrameValue),i)}start(e){return this.stop(),new Promise(i=>{this.hasAnimated=!0,this.animation=e(i),this.events.animationStart&&this.events.animationStart.notify()}).then(()=>{this.events.animationComplete&&this.events.animationComplete.notify(),this.clearAnimation()})}stop(){this.animation&&(this.animation.stop(),this.events.animationCancel&&this.events.animationCancel.notify()),this.clearAnimation()}isAnimating(){return!!this.animation}clearAnimation(){delete this.animation}destroy(){var e,i;(e=this.dependents)==null||e.clear(),(i=this.events.destroy)==null||i.notify(),this.clearListeners(),this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}}function Ia(n,e){return new MT(n,e)}function lx(n,e){if(n!=null&&n.inherit&&e){const{inherit:i,...a}=n;return{...e,...a}}return n}function Pf(n,e){const i=(n==null?void 0:n[e])??(n==null?void 0:n.default)??n;return i!==n?lx(i,n):i}const BT={type:"spring",stiffness:500,damping:25,restSpeed:10},UT=n=>({type:"spring",stiffness:550,damping:n===0?2*Math.sqrt(550):30,restSpeed:10}),LT={type:"keyframes",duration:.8},zT={type:"keyframes",ease:[.25,.1,.35,1],duration:.3},PT=(n,{keyframes:e})=>e.length>2?LT:Xa.has(n)?n.startsWith("scale")?UT(e[1]):BT:zT,VT=new Set(["when","delay","delayChildren","staggerChildren","staggerDirection","repeat","repeatType","repeatDelay","from","elapsed"]);function HT(n){for(const e in n)if(!VT.has(e))return!0;return!1}const Vf=(n,e,i,a={},l,c)=>u=>{const d=Pf(a,n)||{},m=d.delay||a.delay||0;let{elapsed:p=0}=a;p=p-ln(m);const y={keyframes:Array.isArray(i)?i:[null,i],ease:"easeOut",velocity:e.getVelocity(),...d,delay:-p,onUpdate:x=>{e.set(x),d.onUpdate&&d.onUpdate(x)},onComplete:()=>{u(),d.onComplete&&d.onComplete()},name:n,motionValue:e,element:c?void 0:l};HT(d)||Object.assign(y,PT(n,y)),y.duration&&(y.duration=ln(y.duration)),y.repeatDelay&&(y.repeatDelay=ln(y.repeatDelay)),y.from!==void 0&&(y.keyframes[0]=y.from);let v=!1;if((y.type===!1||y.duration===0&&!y.repeatDelay)&&(Kd(y),y.delay===0&&(v=!0)),(ri.instantAnimations||ri.skipAnimations||l!=null&&l.shouldSkipAnimations||d.skipAnimations)&&(v=!0,Kd(y),y.delay=0),y.allowFlatten=!d.type&&!d.ease,v&&!c&&e.get()!==void 0){const x=Lc(y.keyframes,d);if(x!==void 0){Xe.update(()=>{y.onUpdate(x),y.onComplete()});return}}return d.isSync?new vc(y):new OT(y)},$T=/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;function qT(n){const e=$T.exec(n);if(!e)return[,];const[,i,a,l]=e;return[`--${i??a}`,l]}function cx(n,e,i=1){const[a,l]=qT(n);if(!a)return;const c=window.getComputedStyle(e).getPropertyValue(a);if(c){const u=c.trim();return Tv(u)?parseFloat(u):u}return Of(l)?cx(l,e,i+1):l}function g0(n){const e=[{},{}];return n==null||n.values.forEach((i,a)=>{e[0][a]=i.get(),e[1][a]=i.getVelocity()}),e}function Hf(n,e,i,a){if(typeof e=="function"){const[l,c]=g0(a);e=e(i!==void 0?i:n.custom,l,c)}if(typeof e=="string"&&(e=n.variants&&n.variants[e]),typeof e=="function"){const[l,c]=g0(a);e=e(i!==void 0?i:n.custom,l,c)}return e}function Hi(n,e,i){const a=n.getProps();return Hf(a,e,i!==void 0?i:a.custom,n)}const ux=new Set(["width","height","top","left","right","bottom",...Ya]),Yd=n=>Array.isArray(n);function FT(n,e,i){n.hasValue(e)?n.getValue(e).set(i):n.addValue(e,Ia(i))}function IT(n){return Yd(n)?n[n.length-1]||0:n}function GT(n,e){const i=Hi(n,e);let{transitionEnd:a={},transition:l={},...c}=i||{};c={...c,...a};for(const u in c){const d=IT(c[u]);FT(n,u,d)}}const Lt=n=>!!(n&&n.getVelocity);function KT(n){return!!(Lt(n)&&n.add)}function Xd(n,e){const i=n.getValue("willChange");if(KT(i))return i.add(e);if(!i&&ri.WillChange){const a=new ri.WillChange("auto");n.addValue("willChange",a),a.add(e)}}function $f(n){return n.replace(/([A-Z])/g,e=>`-${e.toLowerCase()}`)}const YT="framerAppearId",hx="data-"+$f(YT);function dx(n){return n.props[hx]}function XT({protectedKeys:n,needsAnimating:e},i){const a=n.hasOwnProperty(i)&&e[i]!==!0;return e[i]=!1,a}function fx(n,e,{delay:i=0,transitionOverride:a,type:l}={}){let{transition:c,transitionEnd:u,...d}=e;const m=n.getDefaultTransition();c=c?lx(c,m):m;const p=c==null?void 0:c.reduceMotion,y=c==null?void 0:c.skipAnimations;a&&(c=a);const v=[],x=l&&n.animationState&&n.animationState.getState()[l],_=c==null?void 0:c.path;_&&_.animateVisualElement(n,d,c,i,v);for(const S in d){const T=n.getValue(S,n.latestValues[S]??null),j=d[S];if(j===void 0||x&&XT(x,S))continue;const k={delay:i,...Pf(c||{},S)};y&&(k.skipAnimations=!0);const M=T.get();if(M!==void 0&&!T.isAnimating()&&!Array.isArray(j)&&j===M&&!k.velocity){Xe.update(()=>T.set(j));continue}let C=!1;if(window.MotionHandoffAnimation){const G=dx(n);if(G){const H=window.MotionHandoffAnimation(G,S,Xe);H!==null&&(k.startTime=H,C=!0)}}Xd(n,S);const P=p??n.shouldReduceMotion;T.start(Vf(S,T,j,P&&ux.has(S)?{type:!1}:k,n,C));const K=T.animation;K&&v.push(K)}if(u){const S=()=>Xe.update(()=>{u&>(n,u)});v.length?Promise.all(v).then(S):S()}return v}function Jd(n,e,i={}){var m;const a=Hi(n,e,i.type==="exit"?(m=n.presenceContext)==null?void 0:m.custom:void 0);let{transition:l=n.getDefaultTransition()||{}}=a||{};i.transitionOverride&&(l=i.transitionOverride);const c=a?()=>Promise.all(fx(n,a,i)):()=>Promise.resolve(),u=n.variantChildren&&n.variantChildren.size?(p=0)=>{const{delayChildren:y=0,staggerChildren:v,staggerDirection:x}=l;return JT(n,e,p,y,v,x,i)}:()=>Promise.resolve(),{when:d}=l;if(d){const[p,y]=d==="beforeChildren"?[c,u]:[u,c];return p().then(()=>y())}else return Promise.all([c(),u(i.delay)])}function JT(n,e,i=0,a=0,l=0,c=1,u){const d=[];for(const m of n.variantChildren)m.notify("AnimationStart",e),d.push(Jd(m,e,{...u,delay:i+(typeof a=="function"?0:a)+ox(n.variantChildren,m,a,l,c)}).then(()=>m.notify("AnimationComplete",e)));return Promise.all(d)}function QT(n,e,i={}){n.notify("AnimationStart",e);let a;if(Array.isArray(e)){const l=e.map(c=>Jd(n,c,i));a=Promise.all(l)}else if(typeof e=="string")a=Jd(n,e,i);else{const l=typeof e=="function"?Hi(n,e,i.custom):e;a=Promise.all(fx(n,l,i))}return a.then(()=>{n.notify("AnimationComplete",e)})}const ZT={test:n=>n==="auto",parse:n=>n},mx=n=>e=>e.test(n),px=[Ka,re,ts,js,T1,S1,ZT],y0=n=>px.find(mx(n));function WT(n){return typeof n=="number"?n===0:n!==null?n==="none"||n==="0"||Av(n):!0}const eE=new Set(["brightness","contrast","saturate","opacity"]);function tE(n){const[e,i]=n.slice(0,-1).split("(");if(e==="drop-shadow")return n;const[a]=i.match(Df)||[];if(!a)return n;const l=i.replace(a,"");let c=eE.has(e)?1:0;return a!==i&&(c*=100),e+"("+c+l+")"}const nE=/\b([a-z-]*)\(.*?\)/gu,Qd={...Hn,getAnimatableNone:n=>{const e=n.match(nE);return e?e.map(tE).join(" "):n}},Zd={...Hn,getAnimatableNone:n=>{const e=Hn.parse(n);return Hn.createTransformer(n)(e.map(a=>typeof a=="number"?0:typeof a=="object"?{...a,alpha:1}:a))}},b0={...Ka,transform:Math.round},sE={rotate:js,pathRotation:js,rotateX:js,rotateY:js,rotateZ:js,scale:Il,scaleX:Il,scaleY:Il,scaleZ:Il,skew:js,skewX:js,skewY:js,distance:re,translateX:re,translateY:re,translateZ:re,x:re,y:re,z:re,perspective:re,transformPerspective:re,opacity:oo,originX:i0,originY:i0,originZ:re},xc={borderWidth:re,borderTopWidth:re,borderRightWidth:re,borderBottomWidth:re,borderLeftWidth:re,borderRadius:re,borderTopLeftRadius:re,borderTopRightRadius:re,borderBottomRightRadius:re,borderBottomLeftRadius:re,width:re,maxWidth:re,height:re,maxHeight:re,top:re,right:re,bottom:re,left:re,inset:re,insetBlock:re,insetBlockStart:re,insetBlockEnd:re,insetInline:re,insetInlineStart:re,insetInlineEnd:re,padding:re,paddingTop:re,paddingRight:re,paddingBottom:re,paddingLeft:re,paddingBlock:re,paddingBlockStart:re,paddingBlockEnd:re,paddingInline:re,paddingInlineStart:re,paddingInlineEnd:re,margin:re,marginTop:re,marginRight:re,marginBottom:re,marginLeft:re,marginBlock:re,marginBlockStart:re,marginBlockEnd:re,marginInline:re,marginInlineStart:re,marginInlineEnd:re,fontSize:re,backgroundPositionX:re,backgroundPositionY:re,...sE,zIndex:b0,fillOpacity:oo,strokeOpacity:oo,numOctaves:b0},iE={...xc,color:St,backgroundColor:St,outlineColor:St,fill:St,stroke:St,borderColor:St,borderTopColor:St,borderRightColor:St,borderBottomColor:St,borderLeftColor:St,filter:Qd,WebkitFilter:Qd,mask:Zd,WebkitMask:Zd},gx=n=>iE[n],aE=new Set([Qd,Zd]);function yx(n,e){let i=gx(n);return aE.has(i)||(i=Hn),i.getAnimatableNone?i.getAnimatableNone(e):void 0}const rE=new Set(["auto","none","0"]);function oE(n,e,i){let a=0,l;for(;a{e.getValue(m).set(p)}),this.resolveNoneKeyframes()}}const qf=["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"];function bx(n,e,i){if(n==null)return[];if(n instanceof EventTarget)return[n];if(typeof n=="string"){let a=document;const l=(i==null?void 0:i[n])??a.querySelectorAll(n);return l?Array.from(l):[]}return Array.from(n).filter(a=>a!=null)}const Wd=(n,e)=>e&&typeof n=="number"?e.transform(n):n;function oc(n){return Ev(n)&&"offsetHeight"in n&&!("ownerSVGElement"in n)}const{schedule:Ff}=Pv(queueMicrotask,!1),Ln={x:!1,y:!1};function vx(){return Ln.x||Ln.y}function cE(n){return n==="x"||n==="y"?Ln[n]?null:(Ln[n]=!0,()=>{Ln[n]=!1}):Ln.x||Ln.y?null:(Ln.x=Ln.y=!0,()=>{Ln.x=Ln.y=!1})}function xx(n,e){const i=bx(n),a=new AbortController,l={passive:!0,...e,signal:a.signal};return[i,l,()=>a.abort()]}function uE(n){return!(n.pointerType==="touch"||vx())}function hE(n,e,i={}){const[a,l,c]=xx(n,i);return a.forEach(u=>{let d=!1,m=!1,p;const y=()=>{u.removeEventListener("pointerleave",S)},v=j=>{p&&(p(j),p=void 0),y()},x=j=>{d=!1,window.removeEventListener("pointerup",x),window.removeEventListener("pointercancel",x),m&&(m=!1,v(j))},_=()=>{d=!0,window.addEventListener("pointerup",x,l),window.addEventListener("pointercancel",x,l)},S=j=>{if(j.pointerType!=="touch"){if(d){m=!0;return}v(j)}},T=j=>{if(!uE(j))return;m=!1;const k=e(u,j);typeof k=="function"&&(p=k,u.addEventListener("pointerleave",S,l))};u.addEventListener("pointerenter",T,l),u.addEventListener("pointerdown",_,l)}),c}const wx=(n,e)=>e?n===e?!0:wx(n,e.parentElement):!1,If=n=>n.pointerType==="mouse"?typeof n.button!="number"||n.button<=0:n.isPrimary!==!1,dE=new Set(["BUTTON","INPUT","SELECT","TEXTAREA","A"]);function fE(n){return dE.has(n.tagName)||n.isContentEditable===!0}const mE=new Set(["INPUT","SELECT","TEXTAREA"]);function pE(n){return mE.has(n.tagName)||n.isContentEditable===!0}const lc=new WeakSet;function v0(n){return e=>{e.key==="Enter"&&n(e)}}function fd(n,e){n.dispatchEvent(new PointerEvent("pointer"+e,{isPrimary:!0,bubbles:!0}))}const gE=(n,e)=>{const i=n.currentTarget;if(!i)return;const a=v0(()=>{if(lc.has(i))return;fd(i,"down");const l=v0(()=>{fd(i,"up")}),c=()=>fd(i,"cancel");i.addEventListener("keyup",l,e),i.addEventListener("blur",c,e)});i.addEventListener("keydown",a,e),i.addEventListener("blur",()=>i.removeEventListener("keydown",a),e)};function x0(n){return If(n)&&!vx()}const w0=new WeakSet;function yE(n,e,i={}){const[a,l,c]=xx(n,i),u=d=>{const m=d.currentTarget;if(!x0(d)||w0.has(d))return;lc.add(m),i.stopPropagation&&w0.add(d);const p=e(m,d),y={...l,capture:!0},v=(S,T)=>{window.removeEventListener("pointerup",x,y),window.removeEventListener("pointercancel",_,y),lc.has(m)&&lc.delete(m),x0(S)&&typeof p=="function"&&p(S,{success:T})},x=S=>{v(S,m===window||m===document||i.useGlobalTarget||wx(m,S.target))},_=S=>{v(S,!1)};window.addEventListener("pointerup",x,y),window.addEventListener("pointercancel",_,y)};return a.forEach(d=>{(i.useGlobalTarget?window:d).addEventListener("pointerdown",u,l),oc(d)&&(d.addEventListener("focus",p=>gE(p,l)),!fE(d)&&!d.hasAttribute("tabindex")&&(d.tabIndex=0))}),c}function Gf(n){return Ev(n)&&"ownerSVGElement"in n}const cc=new WeakMap;let ni;const _x=(n,e,i)=>(a,l)=>l&&l[0]?l[0][n+"Size"]:Gf(a)&&"getBBox"in a?a.getBBox()[e]:a[i],bE=_x("inline","width","offsetWidth"),vE=_x("block","height","offsetHeight");function xE({target:n,borderBoxSize:e}){var i;(i=cc.get(n))==null||i.forEach(a=>{a(n,{get width(){return bE(n,e)},get height(){return vE(n,e)}})})}function wE(n){n.forEach(xE)}function _E(){typeof ResizeObserver>"u"||(ni=new ResizeObserver(wE))}function SE(n,e){ni||_E();const i=bx(n);return i.forEach(a=>{let l=cc.get(a);l||(l=new Set,cc.set(a,l)),l.add(e),ni==null||ni.observe(a)}),()=>{i.forEach(a=>{const l=cc.get(a);l==null||l.delete(e),l!=null&&l.size||ni==null||ni.unobserve(a)})}}const uc=new Set;let La;function TE(){La=()=>{const n={get width(){return window.innerWidth},get height(){return window.innerHeight}};uc.forEach(e=>e(n))},window.addEventListener("resize",La)}function EE(n){return uc.add(n),La||TE(),()=>{uc.delete(n),!uc.size&&typeof La=="function"&&(window.removeEventListener("resize",La),La=void 0)}}function _0(n,e){return typeof n=="function"?EE(n):SE(n,e)}function AE(n){return Gf(n)&&n.tagName==="svg"}const jE=[...px,St,Hn],NE=n=>jE.find(mx(n)),S0=()=>({translate:0,scale:1,origin:0,originPoint:0}),za=()=>({x:S0(),y:S0()}),T0=()=>({min:0,max:0}),Et=()=>({x:T0(),y:T0()}),RE=new WeakMap;function zc(n){return n!==null&&typeof n=="object"&&typeof n.start=="function"}function lo(n){return typeof n=="string"||Array.isArray(n)}const Kf=["animate","whileInView","whileFocus","whileHover","whileTap","whileDrag","exit"],Yf=["initial",...Kf];function Pc(n){return zc(n.animate)||Yf.some(e=>lo(n[e]))}function Sx(n){return!!(Pc(n)||n.variants)}function kE(n,e,i){for(const a in e){const l=e[a],c=i[a];if(Lt(l))n.addValue(a,l);else if(Lt(c))n.addValue(a,Ia(l,{owner:n}));else if(c!==l)if(n.hasValue(a)){const u=n.getValue(a);u.liveStyle===!0?u.jump(l):u.hasAnimated||u.set(l)}else{const u=n.getStaticValue(a);n.addValue(a,Ia(u!==void 0?u:l,{owner:n}))}}for(const a in i)e[a]===void 0&&n.removeValue(a);return e}const ef={current:null},Tx={current:!1},CE=typeof window<"u";function OE(){if(Tx.current=!0,!!CE)if(window.matchMedia){const n=window.matchMedia("(prefers-reduced-motion)"),e=()=>ef.current=n.matches;n.addEventListener("change",e),e()}else ef.current=!1}const E0=["AnimationStart","AnimationComplete","Update","BeforeLayoutMeasure","LayoutMeasure","LayoutAnimationStart","LayoutAnimationComplete"];let wc={};function Ex(n){wc=n}function DE(){return wc}class ME{scrapeMotionValuesFromProps(e,i,a){return{}}constructor({parent:e,props:i,presenceContext:a,reducedMotionConfig:l,skipAnimations:c,blockInitialAnimation:u,visualState:d},m={}){this.current=null,this.children=new Set,this.isVariantNode=!1,this.isControllingVariants=!1,this.shouldReduceMotion=null,this.shouldSkipAnimations=!1,this.values=new Map,this.KeyframeResolver=zf,this.features={},this.valueSubscriptions=new Map,this.prevMotionValues={},this.hasBeenMounted=!1,this.events={},this.propEventSubscriptions={},this.notifyUpdate=()=>this.notify("Update",this.latestValues),this.render=()=>{this.current&&(this.triggerBuild(),this.renderInstance(this.current,this.renderState,this.props.style,this.projection))},this.renderScheduledAt=0,this.scheduleRender=()=>{const _=$t.now();this.renderScheduledAt<_&&(this.renderScheduledAt=_,Xe.render(this.render,!1,!0))};const{latestValues:p,renderState:y}=d;this.latestValues=p,this.baseTarget={...p},this.initialValues=i.initial?{...p}:{},this.renderState=y,this.parent=e,this.props=i,this.presenceContext=a,this.depth=e?e.depth+1:0,this.reducedMotionConfig=l,this.skipAnimationsConfig=c,this.options=m,this.blockInitialAnimation=!!u,this.isControllingVariants=Pc(i),this.isVariantNode=Sx(i),this.isVariantNode&&(this.variantChildren=new Set),this.manuallyAnimateOnMount=!!(e&&e.current);const{willChange:v,...x}=this.scrapeMotionValuesFromProps(i,{},this);for(const _ in x){const S=x[_];p[_]!==void 0&&Lt(S)&&S.set(p[_])}}mount(e){var i,a;if(this.hasBeenMounted)for(const l in this.initialValues)(i=this.values.get(l))==null||i.jump(this.initialValues[l]),this.latestValues[l]=this.initialValues[l];this.current=e,RE.set(e,this),this.projection&&!this.projection.instance&&this.projection.mount(e),this.parent&&this.isVariantNode&&!this.isControllingVariants&&(this.removeFromVariantTree=this.parent.addVariantChild(this)),this.values.forEach((l,c)=>this.bindToMotionValue(c,l)),this.reducedMotionConfig==="never"?this.shouldReduceMotion=!1:this.reducedMotionConfig==="always"?this.shouldReduceMotion=!0:(Tx.current||OE(),this.shouldReduceMotion=ef.current),this.shouldSkipAnimations=this.skipAnimationsConfig??!1,(a=this.parent)==null||a.addChild(this),this.update(this.props,this.presenceContext),this.hasBeenMounted=!0}unmount(){var e;this.projection&&this.projection.unmount(),oi(this.notifyUpdate),oi(this.render),this.valueSubscriptions.forEach(i=>i()),this.valueSubscriptions.clear(),this.removeFromVariantTree&&this.removeFromVariantTree(),(e=this.parent)==null||e.removeChild(this);for(const i in this.events)this.events[i].clear();for(const i in this.features){const a=this.features[i];a&&(a.unmount(),a.isMounted=!1)}this.current=null}addChild(e){this.children.add(e),this.enteringChildren??(this.enteringChildren=new Set),this.enteringChildren.add(e)}removeChild(e){this.children.delete(e),this.enteringChildren&&this.enteringChildren.delete(e)}bindToMotionValue(e,i){if(this.valueSubscriptions.has(e)&&this.valueSubscriptions.get(e)(),i.accelerate&&rx.has(e)&&this.current instanceof HTMLElement){const{factory:u,keyframes:d,times:m,ease:p,duration:y}=i.accelerate,v=new ix({element:this.current,name:e,keyframes:d,times:m,ease:p,duration:ln(y)}),x=u(v);this.valueSubscriptions.set(e,()=>{x(),v.cancel()});return}const a=Xa.has(e);a&&this.onBindTransform&&this.onBindTransform();const l=i.on("change",u=>{this.latestValues[e]=u,this.props.onUpdate&&Xe.preRender(this.notifyUpdate),a&&this.projection&&(this.projection.isTransformDirty=!0),this.scheduleRender()});let c;typeof window<"u"&&window.MotionCheckAppearSync&&(c=window.MotionCheckAppearSync(this,e,i)),this.valueSubscriptions.set(e,()=>{l(),c&&c()})}sortNodePosition(e){return!this.current||!this.sortInstanceNodePosition||this.type!==e.type?0:this.sortInstanceNodePosition(this.current,e.current)}updateFeatures(){let e="animation";for(e in wc){const i=wc[e];if(!i)continue;const{isEnabled:a,Feature:l}=i;if(!this.features[e]&&l&&a(this.props)&&(this.features[e]=new l(this)),this.features[e]){const c=this.features[e];c.isMounted?c.update():(c.mount(),c.isMounted=!0)}}}triggerBuild(){this.build(this.renderState,this.latestValues,this.props)}measureViewportBox(){return this.current?this.measureInstanceViewportBox(this.current,this.props):Et()}getStaticValue(e){return this.latestValues[e]}setStaticValue(e,i){this.latestValues[e]=i}update(e,i){(e.transformTemplate||this.props.transformTemplate)&&this.scheduleRender(),this.prevProps=this.props,this.props=e,this.prevPresenceContext=this.presenceContext,this.presenceContext=i;for(let a=0;ai.variantChildren.delete(e)}addValue(e,i){const a=this.values.get(e);i!==a&&(a&&this.removeValue(e),this.bindToMotionValue(e,i),this.values.set(e,i),this.latestValues[e]=i.get())}removeValue(e){this.values.delete(e);const i=this.valueSubscriptions.get(e);i&&(i(),this.valueSubscriptions.delete(e)),delete this.latestValues[e],this.removeValueFromRenderState(e,this.renderState)}hasValue(e){return this.values.has(e)}getValue(e,i){if(this.props.values&&this.props.values[e])return this.props.values[e];let a=this.values.get(e);return a===void 0&&i!==void 0&&(a=Ia(i===null?void 0:i,{owner:this}),this.addValue(e,a)),a}readValue(e,i){let a=this.latestValues[e]!==void 0||!this.current?this.latestValues[e]:this.getBaseTargetFromProps(this.props,e)??this.readValueFromInstance(this.current,e,this.options);return a!=null&&(typeof a=="string"&&(Tv(a)||Av(a))?a=parseFloat(a):!NE(a)&&Hn.test(i)&&(a=yx(e,i)),this.setBaseTarget(e,Lt(a)?a.get():a)),Lt(a)?a.get():a}setBaseTarget(e,i){this.baseTarget[e]=i}getBaseTarget(e){var c;const{initial:i}=this.props;let a;if(typeof i=="string"||typeof i=="object"){const u=Hf(this.props,i,(c=this.presenceContext)==null?void 0:c.custom);u&&(a=u[e])}if(i&&a!==void 0)return a;const l=this.getBaseTargetFromProps(this.props,e);return l!==void 0&&!Lt(l)?l:this.initialValues[e]!==void 0&&a===void 0?void 0:this.baseTarget[e]}on(e,i){return this.events[e]||(this.events[e]=new Rf),this.events[e].add(i)}notify(e,...i){this.events[e]&&this.events[e].notify(...i)}scheduleRenderMicrotask(){Ff.render(this.render)}}class Ax extends ME{constructor(){super(...arguments),this.KeyframeResolver=lE}sortInstanceNodePosition(e,i){return e.compareDocumentPosition(i)&2?1:-1}getBaseTargetFromProps(e,i){const a=e.style;return a?a[i]:void 0}removeValueFromRenderState(e,{vars:i,style:a}){delete i[e],delete a[e]}handleChildMotionValue(){this.childSubscription&&(this.childSubscription(),delete this.childSubscription);const{children:e}=this.props;Lt(e)&&(this.childSubscription=e.on("change",i=>{this.current&&(this.current.textContent=`${i}`)}))}}class li{constructor(e){this.isMounted=!1,this.node=e}update(){}}function jx({top:n,left:e,right:i,bottom:a}){return{x:{min:e,max:i},y:{min:n,max:a}}}function BE({x:n,y:e}){return{top:e.min,right:n.max,bottom:e.max,left:n.min}}function UE(n,e){if(!e)return n;const i=e({x:n.left,y:n.top}),a=e({x:n.right,y:n.bottom});return{top:i.y,left:i.x,bottom:a.y,right:a.x}}function md(n){return n===void 0||n===1}function tf({scale:n,scaleX:e,scaleY:i}){return!md(n)||!md(e)||!md(i)}function Mi(n){return tf(n)||Nx(n)||n.z||n.rotate||n.rotateX||n.rotateY||n.skewX||n.skewY}function Nx(n){return A0(n.x)||A0(n.y)}function A0(n){return n&&n!=="0%"}function _c(n,e,i){const a=n-i,l=e*a;return i+l}function j0(n,e,i,a,l){return l!==void 0&&(n=_c(n,l,a)),_c(n,i,a)+e}function nf(n,e=0,i=1,a,l){n.min=j0(n.min,e,i,a,l),n.max=j0(n.max,e,i,a,l)}function Rx(n,{x:e,y:i}){nf(n.x,e.translate,e.scale,e.originPoint),nf(n.y,i.translate,i.scale,i.originPoint)}const N0=.999999999999,R0=1.0000000000001;function LE(n,e,i,a=!1){var d;const l=i.length;if(!l)return;e.x=e.y=1;let c,u;for(let m=0;mN0&&(e.x=1),e.yN0&&(e.y=1)}function Zn(n,e){n.min+=e,n.max+=e}function k0(n,e,i,a,l=.5){const c=Ye(n.min,n.max,l);nf(n,e,i,c,a)}function C0(n,e){return typeof n=="string"?parseFloat(n)/100*(e.max-e.min):n}function hc(n,e,i){const a=i??n;k0(n.x,C0(e.x,a.x),e.scaleX,e.scale,e.originX),k0(n.y,C0(e.y,a.y),e.scaleY,e.scale,e.originY)}function kx(n,e){return jx(UE(n.getBoundingClientRect(),e))}function zE(n,e,i){const a=kx(n,i),{scroll:l}=e;return l&&(Zn(a.x,l.offset.x),Zn(a.y,l.offset.y)),a}const PE={x:"translateX",y:"translateY",z:"translateZ",transformPerspective:"perspective"},VE=Ya.length;function HE(n,e,i){let a="",l=!0;for(let u=0;u{if(!e.target)return n;if(typeof n=="string")if(re.test(n))n=parseFloat(n);else return n;const i=O0(n,e.target.x),a=O0(n,e.target.y);return`${i}% ${a}%`}},$E={correct:(n,{treeScale:e,projectionDelta:i})=>{const a=n,l=Hn.parse(n);if(l.length>5)return a;const c=Hn.createTransformer(n),u=typeof l[0]!="number"?1:0,d=i.x.scale*e.x,m=i.y.scale*e.y;l[0+u]/=d,l[1+u]/=m;const p=Ye(d,m,.5);return typeof l[2+u]=="number"&&(l[2+u]/=p),typeof l[3+u]=="number"&&(l[3+u]/=p),c(l)}},sf={borderRadius:{...Fr,applyTo:[...qf]},borderTopLeftRadius:Fr,borderTopRightRadius:Fr,borderBottomLeftRadius:Fr,borderBottomRightRadius:Fr,boxShadow:$E};function Ox(n,{layout:e,layoutId:i}){return Xa.has(n)||n.startsWith("origin")||(e||i!==void 0)&&(!!sf[n]||n==="opacity")}function Jf(n,e,i){var u;const a=n.style,l=e==null?void 0:e.style,c={};if(!a)return c;for(const d in a)(Lt(a[d])||l&&Lt(l[d])||Ox(d,n)||((u=i==null?void 0:i.getValue(d))==null?void 0:u.liveStyle)!==void 0)&&(c[d]=a[d]);return c}function qE(n){return window.getComputedStyle(n)}class FE extends Ax{constructor(){super(...arguments),this.type="html",this.renderInstance=Cx}readValueFromInstance(e,i){var a;if(Xa.has(i))return(a=this.projection)!=null&&a.isProjecting?$d(i):uT(e,i);{const l=qE(e),c=(Hv(i)?l.getPropertyValue(i):l[i])||0;return typeof c=="string"?c.trim():c}}measureInstanceViewportBox(e,{transformPagePoint:i}){return kx(e,i)}build(e,i,a){Xf(e,i,a.transformTemplate)}scrapeMotionValuesFromProps(e,i,a){return Jf(e,i,a)}}const IE={offset:"stroke-dashoffset",array:"stroke-dasharray"},GE={offset:"strokeDashoffset",array:"strokeDasharray"};function KE(n,e,i=1,a=0,l=!0){n.pathLength=1;const c=l?IE:GE;n[c.offset]=`${-a}`,n[c.array]=`${e} ${i}`}const YE=["offsetDistance","offsetPath","offsetRotate","offsetAnchor"];function Dx(n,{attrX:e,attrY:i,attrScale:a,pathLength:l,pathSpacing:c=1,pathOffset:u=0,...d},m,p,y){if(Xf(n,d,p),m){n.style.viewBox&&(n.attrs.viewBox=n.style.viewBox);return}n.attrs=n.style,n.style={};const{attrs:v,style:x}=n;v.transform&&(x.transform=v.transform,delete v.transform),(x.transform||v.transformOrigin)&&(x.transformOrigin=v.transformOrigin??"50% 50%",delete v.transformOrigin),x.transform&&(x.transformBox=(y==null?void 0:y.transformBox)??"fill-box",delete v.transformBox);for(const _ of YE)v[_]!==void 0&&(x[_]=v[_],delete v[_]);e!==void 0&&(v.x=e),i!==void 0&&(v.y=i),a!==void 0&&(v.scale=a),l!==void 0&&KE(v,l,c,u,!1)}const Mx=new Set(["baseFrequency","diffuseConstant","kernelMatrix","kernelUnitLength","keySplines","keyTimes","limitingConeAngle","markerHeight","markerWidth","numOctaves","targetX","targetY","surfaceScale","specularConstant","specularExponent","stdDeviation","tableValues","viewBox","gradientTransform","pathLength","startOffset","textLength","lengthAdjust"]),Bx=n=>typeof n=="string"&&n.toLowerCase()==="svg";function XE(n,e,i,a){Cx(n,e,void 0,a);for(const l in e.attrs)n.setAttribute(Mx.has(l)?l:$f(l),e.attrs[l])}function Ux(n,e,i){const a=Jf(n,e,i);for(const l in n)if(Lt(n[l])||Lt(e[l])){const c=Ya.indexOf(l)!==-1?"attr"+l.charAt(0).toUpperCase()+l.substring(1):l;a[c]=n[l]}return a}class JE extends Ax{constructor(){super(...arguments),this.type="svg",this.isSVGTag=!1,this.measureInstanceViewportBox=Et}getBaseTargetFromProps(e,i){return e[i]}readValueFromInstance(e,i){if(Xa.has(i)){const a=gx(i);return a&&a.default||0}return i=Mx.has(i)?i:$f(i),e.getAttribute(i)}scrapeMotionValuesFromProps(e,i,a){return Ux(e,i,a)}build(e,i,a){Dx(e,i,this.isSVGTag,a.transformTemplate,a.style)}renderInstance(e,i,a,l){XE(e,i,a,l)}mount(e){this.isSVGTag=Bx(e.tagName),super.mount(e)}}const QE=Yf.length;function Lx(n){if(!n)return;if(!n.isControllingVariants){const i=n.parent?Lx(n.parent)||{}:{};return n.props.initial!==void 0&&(i.initial=n.props.initial),i}const e={};for(let i=0;iPromise.all(e.map(({animation:i,options:a})=>QT(n,i,a)))}function tA(n){let e=eA(n),i=D0(),a=!0,l=!1;const c=p=>(y,v)=>{var _;const x=Hi(n,v,p==="exit"?(_=n.presenceContext)==null?void 0:_.custom:void 0);if(x){const{transition:S,transitionEnd:T,...j}=x;y={...y,...j,...T}}return y};function u(p){e=p(n)}function d(p){const{props:y}=n,v=Lx(n.parent)||{},x=[],_=new Set;let S={},T=1/0;for(let k=0;kT&&K,se=!1;const me=Array.isArray(P)?P:[P];let ye=me.reduce(c(M),{});G===!1&&(ye={});const{prevResolvedValues:Ae={}}=C,Ne={...Ae,...ye},Be=Q=>{Z=!0,_.has(Q)&&(se=!0,_.delete(Q)),C.needsAnimating[Q]=!0;const le=n.getValue(Q);le&&(le.liveStyle=!1)};for(const Q in Ne){const le=ye[Q],ue=Ae[Q];if(S.hasOwnProperty(Q))continue;let A=!1;Yd(le)&&Yd(ue)?A=!zx(le,ue)||Y:A=le!==ue,A?le!=null?Be(Q):_.add(Q):le!==void 0&&_.has(Q)?Be(Q):C.protectedKeys[Q]=!0}C.prevProp=P,C.prevResolvedValues=ye,C.isActive&&(S={...S,...ye}),(a||l)&&n.blockInitialAnimation&&(Z=!1);const L=H&&Y;Z&&(!L||se)&&x.push(...me.map(Q=>{const le={type:M};if(typeof Q=="string"&&(a||l)&&!L&&n.manuallyAnimateOnMount&&n.parent){const{parent:ue}=n,A=Hi(ue,Q);if(ue.enteringChildren&&A){const{delayChildren:q}=A.transition||{};le.delay=ox(ue.enteringChildren,n,q)}}return{animation:Q,options:le}}))}if(_.size){const k={};if(typeof y.initial!="boolean"){const M=Hi(n,Array.isArray(y.initial)?y.initial[0]:y.initial);M&&M.transition&&(k.transition=M.transition)}_.forEach(M=>{const C=n.getBaseTarget(M),P=n.getValue(M);P&&(P.liveStyle=!0),k[M]=C??null}),x.push({animation:k})}let j=!!x.length;return a&&(y.initial===!1||y.initial===y.animate)&&!n.manuallyAnimateOnMount&&(j=!1),a=!1,l=!1,j?e(x):Promise.resolve()}function m(p,y){var x;if(i[p].isActive===y)return Promise.resolve();(x=n.variantChildren)==null||x.forEach(_=>{var S;return(S=_.animationState)==null?void 0:S.setActive(p,y)}),i[p].isActive=y;const v=d(p);for(const _ in i)i[_].protectedKeys={};return v}return{animateChanges:d,setActive:m,setAnimateFunction:u,getState:()=>i,reset:()=>{i=D0(),l=!0}}}function nA(n,e){return typeof e=="string"?e!==n:Array.isArray(e)?!zx(e,n):!1}function Ci(n=!1){return{isActive:n,protectedKeys:{},needsAnimating:{},prevResolvedValues:{}}}function D0(){return{animate:Ci(!0),whileInView:Ci(),whileHover:Ci(),whileTap:Ci(),whileDrag:Ci(),whileFocus:Ci(),exit:Ci()}}function af(n,e){n.min=e.min,n.max=e.max}function Mn(n,e){af(n.x,e.x),af(n.y,e.y)}function M0(n,e){n.translate=e.translate,n.scale=e.scale,n.originPoint=e.originPoint,n.origin=e.origin}const Px=1e-4,sA=1-Px,iA=1+Px,Vx=.01,aA=0-Vx,rA=0+Vx;function qt(n){return n.max-n.min}function oA(n,e,i){return Math.abs(n-e)<=i}function B0(n,e,i,a=.5){n.origin=a,n.originPoint=Ye(e.min,e.max,n.origin),n.scale=qt(i)/qt(e),n.translate=Ye(i.min,i.max,n.origin)-n.originPoint,(n.scale>=sA&&n.scale<=iA||isNaN(n.scale))&&(n.scale=1),(n.translate>=aA&&n.translate<=rA||isNaN(n.translate))&&(n.translate=0)}function to(n,e,i,a){B0(n.x,e.x,i.x,a?a.originX:void 0),B0(n.y,e.y,i.y,a?a.originY:void 0)}function U0(n,e,i,a=0){const l=a?Ye(i.min,i.max,a):i.min;n.min=l+e.min,n.max=n.min+qt(e)}function lA(n,e,i,a){U0(n.x,e.x,i.x,a==null?void 0:a.x),U0(n.y,e.y,i.y,a==null?void 0:a.y)}function L0(n,e,i,a=0){const l=a?Ye(i.min,i.max,a):i.min;n.min=e.min-l,n.max=n.min+qt(e)}function Sc(n,e,i,a){L0(n.x,e.x,i.x,a==null?void 0:a.x),L0(n.y,e.y,i.y,a==null?void 0:a.y)}function z0(n,e,i,a,l){return n-=e,n=_c(n,1/i,a),l!==void 0&&(n=_c(n,1/l,a)),n}function cA(n,e=0,i=1,a=.5,l,c=n,u=n){if(ts.test(e)&&(e=parseFloat(e),e=Ye(u.min,u.max,e/100)-u.min),typeof e!="number")return;let d=Ye(c.min,c.max,a);n===c&&(d-=e),n.min=z0(n.min,e,i,d,l),n.max=z0(n.max,e,i,d,l)}function P0(n,e,[i,a,l],c,u){cA(n,e[i],e[a],e[l],e.scale,c,u)}const uA=["x","scaleX","originX"],hA=["y","scaleY","originY"];function V0(n,e,i,a){P0(n.x,e,uA,i?i.x:void 0,a?a.x:void 0),P0(n.y,e,hA,i?i.y:void 0,a?a.y:void 0)}function H0(n){return n.translate===0&&n.scale===1}function Hx(n){return H0(n.x)&&H0(n.y)}function $0(n,e){return n.min===e.min&&n.max===e.max}function dA(n,e){return $0(n.x,e.x)&&$0(n.y,e.y)}function q0(n,e){return Math.round(n.min)===Math.round(e.min)&&Math.round(n.max)===Math.round(e.max)}function $x(n,e){return q0(n.x,e.x)&&q0(n.y,e.y)}function F0(n){return qt(n.x)/qt(n.y)}function I0(n,e){return n.translate===e.translate&&n.scale===e.scale&&n.originPoint===e.originPoint}function Jn(n){return[n("x"),n("y")]}function fA(n,e,i){let a="";const l=n.x.translate/e.x,c=n.y.translate/e.y,u=(i==null?void 0:i.z)||0;if((l||c||u)&&(a=`translate3d(${l}px, ${c}px, ${u}px) `),(e.x!==1||e.y!==1)&&(a+=`scale(${1/e.x}, ${1/e.y}) `),i){const{transformPerspective:p,rotate:y,pathRotation:v,rotateX:x,rotateY:_,skewX:S,skewY:T}=i;p&&(a=`perspective(${p}px) ${a}`),y&&(a+=`rotate(${y}deg) `),v&&(a+=`rotate(${v}deg) `),x&&(a+=`rotateX(${x}deg) `),_&&(a+=`rotateY(${_}deg) `),S&&(a+=`skewX(${S}deg) `),T&&(a+=`skewY(${T}deg) `)}const d=n.x.scale*e.x,m=n.y.scale*e.y;return(d!==1||m!==1)&&(a+=`scale(${d}, ${m})`),a||"none"}const mA=qf.length,G0=n=>typeof n=="string"?parseFloat(n):n,K0=n=>typeof n=="number"||re.test(n);function pA(n,e,i,a,l,c){l?(n.opacity=Ye(0,i.opacity??1,gA(a)),n.opacityExit=Ye(e.opacity??1,0,yA(a))):c&&(n.opacity=Ye(e.opacity??1,i.opacity??1,a));for(let u=0;uae?1:i(ro(n,e,a))}function bA(n,e,i){const a=Lt(n)?n:Ia(n);return a.start(Vf("",a,e,i)),a.animation}function co(n,e,i,a={passive:!0}){return n.addEventListener(e,i,a),()=>n.removeEventListener(e,i,a)}const vA=(n,e)=>n.depth-e.depth;class xA{constructor(){this.children=[],this.isDirty=!1}add(e){jf(this.children,e),this.isDirty=!0}remove(e){pc(this.children,e),this.isDirty=!0}forEach(e){this.isDirty&&this.children.sort(vA),this.isDirty=!1,this.children.forEach(e)}}function wA(n,e){const i=$t.now(),a=({timestamp:l})=>{const c=l-i;c>=e&&(oi(a),n(c-e))};return Xe.setup(a,!0),()=>oi(a)}function dc(n){return Lt(n)?n.get():n}class _A{constructor(){this.members=[]}add(e){jf(this.members,e);for(let i=this.members.length-1;i>=0;i--){const a=this.members[i];if(a===e||a===this.lead||a===this.prevLead)continue;const l=a.instance;(!l||l.isConnected===!1)&&!a.snapshot&&(pc(this.members,a),a.unmount())}e.scheduleRender()}remove(e){if(pc(this.members,e),e===this.prevLead&&(this.prevLead=void 0),e===this.lead){const i=this.members[this.members.length-1];i&&this.promote(i)}}relegate(e){var i;for(let a=this.members.indexOf(e)-1;a>=0;a--){const l=this.members[a];if(l.isPresent!==!1&&((i=l.instance)==null?void 0:i.isConnected)!==!1)return this.promote(l),!0}return!1}promote(e,i){var l;const a=this.lead;if(e!==a&&(this.prevLead=a,this.lead=e,e.show(),a)){a.updateSnapshot(),e.scheduleRender();const{layoutDependency:c}=a.options,{layoutDependency:u}=e.options;(c===void 0||c!==u)&&(e.resumeFrom=a,i&&(a.preserveOpacity=!0),a.snapshot&&(e.snapshot=a.snapshot,e.snapshot.latestValues=a.animationValues||a.latestValues),(l=e.root)!=null&&l.isUpdating&&(e.isLayoutDirty=!0)),e.options.crossfade===!1&&a.hide()}}exitAnimationComplete(){this.members.forEach(e=>{var i,a,l,c,u;(a=(i=e.options).onExitComplete)==null||a.call(i),(u=(l=e.resumingFrom)==null?void 0:(c=l.options).onExitComplete)==null||u.call(c)})}scheduleRender(){this.members.forEach(e=>e.instance&&e.scheduleRender(!1))}removeLeadSnapshot(){var e;(e=this.lead)!=null&&e.snapshot&&(this.lead.snapshot=void 0)}}const fc={hasAnimatedSinceResize:!0,hasEverUpdated:!1},pd=["","X","Y","Z"],SA=1e3;let TA=0;function gd(n,e,i,a){const{latestValues:l}=e;l[n]&&(i[n]=l[n],e.setStaticValue(n,0),a&&(a[n]=0))}function Fx(n){if(n.hasCheckedOptimisedAppear=!0,n.root===n)return;const{visualElement:e}=n.options;if(!e)return;const i=dx(e);if(window.MotionHasOptimisedAnimation(i,"transform")){const{layout:l,layoutId:c}=n.options;window.MotionCancelOptimisedAnimation(i,"transform",Xe,!(l||c))}const{parent:a}=n;a&&!a.hasCheckedOptimisedAppear&&Fx(a)}function Ix({attachResizeListener:n,defaultParent:e,measureScroll:i,checkIsScrollRoot:a,resetTransform:l}){return class{constructor(u={},d=e==null?void 0:e()){this.id=TA++,this.animationId=0,this.animationCommitId=0,this.children=new Set,this.options={},this.isTreeAnimating=!1,this.isAnimationBlocked=!1,this.isLayoutDirty=!1,this.isProjectionDirty=!1,this.isSharedProjectionDirty=!1,this.isTransformDirty=!1,this.updateManuallyBlocked=!1,this.updateBlockedByResize=!1,this.isUpdating=!1,this.isSVG=!1,this.needsReset=!1,this.shouldResetTransform=!1,this.hasCheckedOptimisedAppear=!1,this.treeScale={x:1,y:1},this.eventHandlers=new Map,this.hasTreeAnimated=!1,this.layoutVersion=0,this.updateScheduled=!1,this.scheduleUpdate=()=>this.update(),this.projectionUpdateScheduled=!1,this.checkUpdateFailed=()=>{this.isUpdating&&(this.isUpdating=!1,this.clearAllSnapshots())},this.updateProjection=()=>{this.projectionUpdateScheduled=!1,this.nodes.forEach(jA),this.nodes.forEach(DA),this.nodes.forEach(MA),this.nodes.forEach(NA)},this.resolvedRelativeTargetAt=0,this.linkedParentVersion=0,this.hasProjected=!1,this.isVisible=!0,this.animationProgress=0,this.sharedNodes=new Map,this.latestValues=u,this.root=d?d.root||d:this,this.path=d?[...d.path,d]:[],this.parent=d,this.depth=d?d.depth+1:0;for(let m=0;mthis.root.updateBlockedByResize=!1;Xe.read(()=>{v=window.innerWidth}),n(u,()=>{const _=window.innerWidth;_!==v&&(v=_,this.root.updateBlockedByResize=!0,y&&y(),y=wA(x,250),fc.hasAnimatedSinceResize&&(fc.hasAnimatedSinceResize=!1,this.nodes.forEach(Q0)))})}d&&this.root.registerSharedNode(d,this),this.options.animate!==!1&&p&&(d||m)&&this.addEventListener("didUpdate",({delta:y,hasLayoutChanged:v,hasRelativeLayoutChanged:x,layout:_})=>{if(this.isTreeAnimationBlocked()){this.target=void 0,this.relativeTarget=void 0;return}const S=this.options.transition||p.getDefaultTransition()||PA,{onLayoutAnimationStart:T,onLayoutAnimationComplete:j}=p.getProps(),k=!this.targetLayout||!$x(this.targetLayout,_),M=!v&&x;if(this.options.layoutRoot||this.resumeFrom||M||v&&(k||!this.currentAnimation)){this.resumeFrom&&(this.resumingFrom=this.resumeFrom,this.resumingFrom.resumingFrom=void 0);const C={...Pf(S,"layout"),onPlay:T,onComplete:j};(p.shouldReduceMotion||this.options.layoutRoot)&&(C.delay=0,C.type=!1),this.startAnimation(C),this.setAnimationOrigin(y,M,C.path)}else v||Q0(this),this.isLead()&&this.options.onExitComplete&&this.options.onExitComplete();this.targetLayout=_})}unmount(){this.options.layoutId&&this.willUpdate(),this.root.nodes.remove(this);const u=this.getStack();u&&u.remove(this),this.parent&&this.parent.children.delete(this),this.instance=void 0,this.eventHandlers.clear(),oi(this.updateProjection)}blockUpdate(){this.updateManuallyBlocked=!0}unblockUpdate(){this.updateManuallyBlocked=!1}isUpdateBlocked(){return this.updateManuallyBlocked||this.updateBlockedByResize}isTreeAnimationBlocked(){return this.isAnimationBlocked||this.parent&&this.parent.isTreeAnimationBlocked()||!1}startUpdate(){this.isUpdateBlocked()||(this.isUpdating=!0,this.nodes&&this.nodes.forEach(BA),this.animationId++)}getTransformTemplate(){const{visualElement:u}=this.options;return u&&u.getProps().transformTemplate}willUpdate(u=!0){if(this.root.hasTreeAnimated=!0,this.root.isUpdateBlocked()){this.options.onExitComplete&&this.options.onExitComplete();return}if(window.MotionCancelOptimisedAnimation&&!this.hasCheckedOptimisedAppear&&Fx(this),!this.root.isUpdating&&this.root.startUpdate(),this.isLayoutDirty)return;this.isLayoutDirty=!0;for(let y=0;y{this.isLayoutDirty?this.root.didUpdate():this.root.checkUpdateFailed()})}updateSnapshot(){this.snapshot||!this.instance||(this.snapshot=this.measure(),this.snapshot&&!qt(this.snapshot.measuredBox.x)&&!qt(this.snapshot.measuredBox.y)&&(this.snapshot=void 0))}updateLayout(){if(!this.instance||(this.updateScroll(),!(this.options.alwaysMeasureLayout&&this.isLead())&&!this.isLayoutDirty))return;if(this.resumeFrom&&!this.resumeFrom.instance)for(let m=0;m{const H=G/1e3,Y=K==null?void 0:K(H);Y?(x.x.translate=Y.x,x.x.scale=Ye(u.x.scale,1,H),x.x.origin=u.x.origin,x.x.originPoint=u.x.originPoint,x.y.translate=Y.y,x.y.scale=Ye(u.y.scale,1,H),x.y.origin=u.y.origin,x.y.originPoint=u.y.originPoint):(Z0(x.x,u.x,H),Z0(x.y,u.y,H)),this.setTargetDelta(x),this.relativeTarget&&this.relativeTargetOrigin&&this.layout&&this.relativeParent&&this.relativeParent.layout&&(Sc(_,this.layout.layoutBox,this.relativeParent.layout.layoutBox,this.options.layoutAnchor||void 0),LA(this.relativeTarget,this.relativeTargetOrigin,_,H),P&&dA(this.relativeTarget,P)&&(this.isProjectionDirty=!1),P||(P=Et()),Mn(P,this.relativeTarget)),j&&(this.animationValues=v,pA(v,y,this.latestValues,H,C,M)),Y&&Y.rotate!==void 0&&(this.animationValues||(this.animationValues=v),this.animationValues.pathRotation=Y.rotate),this.root.scheduleUpdateProjection(),this.scheduleRender(),this.animationProgress=H},this.mixTargetDelta(this.options.layoutRoot?1e3:0)}startAnimation(u){var d,m,p;this.notifyListeners("animationStart"),(d=this.currentAnimation)==null||d.stop(),(p=(m=this.resumingFrom)==null?void 0:m.currentAnimation)==null||p.stop(),this.pendingAnimation&&(oi(this.pendingAnimation),this.pendingAnimation=void 0),this.pendingAnimation=Xe.update(()=>{fc.hasAnimatedSinceResize=!0,this.motionValue||(this.motionValue=Ia(0)),this.motionValue.jump(0,!1),this.currentAnimation=bA(this.motionValue,[0,1e3],{...u,velocity:0,isSync:!0,onUpdate:y=>{this.mixTargetDelta(y),u.onUpdate&&u.onUpdate(y)},onComplete:()=>{u.onComplete&&u.onComplete(),this.completeAnimation()}}),this.resumingFrom&&(this.resumingFrom.currentAnimation=this.currentAnimation),this.pendingAnimation=void 0})}completeAnimation(){this.resumingFrom&&(this.resumingFrom.currentAnimation=void 0,this.resumingFrom.preserveOpacity=void 0);const u=this.getStack();u&&u.exitAnimationComplete(),this.resumingFrom=this.currentAnimation=this.animationValues=void 0,this.notifyListeners("animationComplete")}finishAnimation(){this.currentAnimation&&(this.mixTargetDelta&&this.mixTargetDelta(SA),this.currentAnimation.stop()),this.completeAnimation()}applyTransformsToTarget(){const u=this.getLead();let{targetWithTransforms:d,target:m,layout:p,latestValues:y}=u;if(!(!d||!m||!p)){if(this!==u&&this.layout&&p&&Gx(this.options.animationType,this.layout.layoutBox,p.layoutBox)){m=this.target||Et();const v=qt(this.layout.layoutBox.x);m.x.min=u.target.x.min,m.x.max=m.x.min+v;const x=qt(this.layout.layoutBox.y);m.y.min=u.target.y.min,m.y.max=m.y.min+x}Mn(d,m),hc(d,y),to(this.projectionDeltaWithTransform,this.layoutCorrected,d,y)}}registerSharedNode(u,d){this.sharedNodes.has(u)||this.sharedNodes.set(u,new _A),this.sharedNodes.get(u).add(d);const p=d.options.initialPromotionConfig;d.promote({transition:p?p.transition:void 0,preserveFollowOpacity:p&&p.shouldPreserveFollowOpacity?p.shouldPreserveFollowOpacity(d):void 0})}isLead(){const u=this.getStack();return u?u.lead===this:!0}getLead(){var d;const{layoutId:u}=this.options;return u?((d=this.getStack())==null?void 0:d.lead)||this:this}getPrevLead(){var d;const{layoutId:u}=this.options;return u?(d=this.getStack())==null?void 0:d.prevLead:void 0}getStack(){const{layoutId:u}=this.options;if(u)return this.root.sharedNodes.get(u)}promote({needsReset:u,transition:d,preserveFollowOpacity:m}={}){const p=this.getStack();p&&p.promote(this,m),u&&(this.projectionDelta=void 0,this.needsReset=!0),d&&this.setOptions({transition:d})}relegate(){const u=this.getStack();return u?u.relegate(this):!1}resetSkewAndRotation(){const{visualElement:u}=this.options;if(!u)return;let d=!1;const{latestValues:m}=u;if((m.z||m.rotate||m.rotateX||m.rotateY||m.rotateZ||m.skewX||m.skewY)&&(d=!0),!d)return;const p={};m.z&&gd("z",u,p,this.animationValues);for(let y=0;y{var d;return(d=u.currentAnimation)==null?void 0:d.stop()}),this.root.nodes.forEach(X0),this.root.sharedNodes.clear()}}}function EA(n){n.updateLayout()}function AA(n){var i;const e=((i=n.resumeFrom)==null?void 0:i.snapshot)||n.snapshot;if(n.isLead()&&n.layout&&e&&n.hasListeners("didUpdate")){const{layoutBox:a,measuredBox:l}=n.layout,{animationType:c}=n.options,u=e.source!==n.layout.source;if(c==="size")Jn(v=>{const x=u?e.measuredBox[v]:e.layoutBox[v],_=qt(x);x.min=a[v].min,x.max=x.min+_});else if(c==="x"||c==="y"){const v=c==="x"?"y":"x";af(u?e.measuredBox[v]:e.layoutBox[v],a[v])}else Gx(c,e.layoutBox,a)&&Jn(v=>{const x=u?e.measuredBox[v]:e.layoutBox[v],_=qt(a[v]);x.max=x.min+_,n.relativeTarget&&!n.currentAnimation&&(n.isProjectionDirty=!0,n.relativeTarget[v].max=n.relativeTarget[v].min+_)});const d=za();to(d,a,e.layoutBox);const m=za();u?to(m,n.applyTransform(l,!0),e.measuredBox):to(m,a,e.layoutBox);const p=!Hx(d);let y=!1;if(!n.resumeFrom){const v=n.getClosestProjectingParent();if(v&&!v.resumeFrom){const{snapshot:x,layout:_}=v;if(x&&_){const S=n.options.layoutAnchor||void 0,T=Et();Sc(T,e.layoutBox,x.layoutBox,S);const j=Et();Sc(j,a,_.layoutBox,S),$x(T,j)||(y=!0),v.options.layoutRoot&&(n.relativeTarget=j,n.relativeTargetOrigin=T,n.relativeParent=v)}}}n.notifyListeners("didUpdate",{layout:a,snapshot:e,delta:m,layoutDelta:d,hasLayoutChanged:p,hasRelativeLayoutChanged:y})}else if(n.isLead()){const{onExitComplete:a}=n.options;a&&a()}n.options.transition=void 0}function jA(n){n.parent&&(n.isProjecting()||(n.isProjectionDirty=n.parent.isProjectionDirty),n.isSharedProjectionDirty||(n.isSharedProjectionDirty=!!(n.isProjectionDirty||n.parent.isProjectionDirty||n.parent.isSharedProjectionDirty)),n.isTransformDirty||(n.isTransformDirty=n.parent.isTransformDirty))}function NA(n){n.isProjectionDirty=n.isSharedProjectionDirty=n.isTransformDirty=!1}function RA(n){n.clearSnapshot()}function X0(n){n.clearMeasurements()}function kA(n){n.isLayoutDirty=!0,n.updateLayout()}function J0(n){n.isLayoutDirty=!1}function CA(n){n.isAnimationBlocked&&n.layout&&!n.isLayoutDirty&&(n.snapshot=n.layout,n.isLayoutDirty=!0)}function OA(n){const{visualElement:e}=n.options;e&&e.getProps().onBeforeLayoutMeasure&&e.notify("BeforeLayoutMeasure"),n.resetTransform()}function Q0(n){n.finishAnimation(),n.targetDelta=n.relativeTarget=n.target=void 0,n.isProjectionDirty=!0}function DA(n){n.resolveTargetDelta()}function MA(n){n.calcProjection()}function BA(n){n.resetSkewAndRotation()}function UA(n){n.removeLeadSnapshot()}function Z0(n,e,i){n.translate=Ye(e.translate,0,i),n.scale=Ye(e.scale,1,i),n.origin=e.origin,n.originPoint=e.originPoint}function W0(n,e,i,a){n.min=Ye(e.min,i.min,a),n.max=Ye(e.max,i.max,a)}function LA(n,e,i,a){W0(n.x,e.x,i.x,a),W0(n.y,e.y,i.y,a)}function zA(n){return n.animationValues&&n.animationValues.opacityExit!==void 0}const PA={duration:.45,ease:[.4,0,.1,1]},eb=n=>typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().includes(n),tb=eb("applewebkit/")&&!eb("chrome/")?Math.round:An;function nb(n){n.min=tb(n.min),n.max=tb(n.max)}function VA(n){nb(n.x),nb(n.y)}function Gx(n,e,i){return n==="position"||n==="preserve-aspect"&&!oA(F0(e),F0(i),.2)}function HA(n){var e;return n!==n.root&&((e=n.scroll)==null?void 0:e.wasRoot)}const $A=Ix({attachResizeListener:(n,e)=>co(n,"resize",e),measureScroll:()=>{var n,e;return{x:document.documentElement.scrollLeft||((n=document.body)==null?void 0:n.scrollLeft)||0,y:document.documentElement.scrollTop||((e=document.body)==null?void 0:e.scrollTop)||0}},checkIsScrollRoot:()=>!0}),yd={current:void 0},Kx=Ix({measureScroll:n=>({x:n.scrollLeft,y:n.scrollTop}),defaultParent:()=>{if(!yd.current){const n=new $A({});n.mount(window),n.setOptions({layoutScroll:!0}),yd.current=n}return yd.current},resetTransform:(n,e)=>{n.style.transform=e!==void 0?e:"none"},checkIsScrollRoot:n=>window.getComputedStyle(n).position==="fixed"}),Qf=D.createContext({transformPagePoint:n=>n,isStatic:!1,reducedMotion:"never"});function sb(n,e){if(typeof n=="function")return n(e);n!=null&&(n.current=e)}function qA(...n){return e=>{let i=!1;const a=n.map(l=>{const c=sb(l,e);return!i&&typeof c=="function"&&(i=!0),c});if(i)return()=>{for(let l=0;l{const{width:_,height:S,top:T,left:j,right:k,bottom:M,direction:C}=m.current;if(e||c===!1||!d.current||!_||!S)return;const P=C==="rtl",K=i==="left"?P?`right: ${k}`:`left: ${j}`:P?`left: ${j}`:`right: ${k}`,G=a==="bottom"?`bottom: ${M}`:`top: ${T}`;d.current.dataset.motionPopId=u;const H=document.createElement("style");p&&(H.nonce=p);const Y=l??document.head;return Y.appendChild(H),H.sheet&&H.sheet.insertRule(` + [data-motion-pop-id="${u}"] { + position: absolute !important; + width: ${_}px !important; + height: ${S}px !important; + ${K}px !important; + ${G}px !important; + } + `),()=>{var Z;(Z=d.current)==null||Z.removeAttribute("data-motion-pop-id"),Y.contains(H)&&Y.removeChild(H)}},[e]),g.jsx(IA,{isPresent:e,childRef:d,sizeRef:m,pop:c,children:c===!1?n:D.cloneElement(n,{ref:v})})}const KA=({children:n,initial:e,isPresent:i,onExitComplete:a,custom:l,presenceAffectsLayout:c,mode:u,anchorX:d,anchorY:m,root:p})=>{const y=Ef(YA),v=D.useId(),x=D.useRef(i),_=D.useRef(a);Af(()=>{x.current=i,_.current=a});let S=!0,T=D.useMemo(()=>(S=!1,{id:v,initial:e,isPresent:i,custom:l,onExitComplete:j=>{y.set(j,!0);for(const k of y.values())if(!k)return;a&&a()},register:j=>(y.set(j,!1),()=>{var k;y.delete(j),!x.current&&!y.size&&((k=_.current)==null||k.call(_))})}),[i,y,a]);return c&&S&&(T={...T}),D.useMemo(()=>{y.forEach((j,k)=>y.set(k,!1))},[i]),D.useEffect(()=>{!i&&!y.size&&a&&a()},[i]),n=g.jsx(GA,{pop:u==="popLayout",isPresent:i,anchorX:d,anchorY:m,root:p,children:n}),g.jsx(Uc.Provider,{value:T,children:n})};function YA(){return new Map}function Yx(n=!0){const e=D.useContext(Uc);if(e===null)return[!0,null];const{isPresent:i,onExitComplete:a,register:l}=e,c=D.useId();D.useEffect(()=>{if(n)return l(c)},[n]);const u=D.useCallback(()=>n&&a&&a(c),[c,a,n]);return!i&&a?[!1,u]:[!0]}const Gl=n=>n.key||"";function ib(n){const e=[];return D.Children.forEach(n,i=>{D.isValidElement(i)&&e.push(i)}),e}const zi=({children:n,custom:e,initial:i=!0,onExitComplete:a,presenceAffectsLayout:l=!0,mode:c="sync",propagate:u=!1,anchorX:d="left",anchorY:m="top",root:p})=>{const[y,v]=Yx(u),x=D.useMemo(()=>ib(n),[n]),_=u&&!y?[]:x.map(Gl),S=D.useRef(!0),T=D.useRef(x),j=Ef(()=>new Map),k=D.useRef(new Set),[M,C]=D.useState(x),[P,K]=D.useState(x);Af(()=>{S.current=!1,T.current=x;for(let Y=0;Y{const Z=Gl(Y),se=u&&!y?!1:x===P||_.includes(Z),me=()=>{if(k.current.has(Z))return;if(j.has(Z))k.current.add(Z),j.set(Z,!0);else return;let ye=!0;j.forEach(Ae=>{Ae||(ye=!1)}),ye&&(H==null||H(),K(T.current),u&&(v==null||v()),a&&a())};return g.jsx(KA,{isPresent:se,initial:!S.current||i?void 0:!1,custom:e,presenceAffectsLayout:l,mode:c,root:p,onExitComplete:se?void 0:me,anchorX:d,anchorY:m,children:Y},Z)})})},Xx=D.createContext({strict:!1}),ab={animation:["animate","variants","whileHover","whileTap","exit","whileInView","whileFocus","whileDrag"],exit:["exit"],drag:["drag","dragControls"],focus:["whileFocus"],hover:["whileHover","onHoverStart","onHoverEnd"],tap:["whileTap","onTap","onTapStart","onTapCancel"],pan:["onPan","onPanStart","onPanSessionStart","onPanEnd"],inView:["whileInView","onViewportEnter","onViewportLeave"],layout:["layout","layoutId"]};let rb=!1;function XA(){if(rb)return;const n={};for(const e in ab)n[e]={isEnabled:i=>ab[e].some(a=>!!i[a])};Ex(n),rb=!0}function Jx(){return XA(),DE()}function JA(n){const e=Jx();for(const i in n)e[i]={...e[i],...n[i]};Ex(e)}const QA=new Set(["animate","exit","variants","initial","style","values","variants","transition","transformTemplate","custom","inherit","onBeforeLayoutMeasure","onAnimationStart","onAnimationComplete","onUpdate","onDragStart","onDrag","onDragEnd","onMeasureDragConstraints","onDirectionLock","onDragTransitionEnd","_dragX","_dragY","onHoverStart","onHoverEnd","onViewportEnter","onViewportLeave","globalTapTarget","propagate","ignoreStrict","viewport"]);function Tc(n){return n.startsWith("while")||n.startsWith("drag")&&n!=="draggable"||n.startsWith("layout")||n.startsWith("onTap")||n.startsWith("onPan")||n.startsWith("onLayout")||QA.has(n)}let Qx=n=>!Tc(n);function ZA(n){typeof n=="function"&&(Qx=e=>e.startsWith("on")?!Tc(e):n(e))}try{ZA(require("@emotion/is-prop-valid").default)}catch{}function WA(n,e,i){const a={};for(const l in n)l==="values"&&typeof n.values=="object"||Lt(n[l])||(Qx(l)||i===!0&&Tc(l)||!e&&!Tc(l)||n.draggable&&l.startsWith("onDrag"))&&(a[l]=n[l]);return a}const Vc=D.createContext({});function ej(n,e){if(Pc(n)){const{initial:i,animate:a}=n;return{initial:i===!1||lo(i)?i:void 0,animate:lo(a)?a:void 0}}return n.inherit!==!1?e:{}}function tj(n){const{initial:e,animate:i}=ej(n,D.useContext(Vc));return D.useMemo(()=>({initial:e,animate:i}),[ob(e),ob(i)])}function ob(n){return Array.isArray(n)?n.join(" "):n}const Zf=()=>({style:{},transform:{},transformOrigin:{},vars:{}});function Zx(n,e,i){for(const a in e)!Lt(e[a])&&!Ox(a,i)&&(n[a]=e[a])}function nj({transformTemplate:n},e){return D.useMemo(()=>{const i=Zf();return Xf(i,e,n),Object.assign({},i.vars,i.style)},[e])}function sj(n,e){const i=n.style||{},a={};return Zx(a,i,n),Object.assign(a,nj(n,e)),a}function ij(n,e){const i={},a=sj(n,e);return n.drag&&n.dragListener!==!1&&(i.draggable=!1,a.userSelect=a.WebkitUserSelect=a.WebkitTouchCallout="none",a.touchAction=n.drag===!0?"none":`pan-${n.drag==="x"?"y":"x"}`),n.tabIndex===void 0&&(n.onTap||n.onTapStart||n.whileTap)&&(i.tabIndex=0),i.style=a,i}const Wx=()=>({...Zf(),attrs:{}});function aj(n,e,i,a){const l=D.useMemo(()=>{const c=Wx();return Dx(c,e,Bx(a),n.transformTemplate,n.style),{...c.attrs,style:{...c.style}}},[e]);if(n.style){const c={};Zx(c,n.style,n),l.style={...c,...l.style}}return l}const rj=["animate","circle","defs","desc","ellipse","g","image","line","filter","marker","mask","metadata","path","pattern","polygon","polyline","rect","stop","switch","symbol","svg","text","tspan","use","view"];function Wf(n){return typeof n!="string"||n.includes("-")?!1:!!(rj.indexOf(n)>-1||/[A-Z]/u.test(n))}function oj(n,e,i,{latestValues:a},l,c=!1,u){const m=(u??Wf(n)?aj:ij)(e,a,l,n),p=WA(e,typeof n=="string",c),y=n!==D.Fragment?{...p,...m,ref:i}:{},{children:v}=e,x=D.useMemo(()=>Lt(v)?v.get():v,[v]);return D.createElement(n,{...y,children:x})}function lj({scrapeMotionValuesFromProps:n,createRenderState:e},i,a,l){return{latestValues:cj(i,a,l,n),renderState:e()}}function cj(n,e,i,a){const l={},c=a(n,{});for(const x in c)l[x]=dc(c[x]);let{initial:u,animate:d}=n;const m=Pc(n),p=Sx(n);e&&p&&!m&&n.inherit!==!1&&(u===void 0&&(u=e.initial),d===void 0&&(d=e.animate));let y=i?i.initial===!1:!1;y=y||u===!1;const v=y?d:u;if(v&&typeof v!="boolean"&&!zc(v)){const x=Array.isArray(v)?v:[v];for(let _=0;_(e,i)=>{const a=D.useContext(Vc),l=D.useContext(Uc),c=()=>lj(n,e,a,l);return i?c():Ef(c)},uj=ew({scrapeMotionValuesFromProps:Jf,createRenderState:Zf}),hj=ew({scrapeMotionValuesFromProps:Ux,createRenderState:Wx}),dj=Symbol.for("motionComponentSymbol");function fj(n,e,i){const a=D.useRef(i);D.useInsertionEffect(()=>{a.current=i});const l=D.useRef(null);return D.useCallback(c=>{var d;c&&((d=n.onMount)==null||d.call(n,c)),e&&(c?e.mount(c):e.unmount());const u=a.current;if(typeof u=="function")if(c){const m=u(c);typeof m=="function"&&(l.current=m)}else l.current?(l.current(),l.current=null):u(c);else u&&(u.current=c)},[e])}const tw=D.createContext({});function ka(n){return n&&typeof n=="object"&&Object.prototype.hasOwnProperty.call(n,"current")}function mj(n,e,i,a,l,c){var C,P;const{visualElement:u}=D.useContext(Vc),d=D.useContext(Xx),m=D.useContext(Uc),p=D.useContext(Qf),y=p.reducedMotion,v=p.skipAnimations,x=D.useRef(null),_=D.useRef(!1);a=a||d.renderer,!x.current&&a&&(x.current=a(n,{visualState:e,parent:u,props:i,presenceContext:m,blockInitialAnimation:m?m.initial===!1:!1,reducedMotionConfig:y,skipAnimations:v,isSVG:c}),_.current&&x.current&&(x.current.manuallyAnimateOnMount=!0));const S=x.current,T=D.useContext(tw);S&&!S.projection&&l&&(S.type==="html"||S.type==="svg")&&pj(x.current,i,l,T);const j=D.useRef(!1);D.useInsertionEffect(()=>{S&&j.current&&S.update(i,m)});const k=i[hx],M=D.useRef(!!k&&typeof window<"u"&&!((C=window.MotionHandoffIsComplete)!=null&&C.call(window,k))&&((P=window.MotionHasOptimisedAnimation)==null?void 0:P.call(window,k)));return Af(()=>{_.current=!0,S&&(j.current=!0,window.MotionIsMounted=!0,S.updateFeatures(),S.scheduleRenderMicrotask(),M.current&&S.animationState&&S.animationState.animateChanges())}),D.useEffect(()=>{S&&(!M.current&&S.animationState&&S.animationState.animateChanges(),M.current&&(queueMicrotask(()=>{var K;(K=window.MotionHandoffMarkAsComplete)==null||K.call(window,k)}),M.current=!1),S.enteringChildren=void 0)}),S}function pj(n,e,i,a){const{layoutId:l,layout:c,drag:u,dragConstraints:d,layoutScroll:m,layoutRoot:p,layoutAnchor:y,layoutCrossfade:v}=e;n.projection=new i(n.latestValues,e["data-framer-portal-id"]?void 0:nw(n.parent)),n.projection.setOptions({layoutId:l,layout:c,alwaysMeasureLayout:!!u||d&&ka(d),visualElement:n,animationType:typeof c=="string"?c:"both",initialPromotionConfig:a,crossfade:v,layoutScroll:m,layoutRoot:p,layoutAnchor:y})}function nw(n){if(n)return n.options.allowProjection!==!1?n.projection:nw(n.parent)}function bd(n,{forwardMotionProps:e=!1,type:i}={},a,l){a&&JA(a);const c=i?i==="svg":Wf(n),u=c?hj:uj;function d(p,y){let v;const x={...D.useContext(Qf),...p,layoutId:gj(p)},{isStatic:_}=x,S=tj(p),T=u(p,_);if(!_&&typeof window<"u"){yj();const j=bj(x);v=j.MeasureLayout,S.visualElement=mj(n,T,x,l,j.ProjectionNode,c)}return g.jsxs(Vc.Provider,{value:S,children:[v&&S.visualElement?g.jsx(v,{visualElement:S.visualElement,...x}):null,oj(n,p,fj(T,S.visualElement,y),T,_,e,c)]})}d.displayName=`motion.${typeof n=="string"?n:`create(${n.displayName??n.name??""})`}`;const m=D.forwardRef(d);return m[dj]=n,m}function gj({layoutId:n}){const e=D.useContext(Tf).id;return e&&n!==void 0?e+"-"+n:n}function yj(n,e){D.useContext(Xx).strict}function bj(n){const e=Jx(),{drag:i,layout:a}=e;if(!i&&!a)return{};const l={...i,...a};return{MeasureLayout:i!=null&&i.isEnabled(n)||a!=null&&a.isEnabled(n)?l.MeasureLayout:void 0,ProjectionNode:l.ProjectionNode}}function vj(n,e){if(typeof Proxy>"u")return bd;const i=new Map,a=(c,u)=>bd(c,u,n,e),l=(c,u)=>a(c,u);return new Proxy(l,{get:(c,u)=>u==="create"?a:(i.has(u)||i.set(u,bd(u,void 0,n,e)),i.get(u))})}const xj=(n,e)=>e.isSVG??Wf(n)?new JE(e):new FE(e,{allowProjection:n!==D.Fragment});class wj extends li{constructor(e){super(e),e.animationState||(e.animationState=tA(e))}updateAnimationControlsSubscription(){const{animate:e}=this.node.getProps();zc(e)&&(this.unmountControls=e.subscribe(this.node))}mount(){this.updateAnimationControlsSubscription()}update(){const{animate:e}=this.node.getProps(),{animate:i}=this.node.prevProps||{};e!==i&&this.updateAnimationControlsSubscription()}unmount(){var e;this.node.animationState.reset(),(e=this.unmountControls)==null||e.call(this)}}let _j=0;class Sj extends li{constructor(){super(...arguments),this.id=_j++,this.isExitComplete=!1}update(){var c;if(!this.node.presenceContext)return;const{isPresent:e,onExitComplete:i}=this.node.presenceContext,{isPresent:a}=this.node.prevPresenceContext||{};if(!this.node.animationState||e===a)return;if(e&&a===!1){if(this.isExitComplete){const{initial:u,custom:d}=this.node.getProps();if(typeof u=="string"||typeof u=="object"&&u!==null&&!Array.isArray(u)){const m=Hi(this.node,u,d);if(m){const{transition:p,transitionEnd:y,...v}=m;for(const x in v)(c=this.node.getValue(x))==null||c.jump(v[x])}}this.node.animationState.reset(),this.node.animationState.animateChanges()}else this.node.animationState.setActive("exit",!1);this.isExitComplete=!1;return}const l=this.node.animationState.setActive("exit",!e);i&&!e&&l.then(()=>{this.isExitComplete=!0,i(this.id)})}mount(){const{register:e,onExitComplete:i}=this.node.presenceContext||{};i&&i(this.id),e&&(this.unmount=e(this.id))}unmount(){}}const Tj={animation:{Feature:wj},exit:{Feature:Sj}};function So(n){return{point:{x:n.pageX,y:n.pageY}}}const Ej=n=>e=>If(e)&&n(e,So(e));function no(n,e,i,a){return co(n,e,Ej(i),a)}const sw=({current:n})=>n?n.ownerDocument.defaultView:null,lb=(n,e)=>Math.abs(n-e);function Aj(n,e){const i=lb(n.x,e.x),a=lb(n.y,e.y);return Math.sqrt(i**2+a**2)}const cb=new Set(["auto","scroll"]);class iw{constructor(e,i,{transformPagePoint:a,contextWindow:l=window,dragSnapToOrigin:c=!1,distanceThreshold:u=3,element:d}={}){if(this.startEvent=null,this.lastMoveEvent=null,this.lastMoveEventInfo=null,this.lastRawMoveEventInfo=null,this.handlers={},this.contextWindow=window,this.scrollPositions=new Map,this.removeScrollListeners=null,this.onElementScroll=S=>{this.handleScroll(S.target)},this.onWindowScroll=()=>{this.handleScroll(window)},this.updatePoint=()=>{if(!(this.lastMoveEvent&&this.lastMoveEventInfo))return;this.lastRawMoveEventInfo&&(this.lastMoveEventInfo=Kl(this.lastRawMoveEventInfo,this.transformPagePoint));const S=vd(this.lastMoveEventInfo,this.history),T=this.startEvent!==null,j=Aj(S.offset,{x:0,y:0})>=this.distanceThreshold;if(!T&&!j)return;const{point:k}=S,{timestamp:M}=Ut;this.history.push({...k,timestamp:M});const{onStart:C,onMove:P}=this.handlers;T||(C&&C(this.lastMoveEvent,S),this.startEvent=this.lastMoveEvent),P&&P(this.lastMoveEvent,S)},this.handlePointerMove=(S,T)=>{this.lastMoveEvent=S,this.lastRawMoveEventInfo=T,this.lastMoveEventInfo=Kl(T,this.transformPagePoint),Xe.update(this.updatePoint,!0)},this.handlePointerUp=(S,T)=>{this.end();const{onEnd:j,onSessionEnd:k,resumeAnimation:M}=this.handlers;if((this.dragSnapToOrigin||!this.startEvent)&&M&&M(),!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const C=vd(S.type==="pointercancel"?this.lastMoveEventInfo:Kl(T,this.transformPagePoint),this.history);this.startEvent&&j&&j(S,C),k&&k(S,C)},!If(e))return;this.dragSnapToOrigin=c,this.handlers=i,this.transformPagePoint=a,this.distanceThreshold=u,this.contextWindow=l||window;const m=So(e),p=Kl(m,this.transformPagePoint),{point:y}=p,{timestamp:v}=Ut;this.history=[{...y,timestamp:v}];const{onSessionStart:x}=i;x&&x(e,vd(p,this.history));const _={passive:!0,capture:!0};this.removeListeners=xo(no(this.contextWindow,"pointermove",this.handlePointerMove,_),no(this.contextWindow,"pointerup",this.handlePointerUp,_),no(this.contextWindow,"pointercancel",this.handlePointerUp,_)),d&&this.startScrollTracking(d)}startScrollTracking(e){let i=e.parentElement;for(;i;){const a=getComputedStyle(i);(cb.has(a.overflowX)||cb.has(a.overflowY))&&this.scrollPositions.set(i,{x:i.scrollLeft,y:i.scrollTop}),i=i.parentElement}this.scrollPositions.set(window,{x:window.scrollX,y:window.scrollY}),window.addEventListener("scroll",this.onElementScroll,{capture:!0}),window.addEventListener("scroll",this.onWindowScroll),this.removeScrollListeners=()=>{window.removeEventListener("scroll",this.onElementScroll,{capture:!0}),window.removeEventListener("scroll",this.onWindowScroll)}}handleScroll(e){const i=this.scrollPositions.get(e);if(!i)return;const a=e===window,l=a?{x:window.scrollX,y:window.scrollY}:{x:e.scrollLeft,y:e.scrollTop},c={x:l.x-i.x,y:l.y-i.y};c.x===0&&c.y===0||(a?this.lastMoveEventInfo&&(this.lastMoveEventInfo.point.x+=c.x,this.lastMoveEventInfo.point.y+=c.y):this.history.length>0&&(this.history[0].x-=c.x,this.history[0].y-=c.y),this.scrollPositions.set(e,l),Xe.update(this.updatePoint,!0))}updateHandlers(e){this.handlers=e}end(){this.removeListeners&&this.removeListeners(),this.removeScrollListeners&&this.removeScrollListeners(),this.scrollPositions.clear(),oi(this.updatePoint)}}function Kl(n,e){return e?{point:e(n.point)}:n}function ub(n,e){return{x:n.x-e.x,y:n.y-e.y}}function vd({point:n},e){return{point:n,delta:ub(n,aw(e)),offset:ub(n,jj(e)),velocity:Nj(e,.1)}}function jj(n){return n[0]}function aw(n){return n[n.length-1]}function Nj(n,e){if(n.length<2)return{x:0,y:0};let i=n.length-1,a=null;const l=aw(n);for(;i>=0&&(a=n[i],!(l.timestamp-a.timestamp>ln(e)));)i--;if(!a)return{x:0,y:0};a===n[0]&&n.length>2&&l.timestamp-a.timestamp>ln(e)*2&&(a=n[1]);const c=En(l.timestamp-a.timestamp);if(c===0)return{x:0,y:0};const u={x:(l.x-a.x)/c,y:(l.y-a.y)/c};return u.x===1/0&&(u.x=0),u.y===1/0&&(u.y=0),u}function Rj(n,{min:e,max:i},a){return e!==void 0&&ni&&(n=a?Ye(i,n,a.max):Math.min(n,i)),n}function hb(n,e,i){return{min:e!==void 0?n.min+e:void 0,max:i!==void 0?n.max+i-(n.max-n.min):void 0}}function kj(n,{top:e,left:i,bottom:a,right:l}){return{x:hb(n.x,i,l),y:hb(n.y,e,a)}}function db(n,e){let i=e.min-n.min,a=e.max-n.max;return e.max-e.mina?i=ro(e.min,e.max-a,n.min):a>l&&(i=ro(n.min,n.max-l,e.min)),ns(0,1,i)}function Dj(n,e){const i={};return e.min!==void 0&&(i.min=e.min-n.min),e.max!==void 0&&(i.max=e.max-n.min),i}const rf=.35;function Mj(n=rf){return n===!1?n=0:n===!0&&(n=rf),{x:fb(n,"left","right"),y:fb(n,"top","bottom")}}function fb(n,e,i){return{min:mb(n,e),max:mb(n,i)}}function mb(n,e){return typeof n=="number"?n:n[e]||0}const Bj=new WeakMap;class Uj{constructor(e){this.openDragLock=null,this.isDragging=!1,this.currentDirection=null,this.originPoint={x:0,y:0},this.constraints=!1,this.hasMutatedConstraints=!1,this.elastic=Et(),this.latestPointerEvent=null,this.latestPanInfo=null,this.visualElement=e}start(e,{snapToCursor:i=!1,distanceThreshold:a}={}){const{presenceContext:l}=this.visualElement;if(l&&l.isPresent===!1)return;const c=v=>{i&&this.snapToCursor(So(v).point),this.stopAnimation()},u=(v,x)=>{const{drag:_,dragPropagation:S,onDragStart:T}=this.getProps();if(_&&!S&&(this.openDragLock&&this.openDragLock(),this.openDragLock=cE(_),!this.openDragLock))return;this.latestPointerEvent=v,this.latestPanInfo=x,this.isDragging=!0,this.currentDirection=null,this.resolveConstraints(),this.visualElement.projection&&(this.visualElement.projection.isAnimationBlocked=!0,this.visualElement.projection.target=void 0),Jn(k=>{let M=this.getAxisMotionValue(k).get()||0;if(ts.test(M)){const{projection:C}=this.visualElement;if(C&&C.layout){const P=C.layout.layoutBox[k];P&&(M=qt(P)*(parseFloat(M)/100))}}this.originPoint[k]=M}),T&&Xe.update(()=>T(v,x),!1,!0),Xd(this.visualElement,"transform");const{animationState:j}=this.visualElement;j&&j.setActive("whileDrag",!0)},d=(v,x)=>{this.latestPointerEvent=v,this.latestPanInfo=x;const{dragPropagation:_,dragDirectionLock:S,onDirectionLock:T,onDrag:j}=this.getProps();if(!_&&!this.openDragLock)return;const{offset:k}=x;if(S&&this.currentDirection===null){this.currentDirection=zj(k),this.currentDirection!==null&&T&&T(this.currentDirection);return}this.updateAxis("x",x.point,k),this.updateAxis("y",x.point,k),this.visualElement.render(),j&&Xe.update(()=>j(v,x),!1,!0)},m=(v,x)=>{this.latestPointerEvent=v,this.latestPanInfo=x,this.stop(v,x),this.latestPointerEvent=null,this.latestPanInfo=null},p=()=>{const{dragSnapToOrigin:v}=this.getProps();(v||this.constraints)&&this.startAnimation({x:0,y:0})},{dragSnapToOrigin:y}=this.getProps();this.panSession=new iw(e,{onSessionStart:c,onStart:u,onMove:d,onSessionEnd:m,resumeAnimation:p},{transformPagePoint:this.visualElement.getTransformPagePoint(),dragSnapToOrigin:y,distanceThreshold:a,contextWindow:sw(this.visualElement),element:this.visualElement.current})}stop(e,i){const a=e||this.latestPointerEvent,l=i||this.latestPanInfo,c=this.isDragging;if(this.cancel(),!c||!l||!a)return;const{velocity:u}=l;this.startAnimation(u);const{onDragEnd:d}=this.getProps();d&&Xe.postRender(()=>d(a,l))}cancel(){this.isDragging=!1;const{projection:e,animationState:i}=this.visualElement;e&&(e.isAnimationBlocked=!1),this.endPanSession();const{dragPropagation:a}=this.getProps();!a&&this.openDragLock&&(this.openDragLock(),this.openDragLock=null),i&&i.setActive("whileDrag",!1)}endPanSession(){this.panSession&&this.panSession.end(),this.panSession=void 0}updateAxis(e,i,a){const{drag:l}=this.getProps();if(!a||!Yl(e,l,this.currentDirection))return;const c=this.getAxisMotionValue(e);let u=this.originPoint[e]+a[e];this.constraints&&this.constraints[e]&&(u=Rj(u,this.constraints[e],this.elastic[e])),c.set(u)}resolveConstraints(){var c;const{dragConstraints:e,dragElastic:i}=this.getProps(),a=this.visualElement.projection&&!this.visualElement.projection.layout?this.visualElement.projection.measure(!1):(c=this.visualElement.projection)==null?void 0:c.layout,l=this.constraints;e&&ka(e)?this.constraints||(this.constraints=this.resolveRefConstraints()):e&&a?this.constraints=kj(a.layoutBox,e):this.constraints=!1,this.elastic=Mj(i),l!==this.constraints&&!ka(e)&&a&&this.constraints&&!this.hasMutatedConstraints&&Jn(u=>{this.constraints!==!1&&this.getAxisMotionValue(u)&&(this.constraints[u]=Dj(a.layoutBox[u],this.constraints[u]))})}resolveRefConstraints(){const{dragConstraints:e,onMeasureDragConstraints:i}=this.getProps();if(!e||!ka(e))return!1;const a=e.current,{projection:l}=this.visualElement;if(!l||!l.layout)return!1;l.root&&(l.root.scroll=void 0,l.root.updateScroll());const c=zE(a,l.root,this.visualElement.getTransformPagePoint());let u=Cj(l.layout.layoutBox,c);if(i){const d=i(BE(u));this.hasMutatedConstraints=!!d,d&&(u=jx(d))}return u}startAnimation(e){const{drag:i,dragMomentum:a,dragElastic:l,dragTransition:c,dragSnapToOrigin:u,onDragTransitionEnd:d}=this.getProps(),m=this.constraints||{},p=Jn(y=>{if(!Yl(y,i,this.currentDirection))return;let v=m&&m[y]||{};(u===!0||u===y)&&(v={min:0,max:0});const x=l?200:1e6,_=l?40:1e7,S={type:"inertia",velocity:a?e[y]:0,bounceStiffness:x,bounceDamping:_,timeConstant:750,restDelta:1,restSpeed:10,...c,...v};return this.startAxisValueAnimation(y,S)});return Promise.all(p).then(d)}startAxisValueAnimation(e,i){const a=this.getAxisMotionValue(e);return Xd(this.visualElement,e),a.start(Vf(e,a,0,i,this.visualElement,!1))}stopAnimation(){Jn(e=>this.getAxisMotionValue(e).stop())}getAxisMotionValue(e){const i=`_drag${e.toUpperCase()}`,l=this.visualElement.getProps()[i];return l||this.visualElement.getValue(e,this.visualElement.latestValues[e]??0)}snapToCursor(e){Jn(i=>{const{drag:a}=this.getProps();if(!Yl(i,a,this.currentDirection))return;const{projection:l}=this.visualElement,c=this.getAxisMotionValue(i);if(l&&l.layout){const{min:u,max:d}=l.layout.layoutBox[i],m=c.get()||0;c.set(e[i]-Ye(u,d,.5)+m)}})}scalePositionWithinConstraints(){if(!this.visualElement.current)return;const{drag:e,dragConstraints:i}=this.getProps(),{projection:a}=this.visualElement;if(!ka(i)||!a||!this.constraints)return;this.stopAnimation();const l={x:0,y:0};Jn(u=>{const d=this.getAxisMotionValue(u);if(d&&this.constraints!==!1){const m=d.get();l[u]=Oj({min:m,max:m},this.constraints[u])}});const{transformTemplate:c}=this.visualElement.getProps();this.visualElement.current.style.transform=c?c({},""):"none",a.root&&a.root.updateScroll(),a.updateLayout(),this.constraints=!1,this.resolveConstraints(),Jn(u=>{if(!Yl(u,e,null))return;const d=this.getAxisMotionValue(u),{min:m,max:p}=this.constraints[u];d.set(Ye(m,p,l[u]))}),this.visualElement.render()}addListeners(){if(!this.visualElement.current)return;Bj.set(this.visualElement,this);const e=this.visualElement.current,i=no(e,"pointerdown",p=>{const{drag:y,dragListener:v=!0}=this.getProps(),x=p.target,_=x!==e&&pE(x);y&&v&&!_&&this.start(p)});let a;const l=()=>{const{dragConstraints:p}=this.getProps();ka(p)&&p.current&&(this.constraints=this.resolveRefConstraints(),a||(a=Lj(e,p.current,()=>this.scalePositionWithinConstraints())))},{projection:c}=this.visualElement,u=c.addEventListener("measure",l);c&&!c.layout&&(c.root&&c.root.updateScroll(),c.updateLayout()),Xe.read(l);const d=co(window,"resize",()=>this.scalePositionWithinConstraints()),m=c.addEventListener("didUpdate",(({delta:p,hasLayoutChanged:y})=>{this.isDragging&&y&&(Jn(v=>{const x=this.getAxisMotionValue(v);x&&(this.originPoint[v]+=p[v].translate,x.set(x.get()+p[v].translate))}),this.visualElement.render())}));return()=>{d(),i(),u(),m&&m(),a&&a()}}getProps(){const e=this.visualElement.getProps(),{drag:i=!1,dragDirectionLock:a=!1,dragPropagation:l=!1,dragConstraints:c=!1,dragElastic:u=rf,dragMomentum:d=!0}=e;return{...e,drag:i,dragDirectionLock:a,dragPropagation:l,dragConstraints:c,dragElastic:u,dragMomentum:d}}}function pb(n){let e=!0;return()=>{if(e){e=!1;return}n()}}function Lj(n,e,i){const a=_0(n,pb(i)),l=_0(e,pb(i));return()=>{a(),l()}}function Yl(n,e,i){return(e===!0||e===n)&&(i===null||i===n)}function zj(n,e=10){let i=null;return Math.abs(n.y)>e?i="y":Math.abs(n.x)>e&&(i="x"),i}class Pj extends li{constructor(e){super(e),this.removeGroupControls=An,this.removeListeners=An,this.controls=new Uj(e)}mount(){const{dragControls:e}=this.node.getProps();e&&(this.removeGroupControls=e.subscribe(this.controls)),this.removeListeners=this.controls.addListeners()||An}update(){const{dragControls:e}=this.node.getProps(),{dragControls:i}=this.node.prevProps||{};e!==i&&(this.removeGroupControls(),e&&(this.removeGroupControls=e.subscribe(this.controls)))}unmount(){this.removeGroupControls(),this.removeListeners(),this.controls.isDragging||this.controls.endPanSession()}}const xd=n=>(e,i)=>{n&&Xe.update(()=>n(e,i),!1,!0)};class Vj extends li{constructor(){super(...arguments),this.removePointerDownListener=An}onPointerDown(e){this.session=new iw(e,this.createPanHandlers(),{transformPagePoint:this.node.getTransformPagePoint(),contextWindow:sw(this.node)})}createPanHandlers(){const{onPanSessionStart:e,onPanStart:i,onPan:a,onPanEnd:l}=this.node.getProps();return{onSessionStart:xd(e),onStart:xd(i),onMove:xd(a),onEnd:(c,u)=>{delete this.session,l&&Xe.postRender(()=>l(c,u))}}}mount(){this.removePointerDownListener=no(this.node.current,"pointerdown",e=>this.onPointerDown(e))}update(){this.session&&this.session.updateHandlers(this.createPanHandlers())}unmount(){this.removePointerDownListener(),this.session&&this.session.end()}}let wd=!1;class Hj extends D.Component{componentDidMount(){const{visualElement:e,layoutGroup:i,switchLayoutGroup:a,layoutId:l}=this.props,{projection:c}=e;c&&(i.group&&i.group.add(c),a&&a.register&&l&&a.register(c),wd&&c.root.didUpdate(),c.addEventListener("animationComplete",()=>{this.safeToRemove()}),c.setOptions({...c.options,layoutDependency:this.props.layoutDependency,onExitComplete:()=>this.safeToRemove()})),fc.hasEverUpdated=!0}getSnapshotBeforeUpdate(e){const{layoutDependency:i,visualElement:a,drag:l,isPresent:c}=this.props,{projection:u}=a;return u&&(u.isPresent=c,e.layoutDependency!==i&&u.setOptions({...u.options,layoutDependency:i}),wd=!0,l||e.layoutDependency!==i||i===void 0||e.isPresent!==c?u.willUpdate():this.safeToRemove(),e.isPresent!==c&&(c?u.promote():u.relegate()||Xe.postRender(()=>{const d=u.getStack();(!d||!d.members.length)&&this.safeToRemove()}))),null}componentDidUpdate(){const{visualElement:e,layoutAnchor:i}=this.props,{projection:a}=e;a&&(a.options.layoutAnchor=i,a.root.didUpdate(),Ff.postRender(()=>{!a.currentAnimation&&a.isLead()&&this.safeToRemove()}))}componentWillUnmount(){const{visualElement:e,layoutGroup:i,switchLayoutGroup:a}=this.props,{projection:l}=e;wd=!0,l&&(l.scheduleCheckAfterUnmount(),i&&i.group&&i.group.remove(l),a&&a.deregister&&a.deregister(l))}safeToRemove(){const{safeToRemove:e}=this.props;e&&e()}render(){return null}}function rw(n){const[e,i]=Yx(),a=D.useContext(Tf);return g.jsx(Hj,{...n,layoutGroup:a,switchLayoutGroup:D.useContext(tw),isPresent:e,safeToRemove:i})}const $j={pan:{Feature:Vj},drag:{Feature:Pj,ProjectionNode:Kx,MeasureLayout:rw}};function gb(n,e,i){const{props:a}=n;n.animationState&&a.whileHover&&n.animationState.setActive("whileHover",i==="Start");const l="onHover"+i,c=a[l];c&&Xe.postRender(()=>c(e,So(e)))}class qj extends li{mount(){const{current:e}=this.node;e&&(this.unmount=hE(e,(i,a)=>(gb(this.node,a,"Start"),l=>gb(this.node,l,"End"))))}unmount(){}}class Fj extends li{constructor(){super(...arguments),this.isActive=!1}onFocus(){let e=!1;try{e=this.node.current.matches(":focus-visible")}catch{e=!0}!e||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!0),this.isActive=!0)}onBlur(){!this.isActive||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!1),this.isActive=!1)}mount(){this.unmount=xo(co(this.node.current,"focus",()=>this.onFocus()),co(this.node.current,"blur",()=>this.onBlur()))}unmount(){}}function yb(n,e,i){const{props:a}=n;if(n.current instanceof HTMLButtonElement&&n.current.disabled)return;n.animationState&&a.whileTap&&n.animationState.setActive("whileTap",i==="Start");const l="onTap"+(i==="End"?"":i),c=a[l];c&&Xe.postRender(()=>c(e,So(e)))}class Ij extends li{mount(){const{current:e}=this.node;if(!e)return;const{globalTapTarget:i,propagate:a}=this.node.props;this.unmount=yE(e,(l,c)=>(yb(this.node,c,"Start"),(u,{success:d})=>yb(this.node,u,d?"End":"Cancel")),{useGlobalTarget:i,stopPropagation:(a==null?void 0:a.tap)===!1})}unmount(){}}const of=new WeakMap,_d=new WeakMap,Gj=n=>{const e=of.get(n.target);e&&e(n)},Kj=n=>{n.forEach(Gj)};function Yj({root:n,...e}){const i=n||document;_d.has(i)||_d.set(i,{});const a=_d.get(i),l=JSON.stringify(e);return a[l]||(a[l]=new IntersectionObserver(Kj,{root:n,...e})),a[l]}function Xj(n,e,i){const a=Yj(e);return of.set(n,i),a.observe(n),()=>{of.delete(n),a.unobserve(n)}}const Jj={some:0,all:1};class Qj extends li{constructor(){super(...arguments),this.hasEnteredView=!1,this.isInView=!1}startObserver(){var m;(m=this.stopObserver)==null||m.call(this);const{viewport:e={}}=this.node.getProps(),{root:i,margin:a,amount:l="some",once:c}=e,u={root:i?i.current:void 0,rootMargin:a,threshold:typeof l=="number"?l:Jj[l]},d=p=>{const{isIntersecting:y}=p;if(this.isInView===y||(this.isInView=y,c&&!y&&this.hasEnteredView))return;y&&(this.hasEnteredView=!0),this.node.animationState&&this.node.animationState.setActive("whileInView",y);const{onViewportEnter:v,onViewportLeave:x}=this.node.getProps(),_=y?v:x;_&&_(p)};this.stopObserver=Xj(this.node.current,u,d)}mount(){this.startObserver()}update(){if(typeof IntersectionObserver>"u")return;const{props:e,prevProps:i}=this.node;["amount","margin","root"].some(Zj(e,i))&&this.startObserver()}unmount(){var e;(e=this.stopObserver)==null||e.call(this),this.hasEnteredView=!1,this.isInView=!1}}function Zj({viewport:n={}},{viewport:e={}}={}){return i=>n[i]!==e[i]}const Wj={inView:{Feature:Qj},tap:{Feature:Ij},focus:{Feature:Fj},hover:{Feature:qj}},e2={layout:{ProjectionNode:Kx,MeasureLayout:rw}},t2={...Tj,...Wj,...$j,...e2},n2=vj(t2,xj),Tn=n2;/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const s2=n=>n.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),i2=n=>n.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,i,a)=>a?a.toUpperCase():i.toLowerCase()),bb=n=>{const e=i2(n);return e.charAt(0).toUpperCase()+e.slice(1)},ow=(...n)=>n.filter((e,i,a)=>!!e&&e.trim()!==""&&a.indexOf(e)===i).join(" ").trim(),a2=n=>{for(const e in n)if(e.startsWith("aria-")||e==="role"||e==="title")return!0};/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */var r2={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const o2=D.forwardRef(({color:n="currentColor",size:e=24,strokeWidth:i=2,absoluteStrokeWidth:a,className:l="",children:c,iconNode:u,...d},m)=>D.createElement("svg",{ref:m,...r2,width:e,height:e,stroke:n,strokeWidth:a?Number(i)*24/Number(e):i,className:ow("lucide",l),...!c&&!a2(d)&&{"aria-hidden":"true"},...d},[...u.map(([p,y])=>D.createElement(p,y)),...Array.isArray(c)?c:[c]]));/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Me=(n,e)=>{const i=D.forwardRef(({className:a,...l},c)=>D.createElement(o2,{ref:c,iconNode:e,className:ow(`lucide-${s2(bb(n))}`,`lucide-${n}`,a),...l}));return i.displayName=bb(n),i};/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const l2=[["path",{d:"M8 3 4 7l4 4",key:"9rb6wj"}],["path",{d:"M4 7h16",key:"6tx8e3"}],["path",{d:"m16 21 4-4-4-4",key:"siv7j2"}],["path",{d:"M20 17H4",key:"h6l3hr"}]],c2=Me("arrow-left-right",l2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const u2=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]],h2=Me("arrow-right",u2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const d2=[["rect",{width:"20",height:"12",x:"2",y:"6",rx:"2",key:"9lu3g6"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}],["path",{d:"M6 12h.01M18 12h.01",key:"113zkx"}]],vb=Me("banknote",d2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const f2=[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}],["path",{d:"M8 14h.01",key:"6423bh"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M16 14h.01",key:"1gbofw"}],["path",{d:"M8 18h.01",key:"lrp35t"}],["path",{d:"M12 18h.01",key:"mhygvu"}],["path",{d:"M16 18h.01",key:"kzsmim"}]],m2=Me("calendar-days",f2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const p2=[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}]],g2=Me("calendar",p2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const y2=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],b2=Me("chevron-down",y2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const v2=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]],x2=Me("circle-alert",v2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const w2=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],Ec=Me("circle-check",w2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const _2=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"10",r:"3",key:"ilqhr7"}],["path",{d:"M7 20.662V19a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v1.662",key:"154egf"}]],S2=Me("circle-user",_2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const T2=[["path",{d:"M21.54 15H17a2 2 0 0 0-2 2v4.54",key:"1djwo0"}],["path",{d:"M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17",key:"1tzkfa"}],["path",{d:"M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05",key:"14pb5j"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],lw=Me("earth",T2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const E2=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],A2=Me("external-link",E2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const j2=[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],N2=Me("eye",j2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const R2=[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M8 13h2",key:"yr2amv"}],["path",{d:"M14 13h2",key:"un5t4a"}],["path",{d:"M8 17h2",key:"2yhykz"}],["path",{d:"M14 17h2",key:"10kma7"}]],Ca=Me("file-spreadsheet",R2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const k2=[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]],Xl=Me("file-text",k2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const C2=[["path",{d:"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z",key:"sc7q7i"}]],O2=Me("funnel",C2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const D2=[["rect",{x:"3",y:"8",width:"18",height:"4",rx:"1",key:"bkv52"}],["path",{d:"M12 8v13",key:"1c76mn"}],["path",{d:"M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7",key:"6wjy6b"}],["path",{d:"M7.5 8a2.5 2.5 0 0 1 0-5A4.8 8 0 0 1 12 8a4.8 8 0 0 1 4.5-5 2.5 2.5 0 0 1 0 5",key:"1ihvrl"}]],xb=Me("gift",D2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const M2=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M12 7v5l4 2",key:"1fdv2h"}]],B2=Me("history",M2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const U2=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],cw=Me("info",U2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const L2=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],Ha=Me("loader-circle",L2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const z2=[["circle",{cx:"12",cy:"16",r:"1",key:"1au0dj"}],["rect",{x:"3",y:"10",width:"18",height:"12",rx:"2",key:"6s8ecr"}],["path",{d:"M7 10V7a5 5 0 0 1 10 0v3",key:"1pqi11"}]],P2=Me("lock-keyhole",z2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const V2=[["path",{d:"m16 17 5-5-5-5",key:"1bji2h"}],["path",{d:"M21 12H9",key:"dn1m92"}],["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}]],H2=Me("log-out",V2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const $2=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],uw=Me("menu",$2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const q2=[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}],["path",{d:"M12 15h.01",key:"q59x07"}],["path",{d:"M12 7v4",key:"xawao1"}]],F2=Me("message-square-warning",q2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const I2=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]],G2=Me("play",I2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const K2=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]],Y2=Me("plus",K2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const X2=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],J2=Me("refresh-cw",X2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Q2=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],Xr=Me("search",Q2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Z2=[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]],hw=Me("send",Z2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const W2=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],Ta=Me("trash-2",W2);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const eN=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],Ac=Me("triangle-alert",eN);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const tN=[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]],Ir=Me("upload",tN);/** + * @license lucide-react v0.546.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const nN=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Ga=Me("x",nN),uo=[{code:"GT",name:"Guatemala",flag:"/cruce-cuentas/gt-flag.png",currency:"GTQ",locale:"es-GT",enabled:!0},{code:"TT",name:"Trinidad y Tobago",flag:"/cruce-cuentas/tt-flag.png",currency:"TTD",locale:"en-TT",enabled:!0},{code:"PA",name:"Panamá",flag:"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_Panama.svg",currency:"USD",locale:"es-PA",enabled:!0},{code:"SV",name:"El Salvador",flag:"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_El_Salvador.svg.webp",currency:"USD",locale:"es-SV",enabled:!0},{code:"HN",name:"Honduras",flag:"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Bandera%20de%20Honduras.webp",currency:"HNL",locale:"es-HN",enabled:!0},{code:"PR",name:"Puerto Rico",flag:"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/bandera-nacional-tela-puerto-rico_113767-1759.avif",currency:"USD",locale:"es-PR",enabled:!0},{code:"RD",name:"República Dominicana",flag:"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_the_Dominican_Republic.svg.webp",currency:"DOP",locale:"es-DO",enabled:!0}];function wb(n){return uo.find(e=>e.code===n)??uo[0]}const sN="https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png";function iN({currentView:n,onViewChange:e,onNewCruce:i,isSidebarOpen:a=!1,onCloseSidebar:l,user:c,isAuthEnabled:u=!1,onLogout:d,country:m,onCountryChange:p,onChooseAnotherCountry:y}){const[v,x]=D.useState(!1),_=D.useRef(null);return D.useEffect(()=>{function S(T){_.current&&!_.current.contains(T.target)&&x(!1)}return document.addEventListener("mousedown",S),()=>document.removeEventListener("mousedown",S)},[]),g.jsxs("aside",{className:`bg-neutral-100 h-screen w-64 fixed left-0 top-0 flex flex-col z-50 pb-6 min-h-screen font-sans transition-transform duration-300 md:translate-x-0 ${a?"translate-x-0":"-translate-x-full"}`,children:[g.jsx("div",{className:"absolute right-0 top-0 h-[80px] w-px bg-[#D0D0D0] pointer-events-none z-10 hidden md:block"}),g.jsx("div",{className:"absolute right-0 top-[84px] bottom-0 w-px bg-[#D0D0D0] pointer-events-none z-10 hidden md:block"}),g.jsxs("div",{className:"h-[84px] px-4 flex justify-between md:justify-center items-center bg-white border-b-4 border-[#6CC24A] relative",children:[g.jsx("img",{alt:"GomezLee Marketing logo",className:"h-10 object-contain selection:bg-transparent",src:sN}),g.jsx("button",{onClick:l,className:"md:hidden p-2 text-neutral-500 hover:text-neutral-800 transition-colors","aria-label":"Cerrar menú",children:g.jsx(Ga,{className:"w-5 h-5"})})]}),g.jsxs("div",{className:"px-4 pt-5",children:[g.jsxs("label",{className:"block",children:[g.jsxs("span",{className:"text-[9px] uppercase tracking-wider font-black text-neutral-400 flex items-center gap-1.5 mb-1.5",children:[g.jsx(lw,{className:"w-3.5 h-3.5"}),"País"]}),g.jsxs("div",{className:"relative",ref:_,children:[g.jsxs("button",{type:"button",onClick:()=>x(!v),className:"w-full border border-neutral-300 bg-white px-3 py-2 text-xs font-bold text-[#4F758B] focus:outline-none focus:border-[#4F758B] flex items-center justify-between transition-colors hover:bg-neutral-50",children:[g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx("img",{src:m.flag,alt:"",className:"w-5 h-3.5 object-cover shadow-sm border border-neutral-200"}),g.jsx("span",{children:m.name})]}),g.jsx(b2,{className:`w-4 h-4 text-[#4F758B] transition-transform ${v?"rotate-180":""}`})]}),v&&g.jsx("ul",{className:"absolute left-0 right-0 top-full mt-1 bg-white border border-neutral-300 shadow-lg z-50 py-1",children:uo.map(S=>g.jsx("li",{children:g.jsxs("button",{type:"button",disabled:!S.enabled,onClick:()=>{p(S.code),x(!1)},className:`w-full text-left px-3 py-2.5 text-xs font-bold flex items-center gap-2.5 transition-colors ${S.enabled?"hover:bg-neutral-100 text-[#4F758B]":"opacity-60 cursor-not-allowed text-neutral-500 bg-neutral-50"}`,children:[g.jsx("img",{src:S.flag,alt:"",className:"w-6 h-4 object-cover shadow-sm border border-neutral-200 bg-white flex-shrink-0"}),g.jsxs("span",{className:"min-w-0 text-left leading-tight",children:[g.jsx("span",{className:"block",children:S.name}),!S.enabled&&g.jsx("span",{className:"block mt-1 text-[10px] text-neutral-400 font-medium italic",children:"Próximamente"})]})]})},S.code))})]})]}),g.jsx("button",{type:"button",onClick:y,className:"mt-2 text-[9px] font-bold uppercase tracking-wider text-neutral-400 hover:text-[#4F758B]",children:"Ver países disponibles"})]}),g.jsx("nav",{className:"flex-1 flex flex-col mt-5",children:g.jsxs("ul",{className:"space-y-1",children:[g.jsx("li",{children:g.jsxs("button",{onClick:()=>e("cruce"),className:`w-full flex items-center gap-3 px-6 py-3.5 transition-all duration-150 text-left font-bold text-sm tracking-wide ${n==="cruce"?"bg-[#4F758B] text-white":"text-neutral-600 hover:bg-neutral-200 hover:text-neutral-800"}`,children:[g.jsx(c2,{className:`w-4 h-4 ${n==="cruce"?"text-[#6CC24A]":""}`}),g.jsx("span",{children:"Cruce de Cuentas"})]})}),g.jsx("li",{children:g.jsxs("button",{onClick:()=>e("historial"),className:`w-full flex items-center gap-3 px-6 py-3.5 transition-all duration-150 text-left font-bold text-sm tracking-wide ${n==="historial"?"bg-[#4F758B] text-white":"text-neutral-600 hover:bg-neutral-200 hover:text-neutral-800"}`,children:[g.jsx(B2,{className:`w-4 h-4 ${n==="historial"?"text-[#6CC24A]":""}`}),g.jsx("span",{children:"Reportes Históricos"})]})})]})}),g.jsxs("div",{className:"px-4 space-y-3 pt-4 border-t border-[#D0D0D0] bg-neutral-100",children:[c&&g.jsxs("div",{className:"border border-neutral-200 bg-white px-3 py-3 flex items-center gap-2",children:[g.jsx(S2,{className:"w-4 h-4 text-[#4F758B] flex-shrink-0"}),g.jsxs("div",{className:"min-w-0",children:[g.jsx("p",{className:"text-[11px] font-black text-neutral-700 truncate",title:c.name,children:c.name}),g.jsx("p",{className:"text-[9px] text-neutral-400 truncate",title:c.email,children:c.email})]})]}),g.jsxs("button",{onClick:i,className:"w-full bg-[#6CC24A] hover:bg-[#5bb03c] text-white py-3 px-4 font-bold text-xs uppercase tracking-wider flex items-center justify-center gap-2 transition-all duration-150 shadow-sm active:scale-98",children:[g.jsx(Y2,{className:"w-4 h-4"}),g.jsx("span",{children:"Nuevo Cruce"})]}),u&&d&&g.jsxs("button",{onClick:d,className:"w-full border border-neutral-300 bg-white hover:bg-neutral-50 text-neutral-600 py-2.5 px-4 font-bold text-[11px] uppercase tracking-wider flex items-center justify-center gap-2 transition-all duration-150",children:[g.jsx(H2,{className:"w-4 h-4"}),g.jsx("span",{children:"Cerrar sesión"})]})]})]})}function Hc(n,e){var i={};for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&e.indexOf(a)<0&&(i[a]=n[a]);if(n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var l=0,a=Object.getOwnPropertySymbols(n);ln?(...e)=>n(...e):(...e)=>fetch(...e);class em extends Error{constructor(e,i="FunctionsError",a){super(e),this.name=i,this.context=a}toJSON(){return{name:this.name,message:this.message,context:this.context}}}class oN extends em{constructor(e){super("Failed to send a request to the Edge Function","FunctionsFetchError",e)}}class _b extends em{constructor(e){super("Relay Error invoking the Edge Function","FunctionsRelayError",e)}}class Sb extends em{constructor(e){super("Edge Function returned a non-2xx status code","FunctionsHttpError",e)}}var lf;(function(n){n.Any="any",n.ApNortheast1="ap-northeast-1",n.ApNortheast2="ap-northeast-2",n.ApSouth1="ap-south-1",n.ApSoutheast1="ap-southeast-1",n.ApSoutheast2="ap-southeast-2",n.CaCentral1="ca-central-1",n.EuCentral1="eu-central-1",n.EuWest1="eu-west-1",n.EuWest2="eu-west-2",n.EuWest3="eu-west-3",n.SaEast1="sa-east-1",n.UsEast1="us-east-1",n.UsWest1="us-west-1",n.UsWest2="us-west-2"})(lf||(lf={}));class lN{constructor(e,{headers:i={},customFetch:a,region:l=lf.Any}={}){this.url=e,this.headers=i,this.region=l,this.fetch=rN(a)}setAuth(e){this.headers.Authorization=`Bearer ${e}`}invoke(e){return aN(this,arguments,void 0,function*(i,a={}){var l;let c,u;try{const{headers:d,method:m,body:p,signal:y,timeout:v}=a;let x={},{region:_}=a;_||(_=this.region);const S=new URL(`${this.url}/${i}`);_&&_!=="any"&&(x["x-region"]=_,S.searchParams.set("forceFunctionRegion",_));let T;const j=!!d&&Object.keys(d).some(G=>G.toLowerCase()==="content-type");p&&!j?typeof Blob<"u"&&p instanceof Blob||p instanceof ArrayBuffer?(x["Content-Type"]="application/octet-stream",T=p):typeof p=="string"?(x["Content-Type"]="text/plain",T=p):typeof FormData<"u"&&p instanceof FormData?T=p:(x["Content-Type"]="application/json",T=JSON.stringify(p)):p&&typeof p!="string"&&!(typeof Blob<"u"&&p instanceof Blob)&&!(p instanceof ArrayBuffer)&&!(typeof FormData<"u"&&p instanceof FormData)?T=JSON.stringify(p):T=p;let k=y;v&&(u=new AbortController,c=setTimeout(()=>u.abort(),v),y?(k=u.signal,y.addEventListener("abort",()=>u.abort())):k=u.signal);const M=yield this.fetch(S.toString(),{method:m||"POST",headers:Object.assign(Object.assign(Object.assign({},x),this.headers),d),body:T,signal:k}).catch(G=>{throw new oN(G)}),C=M.headers.get("x-relay-error");if(C&&C==="true")throw new _b(M);if(!M.ok)throw new Sb(M);let P=((l=M.headers.get("Content-Type"))!==null&&l!==void 0?l:"text/plain").split(";")[0].trim(),K;return P==="application/json"?K=yield M.json():P==="application/octet-stream"||P==="application/pdf"?K=yield M.blob():P==="text/event-stream"?K=M:P==="multipart/form-data"?K=yield M.formData():K=yield M.text(),{data:K,error:null,response:M}}catch(d){return{data:null,error:d,response:d instanceof Sb||d instanceof _b?d.context:void 0}}finally{c&&clearTimeout(c)}})}}const dw=3,Tb=n=>Math.min(1e3*2**n,3e4),cN=[520,503],fw=["GET","HEAD","OPTIONS"];var Eb=class extends Error{constructor(n){super(n.message),this.name="PostgrestError",this.details=n.details,this.hint=n.hint,this.code=n.code}toJSON(){return{name:this.name,message:this.message,details:this.details,hint:this.hint,code:this.code}}};function Ab(n,e){return new Promise(i=>{if(e!=null&&e.aborted){i();return}const a=setTimeout(()=>{e==null||e.removeEventListener("abort",l),i()},n);function l(){clearTimeout(a),i()}e==null||e.addEventListener("abort",l)})}function uN(n,e,i,a){return!(!a||i>=dw||!fw.includes(n)||!cN.includes(e))}var hN=class{constructor(n){var e,i,a,l,c;this.shouldThrowOnError=!1,this.retryEnabled=!0,this.method=n.method,this.url=n.url,this.headers=new Headers(n.headers),this.schema=n.schema,this.body=n.body,this.shouldThrowOnError=(e=n.shouldThrowOnError)!==null&&e!==void 0?e:!1,this.signal=n.signal,this.isMaybeSingle=(i=n.isMaybeSingle)!==null&&i!==void 0?i:!1,this.shouldStripNulls=(a=n.shouldStripNulls)!==null&&a!==void 0?a:!1,this.urlLengthLimit=(l=n.urlLengthLimit)!==null&&l!==void 0?l:8e3,this.retryEnabled=(c=n.retry)!==null&&c!==void 0?c:!0,n.fetch?this.fetch=n.fetch:this.fetch=fetch}throwOnError(){return this.shouldThrowOnError=!0,this}stripNulls(){if(this.headers.get("Accept")==="text/csv")throw new Error("stripNulls() cannot be used with csv()");return this.shouldStripNulls=!0,this}setHeader(n,e){return this.headers=new Headers(this.headers),this.headers.set(n,e),this}retry(n){return this.retryEnabled=n,this}then(n,e){var i=this;if(this.schema===void 0||(["GET","HEAD"].includes(this.method)?this.headers.set("Accept-Profile",this.schema):this.headers.set("Content-Profile",this.schema)),this.method!=="GET"&&this.method!=="HEAD"&&this.headers.set("Content-Type","application/json"),this.shouldStripNulls){const u=this.headers.get("Accept");u==="application/vnd.pgrst.object+json"?this.headers.set("Accept","application/vnd.pgrst.object+json;nulls=stripped"):(!u||u==="application/json")&&this.headers.set("Accept","application/vnd.pgrst.array+json;nulls=stripped")}const a=this.fetch;let c=(async()=>{let u=0;for(;;){const p={};i.headers.forEach((v,x)=>{p[x]=v}),u>0&&(p["X-Retry-Count"]=String(u));let y;try{y=await a(i.url.toString(),{method:i.method,headers:p,body:JSON.stringify(i.body,(v,x)=>typeof x=="bigint"?x.toString():x),signal:i.signal})}catch(v){if((v==null?void 0:v.name)==="AbortError"||(v==null?void 0:v.code)==="ABORT_ERR"||!fw.includes(i.method))throw v;if(i.retryEnabled&&u{var d;let m="",p="",y="";const v=u==null?void 0:u.cause;if(v){var x,_,S,T;const M=(x=v==null?void 0:v.message)!==null&&x!==void 0?x:"",C=(_=v==null?void 0:v.code)!==null&&_!==void 0?_:"";m=`${(S=u==null?void 0:u.name)!==null&&S!==void 0?S:"FetchError"}: ${u==null?void 0:u.message}`,m+=` + +Caused by: ${(T=v==null?void 0:v.name)!==null&&T!==void 0?T:"Error"}: ${M}`,C&&(m+=` (${C})`),v!=null&&v.stack&&(m+=` +${v.stack}`)}else{var j;m=(j=u==null?void 0:u.stack)!==null&&j!==void 0?j:""}const k=this.url.toString().length;return(u==null?void 0:u.name)==="AbortError"||(u==null?void 0:u.code)==="ABORT_ERR"?(y="",p="Request was aborted (timeout or manual cancellation)",k>this.urlLengthLimit&&(p+=`. Note: Your request URL is ${k} characters, which may exceed server limits. If selecting many fields, consider using views. If filtering with large arrays (e.g., .in('id', [many IDs])), consider using an RPC function to pass values server-side.`)):((v==null?void 0:v.name)==="HeadersOverflowError"||(v==null?void 0:v.code)==="UND_ERR_HEADERS_OVERFLOW")&&(y="",p="HTTP headers exceeded server limits (typically 16KB)",k>this.urlLengthLimit&&(p+=`. Your request URL is ${k} characters. If selecting many fields, consider using views. If filtering with large arrays (e.g., .in('id', [200+ IDs])), consider using an RPC function instead.`)),{success:!1,error:{message:`${(d=u==null?void 0:u.name)!==null&&d!==void 0?d:"FetchError"}: ${u==null?void 0:u.message}`,details:m,hint:p,code:y},data:null,count:null,status:0,statusText:""}})),c.then(n,e)}async processResponse(n){var e=this;let i=null,a=null,l=null,c=n.status,u=n.statusText;if(n.ok){var d,m;if(e.method!=="HEAD"){var p;const x=await n.text();if(x!=="")if(e.headers.get("Accept")==="text/csv")a=x;else if(e.headers.get("Accept")&&(!((p=e.headers.get("Accept"))===null||p===void 0)&&p.includes("application/vnd.pgrst.plan+text")))a=x;else try{a=JSON.parse(x)}catch{if(i={message:x},a=null,e.shouldThrowOnError)throw new Eb({message:x,details:"",hint:"",code:""})}}const y=(d=e.headers.get("Prefer"))===null||d===void 0?void 0:d.match(/count=(exact|planned|estimated)/),v=(m=n.headers.get("content-range"))===null||m===void 0?void 0:m.split("/");y&&v&&v.length>1&&(l=parseInt(v[1])),e.isMaybeSingle&&Array.isArray(a)&&(a.length>1?(i={code:"PGRST116",details:`Results contain ${a.length} rows, application/vnd.pgrst.object+json requires 1 row`,hint:null,message:"JSON object requested, multiple (or no) rows returned"},a=null,l=null,c=406,u="Not Acceptable"):a.length===1?a=a[0]:a=null)}else{const y=await n.text();try{i=JSON.parse(y),Array.isArray(i)&&n.status===404&&(a=[],i=null,c=200,u="OK")}catch{n.status===404&&y===""?(c=204,u="No Content"):i={message:y}}if(i&&e.shouldThrowOnError)throw new Eb(i)}return{success:i===null,error:i,data:a,count:l,status:c,statusText:u}}returns(){return this}overrideTypes(){return this}},dN=class extends hN{throwOnError(){return super.throwOnError()}select(n){let e=!1;const i=(n??"*").split("").map(a=>/\s/.test(a)&&!e?"":(a==='"'&&(e=!e),a)).join("");return this.url.searchParams.set("select",i),this.headers.append("Prefer","return=representation"),this}order(n,{ascending:e=!0,nullsFirst:i,foreignTable:a,referencedTable:l=a}={}){const c=l?`${l}.order`:"order",u=this.url.searchParams.get(c);return this.url.searchParams.set(c,`${u?`${u},`:""}${n}.${e?"asc":"desc"}${i===void 0?"":i?".nullsfirst":".nullslast"}`),this}limit(n,{foreignTable:e,referencedTable:i=e}={}){const a=typeof i>"u"?"limit":`${i}.limit`;return this.url.searchParams.set(a,`${n}`),this}range(n,e,{foreignTable:i,referencedTable:a=i}={}){const l=typeof a>"u"?"offset":`${a}.offset`,c=typeof a>"u"?"limit":`${a}.limit`;return this.url.searchParams.set(l,`${n}`),this.url.searchParams.set(c,`${e-n+1}`),this}abortSignal(n){return this.signal=n,this}single(){return this.headers.set("Accept","application/vnd.pgrst.object+json"),this}maybeSingle(){return this.isMaybeSingle=!0,this}csv(){return this.headers.set("Accept","text/csv"),this}geojson(){return this.headers.set("Accept","application/geo+json"),this}explain({analyze:n=!1,verbose:e=!1,settings:i=!1,buffers:a=!1,wal:l=!1,format:c="text"}={}){var u;const d=[n?"analyze":null,e?"verbose":null,i?"settings":null,a?"buffers":null,l?"wal":null].filter(Boolean).join("|"),m=(u=this.headers.get("Accept"))!==null&&u!==void 0?u:"application/json";return this.headers.set("Accept",`application/vnd.pgrst.plan+${c}; for="${m}"; options=${d};`),c==="json"?this:this}rollback(){return this.headers.append("Prefer","tx=rollback"),this}returns(){return this}maxAffected(n){return this.headers.append("Prefer","handling=strict"),this.headers.append("Prefer",`max-affected=${n}`),this}};const jb=new RegExp("[,()]");var Oa=class extends dN{throwOnError(){return super.throwOnError()}eq(n,e){return this.url.searchParams.append(n,`eq.${e}`),this}neq(n,e){return this.url.searchParams.append(n,`neq.${e}`),this}gt(n,e){return this.url.searchParams.append(n,`gt.${e}`),this}gte(n,e){return this.url.searchParams.append(n,`gte.${e}`),this}lt(n,e){return this.url.searchParams.append(n,`lt.${e}`),this}lte(n,e){return this.url.searchParams.append(n,`lte.${e}`),this}like(n,e){return this.url.searchParams.append(n,`like.${e}`),this}likeAllOf(n,e){return this.url.searchParams.append(n,`like(all).{${e.join(",")}}`),this}likeAnyOf(n,e){return this.url.searchParams.append(n,`like(any).{${e.join(",")}}`),this}ilike(n,e){return this.url.searchParams.append(n,`ilike.${e}`),this}ilikeAllOf(n,e){return this.url.searchParams.append(n,`ilike(all).{${e.join(",")}}`),this}ilikeAnyOf(n,e){return this.url.searchParams.append(n,`ilike(any).{${e.join(",")}}`),this}regexMatch(n,e){return this.url.searchParams.append(n,`match.${e}`),this}regexIMatch(n,e){return this.url.searchParams.append(n,`imatch.${e}`),this}is(n,e){return this.url.searchParams.append(n,`is.${e}`),this}isDistinct(n,e){return this.url.searchParams.append(n,`isdistinct.${e}`),this}in(n,e){const i=Array.from(new Set(e)).map(a=>typeof a=="string"&&jb.test(a)?`"${a}"`:`${a}`).join(",");return this.url.searchParams.append(n,`in.(${i})`),this}notIn(n,e){const i=Array.from(new Set(e)).map(a=>typeof a=="string"&&jb.test(a)?`"${a}"`:`${a}`).join(",");return this.url.searchParams.append(n,`not.in.(${i})`),this}contains(n,e){return typeof e=="string"?this.url.searchParams.append(n,`cs.${e}`):Array.isArray(e)?this.url.searchParams.append(n,`cs.{${e.join(",")}}`):this.url.searchParams.append(n,`cs.${JSON.stringify(e)}`),this}containedBy(n,e){return typeof e=="string"?this.url.searchParams.append(n,`cd.${e}`):Array.isArray(e)?this.url.searchParams.append(n,`cd.{${e.join(",")}}`):this.url.searchParams.append(n,`cd.${JSON.stringify(e)}`),this}rangeGt(n,e){return this.url.searchParams.append(n,`sr.${e}`),this}rangeGte(n,e){return this.url.searchParams.append(n,`nxl.${e}`),this}rangeLt(n,e){return this.url.searchParams.append(n,`sl.${e}`),this}rangeLte(n,e){return this.url.searchParams.append(n,`nxr.${e}`),this}rangeAdjacent(n,e){return this.url.searchParams.append(n,`adj.${e}`),this}overlaps(n,e){return typeof e=="string"?this.url.searchParams.append(n,`ov.${e}`):this.url.searchParams.append(n,`ov.{${e.join(",")}}`),this}textSearch(n,e,{config:i,type:a}={}){let l="";a==="plain"?l="pl":a==="phrase"?l="ph":a==="websearch"&&(l="w");const c=i===void 0?"":`(${i})`;return this.url.searchParams.append(n,`${l}fts${c}.${e}`),this}match(n){return Object.entries(n).filter(([e,i])=>i!==void 0).forEach(([e,i])=>{this.url.searchParams.append(e,`eq.${i}`)}),this}not(n,e,i){return this.url.searchParams.append(n,`not.${e}.${i}`),this}or(n,{foreignTable:e,referencedTable:i=e}={}){const a=i?`${i}.or`:"or";return this.url.searchParams.append(a,`(${n})`),this}filter(n,e,i){return this.url.searchParams.append(n,`${e}.${i}`),this}},fN=class{constructor(n,{headers:e={},schema:i,fetch:a,urlLengthLimit:l=8e3,retry:c}){this.url=n,this.headers=new Headers(e),this.schema=i,this.fetch=a,this.urlLengthLimit=l,this.retry=c}cloneRequestState(){return{url:new URL(this.url.toString()),headers:new Headers(this.headers)}}select(n,e){const{head:i=!1,count:a}=e??{},l=i?"HEAD":"GET";let c=!1;const u=(n??"*").split("").map(p=>/\s/.test(p)&&!c?"":(p==='"'&&(c=!c),p)).join(""),{url:d,headers:m}=this.cloneRequestState();return d.searchParams.set("select",u),a&&m.append("Prefer",`count=${a}`),new Oa({method:l,url:d,headers:m,schema:this.schema,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}insert(n,{count:e,defaultToNull:i=!0}={}){var a;const l="POST",{url:c,headers:u}=this.cloneRequestState();if(e&&u.append("Prefer",`count=${e}`),i||u.append("Prefer","missing=default"),Array.isArray(n)){const d=n.reduce((m,p)=>m.concat(Object.keys(p)),[]);if(d.length>0){const m=[...new Set(d)].map(p=>`"${p}"`);c.searchParams.set("columns",m.join(","))}}return new Oa({method:l,url:c,headers:u,schema:this.schema,body:n,fetch:(a=this.fetch)!==null&&a!==void 0?a:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}upsert(n,{onConflict:e,ignoreDuplicates:i=!1,count:a,defaultToNull:l=!0}={}){var c;const u="POST",{url:d,headers:m}=this.cloneRequestState();if(m.append("Prefer",`resolution=${i?"ignore":"merge"}-duplicates`),e!==void 0&&d.searchParams.set("on_conflict",e),a&&m.append("Prefer",`count=${a}`),l||m.append("Prefer","missing=default"),Array.isArray(n)){const p=n.reduce((y,v)=>y.concat(Object.keys(v)),[]);if(p.length>0){const y=[...new Set(p)].map(v=>`"${v}"`);d.searchParams.set("columns",y.join(","))}}return new Oa({method:u,url:d,headers:m,schema:this.schema,body:n,fetch:(c=this.fetch)!==null&&c!==void 0?c:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}update(n,{count:e}={}){var i;const a="PATCH",{url:l,headers:c}=this.cloneRequestState();return e&&c.append("Prefer",`count=${e}`),new Oa({method:a,url:l,headers:c,schema:this.schema,body:n,fetch:(i=this.fetch)!==null&&i!==void 0?i:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}delete({count:n}={}){var e;const i="DELETE",{url:a,headers:l}=this.cloneRequestState();return n&&l.append("Prefer",`count=${n}`),new Oa({method:i,url:a,headers:l,schema:this.schema,fetch:(e=this.fetch)!==null&&e!==void 0?e:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}};function ho(n){"@babel/helpers - typeof";return ho=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ho(n)}function mN(n,e){if(ho(n)!="object"||!n)return n;var i=n[Symbol.toPrimitive];if(i!==void 0){var a=i.call(n,e);if(ho(a)!="object")return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(n)}function pN(n){var e=mN(n,"string");return ho(e)=="symbol"?e:e+""}function gN(n,e,i){return(e=pN(e))in n?Object.defineProperty(n,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):n[e]=i,n}function Nb(n,e){var i=Object.keys(n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(n);e&&(a=a.filter(function(l){return Object.getOwnPropertyDescriptor(n,l).enumerable})),i.push.apply(i,a)}return i}function Jl(n){for(var e=1;e0?this.fetch=(p,y)=>{const v=new AbortController,x=setTimeout(()=>v.abort(),c),_=y==null?void 0:y.signal;if(_){if(_.aborted)return clearTimeout(x),m(p,y);const S=()=>{clearTimeout(x),v.abort()};return _.addEventListener("abort",S,{once:!0}),m(p,Jl(Jl({},y),{},{signal:v.signal})).finally(()=>{clearTimeout(x),_.removeEventListener("abort",S)})}return m(p,Jl(Jl({},y),{},{signal:v.signal})).finally(()=>clearTimeout(x))}:this.fetch=m,this.retry=d}from(e){if(!e||typeof e!="string"||e.trim()==="")throw new Error("Invalid relation name: relation must be a non-empty string.");return new fN(new URL(`${this.url}/${e}`),{headers:new Headers(this.headers),schema:this.schemaName,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}schema(e){return new mw(this.url,{headers:this.headers,schema:e,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}rpc(e,i={},{head:a=!1,get:l=!1,count:c}={}){var u;let d;const m=new URL(`${this.url}/rpc/${e}`);let p;const y=_=>_!==null&&typeof _=="object"&&(!Array.isArray(_)||_.some(y)),v=a&&Object.values(i).some(y);v?(d="POST",p=i):a||l?(d=a?"HEAD":"GET",Object.entries(i).filter(([_,S])=>S!==void 0).map(([_,S])=>[_,Array.isArray(S)?`{${S.join(",")}}`:`${S}`]).forEach(([_,S])=>{m.searchParams.append(_,S)})):(d="POST",p=i);const x=new Headers(this.headers);return v?x.set("Prefer",c?`count=${c},return=minimal`:"return=minimal"):c&&x.set("Prefer",`count=${c}`),new Oa({method:d,url:m,headers:x,schema:this.schemaName,body:p,fetch:(u=this.fetch)!==null&&u!==void 0?u:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}};class bN{constructor(){}static detectEnvironment(){var e;if(typeof WebSocket<"u")return{type:"native",wsConstructor:WebSocket};const i=globalThis;if(typeof globalThis<"u"&&typeof i.WebSocket<"u")return{type:"native",wsConstructor:i.WebSocket};const a=typeof global<"u"?global:void 0;if(a&&typeof a.WebSocket<"u")return{type:"native",wsConstructor:a.WebSocket};if(typeof globalThis<"u"&&typeof i.WebSocketPair<"u"&&typeof globalThis.WebSocket>"u")return{type:"cloudflare",error:"Cloudflare Workers detected. WebSocket clients are not supported in Cloudflare Workers.",workaround:"Use Cloudflare Workers WebSocket API for server-side WebSocket handling, or deploy to a different runtime."};if(typeof globalThis<"u"&&i.EdgeRuntime||typeof navigator<"u"&&(!((e=navigator.userAgent)===null||e===void 0)&&e.includes("Vercel-Edge")))return{type:"unsupported",error:"Edge runtime detected (Vercel Edge/Netlify Edge). WebSockets are not supported in edge functions.",workaround:"Use serverless functions or a different deployment target for WebSocket functionality."};const l=globalThis.process;if(l){const c=l.versions;if(c&&c.node)return{type:"unsupported",error:"Node.js detected but native WebSocket not found.",workaround:"Ensure you are running Node.js 22+ or provide a WebSocket implementation via the transport option."}}return{type:"unsupported",error:"Unknown JavaScript runtime without WebSocket support.",workaround:"Ensure you're running in a supported environment (browser, Node.js, Deno) or provide a custom WebSocket implementation."}}static getWebSocketConstructor(){const e=this.detectEnvironment();if(e.wsConstructor)return e.wsConstructor;let i=e.error||"WebSocket not supported in this environment.";throw e.workaround&&(i+=` + +Suggested solution: ${e.workaround}`),new Error(i)}static isWebSocketSupported(){try{return this.detectEnvironment().type==="native"}catch{return!1}}}const vN="2.110.2",xN=`realtime-js/${vN}`,wN="1.0.0",pw="2.0.0",_N=pw,SN=1e4,TN=100,si={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},gw={close:"phx_close",error:"phx_error",join:"phx_join",leave:"phx_leave",access_token:"access_token"},cf={connecting:"connecting",closing:"closing",closed:"closed"};class EN{constructor(e){this.HEADER_LENGTH=1,this.USER_BROADCAST_PUSH_META_LENGTH=6,this.KINDS={userBroadcastPush:3,userBroadcast:4},this.BINARY_ENCODING=0,this.JSON_ENCODING=1,this.BROADCAST_EVENT="broadcast",this.allowedMetadataKeys=[],this.allowedMetadataKeys=e??[]}encode(e,i){if(e.event===this.BROADCAST_EVENT&&!(e.payload instanceof ArrayBuffer)&&typeof e.payload.event=="string")return i(this._binaryEncodeUserBroadcastPush(e));let a=[e.join_ref,e.ref,e.topic,e.event,e.payload];return i(JSON.stringify(a))}_binaryEncodeUserBroadcastPush(e){var i;return this._isArrayBuffer((i=e.payload)===null||i===void 0?void 0:i.payload)?this._encodeBinaryUserBroadcastPush(e):this._encodeJsonUserBroadcastPush(e)}_encodeBinaryUserBroadcastPush(e){var i,a;const l=(a=(i=e.payload)===null||i===void 0?void 0:i.payload)!==null&&a!==void 0?a:new ArrayBuffer(0);return this._encodeUserBroadcastPush(e,this.BINARY_ENCODING,l)}_encodeJsonUserBroadcastPush(e){var i,a;const l=(a=(i=e.payload)===null||i===void 0?void 0:i.payload)!==null&&a!==void 0?a:{},u=new TextEncoder().encode(JSON.stringify(l)).buffer;return this._encodeUserBroadcastPush(e,this.JSON_ENCODING,u)}_encodeUserBroadcastPush(e,i,a){var l,c;const u=e.topic,d=(l=e.ref)!==null&&l!==void 0?l:"",m=(c=e.join_ref)!==null&&c!==void 0?c:"",p=e.payload.event,y=this.allowedMetadataKeys?this._pick(e.payload,this.allowedMetadataKeys):{},v=Object.keys(y).length===0?"":JSON.stringify(y);if(m.length>255)throw new Error(`joinRef length ${m.length} exceeds maximum of 255`);if(d.length>255)throw new Error(`ref length ${d.length} exceeds maximum of 255`);if(u.length>255)throw new Error(`topic length ${u.length} exceeds maximum of 255`);if(p.length>255)throw new Error(`userEvent length ${p.length} exceeds maximum of 255`);if(v.length>255)throw new Error(`metadata length ${v.length} exceeds maximum of 255`);const x=this.USER_BROADCAST_PUSH_META_LENGTH+m.length+d.length+u.length+p.length+v.length,_=new ArrayBuffer(this.HEADER_LENGTH+x);let S=new DataView(_),T=0;S.setUint8(T++,this.KINDS.userBroadcastPush),S.setUint8(T++,m.length),S.setUint8(T++,d.length),S.setUint8(T++,u.length),S.setUint8(T++,p.length),S.setUint8(T++,v.length),S.setUint8(T++,i),Array.from(m,k=>S.setUint8(T++,k.charCodeAt(0))),Array.from(d,k=>S.setUint8(T++,k.charCodeAt(0))),Array.from(u,k=>S.setUint8(T++,k.charCodeAt(0))),Array.from(p,k=>S.setUint8(T++,k.charCodeAt(0))),Array.from(v,k=>S.setUint8(T++,k.charCodeAt(0)));var j=new Uint8Array(_.byteLength+a.byteLength);return j.set(new Uint8Array(_),0),j.set(new Uint8Array(a),_.byteLength),j.buffer}decode(e,i){if(this._isArrayBuffer(e)){let a=this._binaryDecode(e);return i(a)}if(typeof e=="string"){const a=JSON.parse(e),[l,c,u,d,m]=a;return i({join_ref:l,ref:c,topic:u,event:d,payload:m})}return i({})}_binaryDecode(e){const i=new DataView(e),a=i.getUint8(0),l=new TextDecoder;switch(a){case this.KINDS.userBroadcast:return this._decodeUserBroadcast(e,i,l)}}_decodeUserBroadcast(e,i,a){const l=i.getUint8(1),c=i.getUint8(2),u=i.getUint8(3),d=i.getUint8(4);let m=this.HEADER_LENGTH+4;const p=a.decode(e.slice(m,m+l));m=m+l;const y=a.decode(e.slice(m,m+c));m=m+c;const v=a.decode(e.slice(m,m+u));m=m+u;const x=e.slice(m,e.byteLength),_=d===this.JSON_ENCODING?JSON.parse(a.decode(x)):x,S={type:this.BROADCAST_EVENT,event:y,payload:_};return u>0&&(S.meta=JSON.parse(v)),{join_ref:null,ref:null,topic:p,event:this.BROADCAST_EVENT,payload:S}}_isArrayBuffer(e){var i;return e instanceof ArrayBuffer||((i=e==null?void 0:e.constructor)===null||i===void 0?void 0:i.name)==="ArrayBuffer"}_pick(e,i){return!e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).filter(([a])=>i.includes(a)))}}var Qe;(function(n){n.abstime="abstime",n.bool="bool",n.date="date",n.daterange="daterange",n.float4="float4",n.float8="float8",n.int2="int2",n.int4="int4",n.int4range="int4range",n.int8="int8",n.int8range="int8range",n.json="json",n.jsonb="jsonb",n.money="money",n.numeric="numeric",n.oid="oid",n.reltime="reltime",n.text="text",n.time="time",n.timestamp="timestamp",n.timestamptz="timestamptz",n.timetz="timetz",n.tsrange="tsrange",n.tstzrange="tstzrange"})(Qe||(Qe={}));const Rb=(n,e,i={})=>{var a;const l=(a=i.skipTypes)!==null&&a!==void 0?a:[];return e?Object.keys(e).reduce((c,u)=>(c[u]=AN(u,n,e,l),c),{}):{}},AN=(n,e,i,a)=>{const l=e.find(d=>d.name===n),c=l==null?void 0:l.type,u=i[n];return c&&!a.includes(c)?yw(c,u):uf(u)},yw=(n,e)=>{if(n.charAt(0)==="_"){const i=n.slice(1,n.length);return kN(e,i)}switch(n){case Qe.bool:return jN(e);case Qe.float4:case Qe.float8:case Qe.int2:case Qe.int4:case Qe.int8:case Qe.numeric:case Qe.oid:return NN(e);case Qe.json:case Qe.jsonb:return RN(e);case Qe.timestamp:return CN(e);case Qe.abstime:case Qe.date:case Qe.daterange:case Qe.int4range:case Qe.int8range:case Qe.money:case Qe.reltime:case Qe.text:case Qe.time:case Qe.timestamptz:case Qe.timetz:case Qe.tsrange:case Qe.tstzrange:return uf(e);default:return uf(e)}},uf=n=>n,jN=n=>{switch(n){case"t":return!0;case"f":return!1;default:return n}},NN=n=>{if(typeof n=="string"){const e=parseFloat(n);if(!Number.isNaN(e))return e}return n},RN=n=>{if(typeof n=="string")try{return JSON.parse(n)}catch{return n}return n},kN=(n,e)=>{if(typeof n!="string")return n;const i=n.length-1,a=n[i];if(n[0]==="{"&&a==="}"){let c;const u=n.slice(1,i);try{c=JSON.parse("["+u+"]")}catch{c=u?u.split(","):[]}return c.map(d=>yw(e,d))}return n},CN=n=>typeof n=="string"?n.replace(" ","T"):n,bw=n=>{const e=new URL(n);return e.protocol=e.protocol.replace(/^ws/i,"http"),e.pathname=e.pathname.replace(/\/+$/,"").replace(/\/socket\/websocket$/i,"").replace(/\/socket$/i,"").replace(/\/websocket$/i,""),e.pathname===""||e.pathname==="/"?e.pathname="/api/broadcast":e.pathname=e.pathname+"/api/broadcast",e.href};var so=n=>typeof n=="function"?n:function(){return n},ON=typeof self<"u"?self:null,Da=typeof window<"u"?window:null,Qn=ON||Da||globalThis,DN="2.0.0",MN=1e4,BN=1e3,Wn={connecting:0,open:1,closing:2,closed:3},Jt={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},Ns={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},hf={longpoll:"longpoll",websocket:"websocket"},UN={complete:4},df="base64url.bearer.phx.",Ql=class{constructor(n,e,i,a){this.channel=n,this.event=e,this.payload=i||function(){return{}},this.receivedResp=null,this.timeout=a,this.timeoutTimer=null,this.recHooks=[],this.sent=!1,this.ref=void 0}resend(n){this.timeout=n,this.reset(),this.send()}send(){this.hasReceived("timeout")||(this.startTimeout(),this.sent=!0,this.channel.socket.push({topic:this.channel.topic,event:this.event,payload:this.payload(),ref:this.ref,join_ref:this.channel.joinRef()}))}receive(n,e){return this.hasReceived(n)&&e(this.receivedResp.response),this.recHooks.push({status:n,callback:e}),this}reset(){this.cancelRefEvent(),this.ref=null,this.refEvent=null,this.receivedResp=null,this.sent=!1}destroy(){this.cancelRefEvent(),this.cancelTimeout()}matchReceive({status:n,response:e,_ref:i}){this.recHooks.filter(a=>a.status===n).forEach(a=>a.callback(e))}cancelRefEvent(){this.refEvent&&this.channel.off(this.refEvent)}cancelTimeout(){clearTimeout(this.timeoutTimer),this.timeoutTimer=null}startTimeout(){this.timeoutTimer&&this.cancelTimeout(),this.ref=this.channel.socket.makeRef(),this.refEvent=this.channel.replyEventName(this.ref),this.channel.on(this.refEvent,n=>{this.cancelRefEvent(),this.cancelTimeout(),this.receivedResp=n,this.matchReceive(n)}),this.timeoutTimer=setTimeout(()=>{this.trigger("timeout",{})},this.timeout)}hasReceived(n){return this.receivedResp&&this.receivedResp.status===n}trigger(n,e){this.channel.trigger(this.refEvent,{status:n,response:e})}},vw=class{constructor(n,e){this.callback=n,this.timerCalc=e,this.timer=void 0,this.tries=0}reset(){this.tries=0,clearTimeout(this.timer)}scheduleTimeout(){clearTimeout(this.timer),this.timer=setTimeout(()=>{this.tries=this.tries+1,this.callback()},this.timerCalc(this.tries+1))}},LN=class{constructor(n,e,i){this.state=Jt.closed,this.topic=n,this.params=so(e||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new Ql(this,Ns.join,this.params,this.timeout),this.pushBuffer=[],this.stateChangeRefs=[],this.rejoinTimer=new vw(()=>{this.socket.isConnected()&&this.rejoin()},this.socket.rejoinAfterMs),this.stateChangeRefs.push(this.socket.onError(()=>this.rejoinTimer.reset())),this.stateChangeRefs.push(this.socket.onOpen(()=>{this.rejoinTimer.reset(),this.isErrored()&&this.rejoin()})),this.joinPush.receive("ok",()=>{this.state=Jt.joined,this.rejoinTimer.reset(),this.pushBuffer.forEach(a=>a.send()),this.pushBuffer=[]}),this.joinPush.receive("error",a=>{this.state=Jt.errored,this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,a),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.onClose(()=>{this.rejoinTimer.reset(),this.socket.hasLogger()&&this.socket.log("channel",`close ${this.topic}`),this.state=Jt.closed,this.socket.remove(this)}),this.onError(a=>{this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,a),this.isJoining()&&this.joinPush.reset(),this.state=Jt.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.joinPush.receive("timeout",()=>{this.socket.hasLogger()&&this.socket.log("channel",`timeout ${this.topic}`,this.joinPush.timeout),new Ql(this,Ns.leave,so({}),this.timeout).send(),this.state=Jt.errored,this.joinPush.reset(),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.on(Ns.reply,(a,l)=>{this.trigger(this.replyEventName(l),a)})}join(n=this.timeout){if(this.joinedOnce)throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");return this.timeout=n,this.joinedOnce=!0,this.rejoin(),this.joinPush}teardown(){this.pushBuffer.forEach(n=>n.destroy()),this.pushBuffer=[],this.rejoinTimer.reset(),this.joinPush.destroy(),this.state=Jt.closed,this.bindings=[]}onClose(n){this.on(Ns.close,n)}onError(n){return this.on(Ns.error,e=>n(e))}on(n,e){let i=this.bindingRef++;return this.bindings.push({event:n,ref:i,callback:e}),i}off(n,e){this.bindings=this.bindings.filter(i=>!(i.event===n&&(typeof e>"u"||e===i.ref)))}canPush(){return this.socket.isConnected()&&this.isJoined()}push(n,e,i=this.timeout){if(e=e||{},!this.joinedOnce)throw new Error(`tried to push '${n}' to '${this.topic}' before joining. Use channel.join() before pushing events`);let a=new Ql(this,n,function(){return e},i);return this.canPush()?a.send():(a.startTimeout(),this.pushBuffer.push(a)),a}leave(n=this.timeout){this.rejoinTimer.reset(),this.joinPush.cancelTimeout(),this.state=Jt.leaving;let e=()=>{this.socket.hasLogger()&&this.socket.log("channel",`leave ${this.topic}`),this.trigger(Ns.close,"leave")},i=new Ql(this,Ns.leave,so({}),n);return i.receive("ok",()=>e()).receive("timeout",()=>e()),i.send(),this.canPush()||i.trigger("ok",{}),i}onMessage(n,e,i){return e}filterBindings(n,e,i){return!0}isMember(n,e,i,a){return this.topic!==n?!1:a&&a!==this.joinRef()?(this.socket.hasLogger()&&this.socket.log("channel","dropping outdated message",{topic:n,event:e,payload:i,joinRef:a}),!1):!0}joinRef(){return this.joinPush.ref}rejoin(n=this.timeout){this.isLeaving()||(this.socket.leaveOpenTopic(this.topic),this.state=Jt.joining,this.joinPush.resend(n))}trigger(n,e,i,a){let l=this.onMessage(n,e,i,a);if(e&&!l)throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");let c=this.bindings.filter(u=>u.event===n&&this.filterBindings(u,e,i));for(let u=0;um.abort(),l),d.signal=m.signal),Qn.fetch(e,d).then(p=>p.text()).then(p=>this.parseJSON(p)).then(p=>u&&u(p)).catch(p=>{p.name==="AbortError"&&c?c():u&&u(null)}),m}static xdomainRequest(n,e,i,a,l,c,u){return n.timeout=l,n.open(e,i),n.onload=()=>{let d=this.parseJSON(n.responseText);u&&u(d)},c&&(n.ontimeout=c),n.onprogress=()=>{},n.send(a),n}static xhrRequest(n,e,i,a,l,c,u,d){n.open(e,i,!0),n.timeout=c;for(let[m,p]of Object.entries(a))n.setRequestHeader(m,p);return n.onerror=()=>d&&d(null),n.onreadystatechange=()=>{if(n.readyState===UN.complete&&d){let m=this.parseJSON(n.responseText);d(m)}},u&&(n.ontimeout=u),n.send(l),n}static parseJSON(n){if(!n||n==="")return null;try{return JSON.parse(n)}catch{return console&&console.log("failed to parse JSON response",n),null}}static serialize(n,e){let i=[];for(var a in n){if(!Object.prototype.hasOwnProperty.call(n,a))continue;let l=e?`${e}[${a}]`:a,c=n[a];typeof c=="object"?i.push(this.serialize(c,l)):i.push(encodeURIComponent(l)+"="+encodeURIComponent(c))}return i.join("&")}static appendParams(n,e){if(Object.keys(e).length===0)return n;let i=n.match(/\?/)?"&":"?";return`${n}${i}${this.serialize(e)}`}},zN=n=>{let e="",i=new Uint8Array(n),a=i.byteLength;for(let l=0;lthis.poll(),0)}normalizeEndpoint(n){return n.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+hf.websocket),"$1/"+hf.longpoll)}endpointURL(){return jc.appendParams(this.pollEndpoint,{token:this.token})}closeAndRetry(n,e,i){this.close(n,e,i),this.readyState=Wn.connecting}ontimeout(){this.onerror("timeout"),this.closeAndRetry(1005,"timeout",!1)}isActive(){return this.readyState===Wn.open||this.readyState===Wn.connecting}poll(){const n={Accept:"application/json"};this.authToken&&(n["X-Phoenix-AuthToken"]=this.authToken),this.ajax("GET",n,null,()=>this.ontimeout(),e=>{if(e){var{status:i,token:a,messages:l}=e;if(i===410&&this.token!==null){this.onerror(410),this.closeAndRetry(3410,"session_gone",!1);return}this.token=a}else i=0;switch(i){case 200:l.forEach(c=>{setTimeout(()=>this.onmessage({data:c}),0)}),this.poll();break;case 204:this.poll();break;case 410:this.readyState=Wn.open,this.onopen({}),this.poll();break;case 403:this.onerror(403),this.close(1008,"forbidden",!1);break;case 0:case 500:this.onerror(500),this.closeAndRetry(1011,"internal server error",500);break;default:throw new Error(`unhandled poll status ${i}`)}})}send(n){typeof n!="string"&&(n=zN(n)),this.currentBatch?this.currentBatch.push(n):this.awaitingBatchAck?this.batchBuffer.push(n):(this.currentBatch=[n],this.currentBatchTimer=setTimeout(()=>{this.batchSend(this.currentBatch),this.currentBatch=null},0))}batchSend(n){this.awaitingBatchAck=!0,this.ajax("POST",{"Content-Type":"application/x-ndjson"},n.join(` +`),()=>this.onerror("timeout"),e=>{this.awaitingBatchAck=!1,!e||e.status!==200?(this.onerror(e&&e.status),this.closeAndRetry(1011,"internal server error",!1)):this.batchBuffer.length>0&&(this.batchSend(this.batchBuffer),this.batchBuffer=[])})}close(n,e,i){for(let l of this.reqs)l.abort();this.readyState=Wn.closed;let a=Object.assign({code:1e3,reason:void 0,wasClean:!0},{code:n,reason:e,wasClean:i});this.batchBuffer=[],clearTimeout(this.currentBatchTimer),this.currentBatchTimer=null,typeof CloseEvent<"u"?this.onclose(new CloseEvent("close",a)):this.onclose(a)}ajax(n,e,i,a,l){let c,u=()=>{this.reqs.delete(c),a()};c=jc.request(n,this.endpointURL(),e,i,this.timeout,u,d=>{this.reqs.delete(c),this.isActive()&&l(d)}),this.reqs.add(c)}},PN=class Jr{constructor(e,i={}){let a=i.events||{state:"presence_state",diff:"presence_diff"};this.state={},this.pendingDiffs=[],this.channel=e,this.joinRef=null,this.caller={onJoin:function(){},onLeave:function(){},onSync:function(){}},this.channel.on(a.state,l=>{let{onJoin:c,onLeave:u,onSync:d}=this.caller;this.joinRef=this.channel.joinRef(),this.state=Jr.syncState(this.state,l,c,u),this.pendingDiffs.forEach(m=>{this.state=Jr.syncDiff(this.state,m,c,u)}),this.pendingDiffs=[],d()}),this.channel.on(a.diff,l=>{let{onJoin:c,onLeave:u,onSync:d}=this.caller;this.inPendingSyncState()?this.pendingDiffs.push(l):(this.state=Jr.syncDiff(this.state,l,c,u),d())})}onJoin(e){this.caller.onJoin=e}onLeave(e){this.caller.onLeave=e}onSync(e){this.caller.onSync=e}list(e){return Jr.list(this.state,e)}inPendingSyncState(){return!this.joinRef||this.joinRef!==this.channel.joinRef()}static syncState(e,i,a,l){let c=this.clone(e),u={},d={};return this.map(c,(m,p)=>{i[m]||(d[m]=p)}),this.map(i,(m,p)=>{let y=c[m];if(y){let v=p.metas.map(T=>T.phx_ref),x=y.metas.map(T=>T.phx_ref),_=p.metas.filter(T=>x.indexOf(T.phx_ref)<0),S=y.metas.filter(T=>v.indexOf(T.phx_ref)<0);_.length>0&&(u[m]=p,u[m].metas=_),S.length>0&&(d[m]=this.clone(y),d[m].metas=S)}else u[m]=p}),this.syncDiff(c,{joins:u,leaves:d},a,l)}static syncDiff(e,i,a,l){let{joins:c,leaves:u}=this.clone(i);return a||(a=function(){}),l||(l=function(){}),this.map(c,(d,m)=>{let p=e[d];if(e[d]=this.clone(m),p){let y=e[d].metas.map(x=>x.phx_ref),v=p.metas.filter(x=>y.indexOf(x.phx_ref)<0);e[d].metas.unshift(...v)}a(d,p,m)}),this.map(u,(d,m)=>{let p=e[d];if(!p)return;let y=m.metas.map(v=>v.phx_ref);p.metas=p.metas.filter(v=>y.indexOf(v.phx_ref)<0),l(d,p,m),p.metas.length===0&&delete e[d]}),e}static list(e,i){return i||(i=function(a,l){return l}),this.map(e,(a,l)=>i(a,l))}static map(e,i){return Object.getOwnPropertyNames(e).map(a=>i(a,e[a]))}static clone(e){return JSON.parse(JSON.stringify(e))}},Zl={HEADER_LENGTH:1,META_LENGTH:4,KINDS:{push:0,reply:1,broadcast:2},encode(n,e){if(n.payload.constructor===ArrayBuffer)return e(this.binaryEncode(n));{let i=[n.join_ref,n.ref,n.topic,n.event,n.payload];return e(JSON.stringify(i))}},decode(n,e){if(n.constructor===ArrayBuffer)return e(this.binaryDecode(n));{let[i,a,l,c,u]=JSON.parse(n);return e({join_ref:i,ref:a,topic:l,event:c,payload:u})}},binaryEncode(n){let{join_ref:e,ref:i,event:a,topic:l,payload:c}=n,u=this.META_LENGTH+e.length+i.length+l.length+a.length,d=new ArrayBuffer(this.HEADER_LENGTH+u),m=new DataView(d),p=0;m.setUint8(p++,this.KINDS.push),m.setUint8(p++,e.length),m.setUint8(p++,i.length),m.setUint8(p++,l.length),m.setUint8(p++,a.length),Array.from(e,v=>m.setUint8(p++,v.charCodeAt(0))),Array.from(i,v=>m.setUint8(p++,v.charCodeAt(0))),Array.from(l,v=>m.setUint8(p++,v.charCodeAt(0))),Array.from(a,v=>m.setUint8(p++,v.charCodeAt(0)));var y=new Uint8Array(d.byteLength+c.byteLength);return y.set(new Uint8Array(d),0),y.set(new Uint8Array(c),d.byteLength),y.buffer},binaryDecode(n){let e=new DataView(n),i=e.getUint8(0),a=new TextDecoder;switch(i){case this.KINDS.push:return this.decodePush(n,e,a);case this.KINDS.reply:return this.decodeReply(n,e,a);case this.KINDS.broadcast:return this.decodeBroadcast(n,e,a)}},decodePush(n,e,i){let a=e.getUint8(1),l=e.getUint8(2),c=e.getUint8(3),u=this.HEADER_LENGTH+this.META_LENGTH-1,d=i.decode(n.slice(u,u+a));u=u+a;let m=i.decode(n.slice(u,u+l));u=u+l;let p=i.decode(n.slice(u,u+c));u=u+c;let y=n.slice(u,n.byteLength);return{join_ref:d,ref:null,topic:m,event:p,payload:y}},decodeReply(n,e,i){let a=e.getUint8(1),l=e.getUint8(2),c=e.getUint8(3),u=e.getUint8(4),d=this.HEADER_LENGTH+this.META_LENGTH,m=i.decode(n.slice(d,d+a));d=d+a;let p=i.decode(n.slice(d,d+l));d=d+l;let y=i.decode(n.slice(d,d+c));d=d+c;let v=i.decode(n.slice(d,d+u));d=d+u;let x=n.slice(d,n.byteLength),_={status:v,response:x};return{join_ref:m,ref:p,topic:y,event:Ns.reply,payload:_}},decodeBroadcast(n,e,i){let a=e.getUint8(1),l=e.getUint8(2),c=this.HEADER_LENGTH+2,u=i.decode(n.slice(c,c+a));c=c+a;let d=i.decode(n.slice(c,c+l));c=c+l;let m=n.slice(c,n.byteLength);return{join_ref:null,ref:null,topic:u,event:d,payload:m}}},VN=class{constructor(n,e={}){this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.fallbackRef=null,this.timeout=e.timeout||MN,this.transport=e.transport||Qn.WebSocket||Ea,this.conn=void 0,this.primaryPassedHealthCheck=!1,this.longPollFallbackMs=e.longPollFallbackMs,this.fallbackTimer=null;let i=null;try{i=Qn&&Qn.sessionStorage}catch{}this.sessionStore=e.sessionStorage||i,this.establishedConnections=0,this.defaultEncoder=Zl.encode.bind(Zl),this.defaultDecoder=Zl.decode.bind(Zl),this.closeWasClean=!0,this.disconnecting=!1,this.binaryType=e.binaryType||"arraybuffer",this.connectClock=1,this.pageHidden=!1,this.encode=void 0,this.decode=void 0,this.transport!==Ea?(this.encode=e.encode||this.defaultEncoder,this.decode=e.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder);let a=null;Da&&Da.addEventListener&&(Da.addEventListener("pagehide",l=>{this.conn&&(this.disconnect(),a=this.connectClock)}),Da.addEventListener("pageshow",l=>{a===this.connectClock&&(a=null,this.connect())}),Da.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?this.pageHidden=!0:(this.pageHidden=!1,!this.isConnected()&&!this.closeWasClean&&this.teardown(()=>this.connect()))})),this.heartbeatIntervalMs=e.heartbeatIntervalMs||3e4,this.autoSendHeartbeat=e.autoSendHeartbeat??!0,this.heartbeatCallback=e.heartbeatCallback??(()=>{}),this.rejoinAfterMs=l=>e.rejoinAfterMs?e.rejoinAfterMs(l):[1e3,2e3,5e3][l-1]||1e4,this.reconnectAfterMs=l=>e.reconnectAfterMs?e.reconnectAfterMs(l):[10,50,100,150,200,250,500,1e3,2e3][l-1]||5e3,this.logger=e.logger||null,!this.logger&&e.debug&&(this.logger=(l,c,u)=>{console.log(`${l}: ${c}`,u)}),this.longpollerTimeout=e.longpollerTimeout||2e4,this.params=so(e.params||{}),this.endPoint=`${n}/${hf.websocket}`,this.vsn=e.vsn||DN,this.heartbeatTimeoutTimer=null,this.heartbeatTimer=null,this.heartbeatSentAt=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new vw(()=>{if(this.pageHidden){this.log("Not reconnecting as page is hidden!"),this.teardown();return}this.teardown(async()=>{e.beforeReconnect&&await e.beforeReconnect(),this.connect()})},this.reconnectAfterMs),this.authToken=e.authToken}getLongPollTransport(){return Ea}replaceTransport(n){this.connectClock++,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.conn&&(this.conn.close(),this.conn=null),this.transport=n}protocol(){return location.protocol.match(/^https/)?"wss":"ws"}endPointURL(){let n=jc.appendParams(jc.appendParams(this.endPoint,this.params()),{vsn:this.vsn});return n.charAt(0)!=="/"?n:n.charAt(1)==="/"?`${this.protocol()}:${n}`:`${this.protocol()}://${location.host}${n}`}disconnect(n,e,i){this.connectClock++,this.disconnecting=!0,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.teardown(()=>{this.disconnecting=!1,n&&n()},e,i)}connect(n){n&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=so(n)),!(this.conn&&!this.disconnecting)&&(this.longPollFallbackMs&&this.transport!==Ea?this.connectWithFallback(Ea,this.longPollFallbackMs):this.transportConnect())}log(n,e,i){this.logger&&this.logger(n,e,i)}hasLogger(){return this.logger!==null}onOpen(n){let e=this.makeRef();return this.stateChangeCallbacks.open.push([e,n]),e}onClose(n){let e=this.makeRef();return this.stateChangeCallbacks.close.push([e,n]),e}onError(n){let e=this.makeRef();return this.stateChangeCallbacks.error.push([e,n]),e}onMessage(n){let e=this.makeRef();return this.stateChangeCallbacks.message.push([e,n]),e}onHeartbeat(n){this.heartbeatCallback=n}ping(n){if(!this.isConnected())return!1;let e=this.makeRef(),i=Date.now();this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:e});let a=this.onMessage(l=>{l.ref===e&&(this.off([a]),n(Date.now()-i))});return!0}transportName(n){switch(n){case Ea:return"LongPoll";default:return n.name}}transportConnect(){this.connectClock++,this.closeWasClean=!1;let n;this.authToken&&(n=["phoenix",`${df}${btoa(this.authToken).replace(/=/g,"")}`]),this.conn=new this.transport(this.endPointURL(),n),this.conn.binaryType=this.binaryType,this.conn.timeout=this.longpollerTimeout,this.conn.onopen=()=>this.onConnOpen(),this.conn.onerror=e=>this.onConnError(e),this.conn.onmessage=e=>this.onConnMessage(e),this.conn.onclose=e=>this.onConnClose(e)}getSession(n){return this.sessionStore&&this.sessionStore.getItem(n)}storeSession(n,e){this.sessionStore&&this.sessionStore.setItem(n,e)}connectWithFallback(n,e=2500){clearTimeout(this.fallbackTimer);let i=!1,a=!0,l,c,u=this.transportName(n),d=m=>{this.log("transport",`falling back to ${u}...`,m),this.off([l,c]),a=!1,this.replaceTransport(n),this.transportConnect()};if(this.getSession(`phx:fallback:${u}`))return d("memorized");this.fallbackTimer=setTimeout(d,e),c=this.onError(m=>{this.log("transport","error",m),a&&!i&&(clearTimeout(this.fallbackTimer),d(m))}),this.fallbackRef&&this.off([this.fallbackRef]),this.fallbackRef=this.onOpen(()=>{if(i=!0,!a){let m=this.transportName(n);return this.primaryPassedHealthCheck||this.storeSession(`phx:fallback:${m}`,"true"),this.log("transport",`established ${m} fallback`)}clearTimeout(this.fallbackTimer),this.fallbackTimer=setTimeout(d,e),this.ping(m=>{this.log("transport","connected to primary after",m),this.primaryPassedHealthCheck=!0,clearTimeout(this.fallbackTimer)})}),this.transportConnect()}clearHeartbeats(){clearTimeout(this.heartbeatTimer),clearTimeout(this.heartbeatTimeoutTimer)}onConnOpen(){this.hasLogger()&&this.log("transport",`connected to ${this.endPointURL()}`),this.closeWasClean=!1,this.disconnecting=!1,this.establishedConnections++,this.flushSendBuffer(),this.reconnectTimer.reset(),this.autoSendHeartbeat&&this.resetHeartbeat(),this.triggerStateCallbacks("open")}heartbeatTimeout(){if(this.pendingHeartbeatRef){this.pendingHeartbeatRef=null,this.heartbeatSentAt=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection");try{this.heartbeatCallback("timeout")}catch(n){this.log("error","error in heartbeat callback",n)}this.triggerChanError(new Error("heartbeat timeout")),this.closeWasClean=!1,this.teardown(()=>this.reconnectTimer.scheduleTimeout(),BN,"heartbeat timeout")}}resetHeartbeat(){this.conn&&this.conn.skipHeartbeat||(this.pendingHeartbeatRef=null,this.clearHeartbeats(),this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}teardown(n,e,i){if(!this.conn)return n&&n();const a=this.conn;this.waitForBufferDone(a,()=>{e?a.close(e,i||""):a.close(),this.waitForSocketClosed(a,()=>{this.conn===a&&(this.conn.onopen=function(){},this.conn.onerror=function(){},this.conn.onmessage=function(){},this.conn.onclose=function(){},this.conn=null),n&&n()})})}waitForBufferDone(n,e,i=1){if(i===5||!n.bufferedAmount){e();return}setTimeout(()=>{this.waitForBufferDone(n,e,i+1)},150*i)}waitForSocketClosed(n,e,i=1){if(i===5||n.readyState===Wn.closed){e();return}setTimeout(()=>{this.waitForSocketClosed(n,e,i+1)},150*i)}onConnClose(n){this.conn&&(this.conn.onclose=()=>{}),this.hasLogger()&&this.log("transport","close",n),this.triggerChanError(n),this.clearHeartbeats(),this.closeWasClean||this.reconnectTimer.scheduleTimeout(),this.triggerStateCallbacks("close",n)}onConnError(n){this.hasLogger()&&this.log("transport","error",n);let e=this.transport,i=this.establishedConnections;this.triggerStateCallbacks("error",n,e,i),(e===this.transport||i>0)&&this.triggerChanError(n)}triggerChanError(n){this.channels.forEach(e=>{e.isErrored()||e.isLeaving()||e.isClosed()||e.trigger(Ns.error,n)})}connectionState(){switch(this.conn&&this.conn.readyState){case Wn.connecting:return"connecting";case Wn.open:return"open";case Wn.closing:return"closing";default:return"closed"}}isConnected(){return this.connectionState()==="open"}remove(n){this.off(n.stateChangeRefs),this.channels=this.channels.filter(e=>e!==n)}off(n){for(let e in this.stateChangeCallbacks)this.stateChangeCallbacks[e]=this.stateChangeCallbacks[e].filter(([i])=>n.indexOf(i)===-1)}channel(n,e={}){let i=new LN(n,e,this);return this.channels.push(i),i}push(n){if(this.hasLogger()){let{topic:e,event:i,payload:a,ref:l,join_ref:c}=n;this.log("push",`${e} ${i} (${c}, ${l})`,a)}this.isConnected()?this.encode(n,e=>this.conn.send(e)):this.sendBuffer.push(()=>this.encode(n,e=>this.conn.send(e)))}makeRef(){let n=this.ref+1;return n===this.ref?this.ref=0:this.ref=n,this.ref.toString()}sendHeartbeat(){if(!this.isConnected()){try{this.heartbeatCallback("disconnected")}catch(n){this.log("error","error in heartbeat callback",n)}return}if(this.pendingHeartbeatRef){this.heartbeatTimeout();return}this.pendingHeartbeatRef=this.makeRef(),this.heartbeatSentAt=Date.now(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef});try{this.heartbeatCallback("sent")}catch(n){this.log("error","error in heartbeat callback",n)}this.heartbeatTimeoutTimer=setTimeout(()=>this.heartbeatTimeout(),this.heartbeatIntervalMs)}flushSendBuffer(){this.isConnected()&&this.sendBuffer.length>0&&(this.sendBuffer.forEach(n=>n()),this.sendBuffer=[])}onConnMessage(n){this.decode(n.data,e=>{let{topic:i,event:a,payload:l,ref:c,join_ref:u}=e;if(c&&c===this.pendingHeartbeatRef){const d=this.heartbeatSentAt?Date.now()-this.heartbeatSentAt:void 0;this.clearHeartbeats();try{this.heartbeatCallback(l.status==="ok"?"ok":"error",d)}catch(m){this.log("error","error in heartbeat callback",m)}this.pendingHeartbeatRef=null,this.heartbeatSentAt=null,this.autoSendHeartbeat&&(this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}this.hasLogger()&&this.log("receive",`${l.status||""} ${i} ${a} ${c&&"("+c+")"||""}`.trim(),l);for(let d=0;d{try{a(...e)}catch(l){this.log("error",`error in ${n} callback`,l)}})}catch(i){this.log("error",`error triggering ${n} callbacks`,i)}}leaveOpenTopic(n){let e=this.channels.find(i=>i.topic===n&&(i.isJoined()||i.isJoining()));e&&(this.hasLogger()&&this.log("transport",`leaving duplicate topic "${n}"`),e.leave())}};class io{constructor(e,i){const a=$N(i);this.presence=new PN(e.getChannel(),a),this.presence.onJoin((l,c,u)=>{const d=io.onJoinPayload(l,c,u);e.getChannel().trigger("presence",d)}),this.presence.onLeave((l,c,u)=>{const d=io.onLeavePayload(l,c,u);e.getChannel().trigger("presence",d)}),this.presence.onSync(()=>{e.getChannel().trigger("presence",{event:"sync"})})}get state(){return io.transformState(this.presence.state)}static transformState(e){return e=HN(e),Object.getOwnPropertyNames(e).reduce((i,a)=>{const l=e[a];return i[a]=mc(l),i},{})}static onJoinPayload(e,i,a){const l=kb(i),c=mc(a);return{event:"join",key:e,currentPresences:l,newPresences:c}}static onLeavePayload(e,i,a){const l=kb(i),c=mc(a);return{event:"leave",key:e,currentPresences:l,leftPresences:c}}}function mc(n){return n.metas.map(e=>(e.presence_ref=e.phx_ref,delete e.phx_ref,delete e.phx_ref_prev,e))}function HN(n){return JSON.parse(JSON.stringify(n))}function $N(n){return(n==null?void 0:n.events)&&{events:n.events}}function kb(n){return n!=null&&n.metas?mc(n):[]}var Cb;(function(n){n.SYNC="sync",n.JOIN="join",n.LEAVE="leave"})(Cb||(Cb={}));class qN{get state(){return this.presenceAdapter.state}constructor(e,i){this.channel=e,this.presenceAdapter=new io(this.channel.channelAdapter,i)}}function FN(n){if(n instanceof Error)return n;if(typeof n=="string")return new Error(n);if(n&&typeof n=="object"){const e=n;if(typeof e.code=="number"){const i=typeof e.reason=="string"&&e.reason?` (${e.reason})`:"";return new Error(`socket closed: ${e.code}${i}`,{cause:n})}return new Error("channel error: transport failure",{cause:n})}return new Error("channel error: connection lost")}class IN{constructor(e,i,a){const l=GN(a);this.channel=e.getSocket().channel(i,l),this.socket=e}get state(){return this.channel.state}set state(e){this.channel.state=e}get joinedOnce(){return this.channel.joinedOnce}get joinPush(){return this.channel.joinPush}get rejoinTimer(){return this.channel.rejoinTimer}on(e,i){return this.channel.on(e,i)}off(e,i){this.channel.off(e,i)}subscribe(e){return this.channel.join(e)}unsubscribe(e){return this.channel.leave(e)}teardown(){this.channel.teardown()}onClose(e){this.channel.onClose(e)}onError(e){return this.channel.onError(e)}push(e,i,a){let l;try{l=this.channel.push(e,i,a)}catch{throw new Error(`tried to push '${e}' to '${this.channel.topic}' before joining. Use channel.subscribe() before pushing events`)}if(this.channel.pushBuffer.length>TN){const c=this.channel.pushBuffer.shift();c.cancelTimeout(),this.socket.log("channel",`discarded push due to buffer overflow: ${c.event}`,c.payload())}return l}updateJoinPayload(e){const i=this.channel.joinPush.payload();this.channel.joinPush.payload=()=>Object.assign(Object.assign({},i),e)}canPush(){return this.socket.isConnected()&&this.state===si.joined}isJoined(){return this.state===si.joined}isJoining(){return this.state===si.joining}isClosed(){return this.state===si.closed}isLeaving(){return this.state===si.leaving}updateFilterBindings(e){this.channel.filterBindings=e}updatePayloadTransform(e){this.channel.onMessage=e}getChannel(){return this.channel}}function GN(n){return{config:Object.assign({broadcast:{ack:!1,self:!1},presence:{key:"",enabled:!1},private:!1},n.config)}}const KN=/[,()"\\]/,YN=n=>KN.test(n)||n!==n.trim(),XN=n=>`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`,Ob=n=>{const e=n===null?"null":String(n);return YN(e)?XN(e):e},JN=n=>n===null?"null":String(n),QN=(n,e)=>{if(n==="in"){const i=Array.isArray(e)?e:[e];if(i.length===0)throw new Error("Realtime `in` filter requires at least one value.");return`in.(${Array.from(new Set(i)).map(l=>Ob(l)).join(",")})`}return n==="is"?`is.${JN(e)}`:`${n}.${Ob(e)}`};class ZN{constructor(){this.filters=[]}add(e,i,a,l=!1){const c=l?"not.":"";return this.filters.push(`${e}=${c}${QN(i,a)}`),this}eq(e,i){return this.add(e,"eq",i)}neq(e,i){return this.add(e,"neq",i)}gt(e,i){return this.add(e,"gt",i)}gte(e,i){return this.add(e,"gte",i)}lt(e,i){return this.add(e,"lt",i)}lte(e,i){return this.add(e,"lte",i)}in(e,i){return this.add(e,"in",i)}like(e,i){return this.add(e,"like",i)}ilike(e,i){return this.add(e,"ilike",i)}match(e,i){return this.add(e,"match",i)}imatch(e,i){return this.add(e,"imatch",i)}is(e,i){return this.add(e,"is",i)}isDistinct(e,i){return this.add(e,"isdistinct",i)}not(e,i,a){return this.add(e,i,a,!0)}build(){return this.filters.join(",")}toString(){return this.build()}}var Db;(function(n){n.ALL="*",n.INSERT="INSERT",n.UPDATE="UPDATE",n.DELETE="DELETE"})(Db||(Db={}));var Pa;(function(n){n.BROADCAST="broadcast",n.PRESENCE="presence",n.POSTGRES_CHANGES="postgres_changes",n.SYSTEM="system"})(Pa||(Pa={}));var Rs;(function(n){n.SUBSCRIBED="SUBSCRIBED",n.TIMED_OUT="TIMED_OUT",n.CLOSED="CLOSED",n.CHANNEL_ERROR="CHANNEL_ERROR"})(Rs||(Rs={}));class ao{get state(){return this.channelAdapter.state}set state(e){this.channelAdapter.state=e}get joinedOnce(){return this.channelAdapter.joinedOnce}get timeout(){return this.socket.timeout}get joinPush(){return this.channelAdapter.joinPush}get rejoinTimer(){return this.channelAdapter.rejoinTimer}constructor(e,i={config:{}},a){var l,c;if(this.topic=e,this.params=i,this.socket=a,this.bindings={},this.subTopic=e.replace(/^realtime:/i,""),this.params.config=Object.assign({broadcast:{ack:!1,self:!1},presence:{key:"",enabled:!1},private:!1},i.config),this.channelAdapter=new IN(this.socket.socketAdapter,e,this.params),this.presence=new qN(this),this._onClose(()=>{this.socket._remove(this)}),this._updateFilterTransform(),this.broadcastEndpointURL=bw(this.socket.socketAdapter.endPointURL()),this.private=this.params.config.private||!1,!this.private&&(!((c=(l=this.params.config)===null||l===void 0?void 0:l.broadcast)===null||c===void 0)&&c.replay))throw new Error(`tried to use replay on public channel '${this.topic}'. It must be a private channel.`)}subscribe(e,i=this.timeout){var a,l,c;if(this.socket.isConnected()||this.socket.connect(),this.channelAdapter.isClosed()){const{config:{broadcast:u,presence:d,private:m}}=this.params,p=(l=(a=this.bindings.postgres_changes)===null||a===void 0?void 0:a.map(_=>_.filter))!==null&&l!==void 0?l:[],y=!!this.bindings[Pa.PRESENCE]&&this.bindings[Pa.PRESENCE].length>0||((c=this.params.config.presence)===null||c===void 0?void 0:c.enabled)===!0,v={},x={broadcast:u,presence:Object.assign(Object.assign({},d),{enabled:y}),postgres_changes:p,private:m};this.socket.accessTokenValue&&(v.access_token=this.socket.accessTokenValue),this._onError(_=>{e==null||e(Rs.CHANNEL_ERROR,FN(_))}),this._onClose(()=>e==null?void 0:e(Rs.CLOSED)),this.updateJoinPayload(Object.assign({config:x},v)),this._updateFilterMessage(),this.channelAdapter.subscribe(i).receive("ok",async({postgres_changes:_})=>{if(this.socket._isManualToken()||this.socket.setAuth(),_===void 0){e==null||e(Rs.SUBSCRIBED);return}this._updatePostgresBindings(_,e)}).receive("error",_=>{this.state=si.errored;const S=Object.values(_).join(", ")||"error";e==null||e(Rs.CHANNEL_ERROR,new Error(S,{cause:_}))}).receive("timeout",()=>{e==null||e(Rs.TIMED_OUT)})}return this}_updatePostgresBindings(e,i){var a;const l=this.bindings.postgres_changes,c=(a=l==null?void 0:l.length)!==null&&a!==void 0?a:0,u=[];for(let d=0;d{var u,d,m;const p=this.channelAdapter.push(e.type,e,i.timeout||this.timeout);e.type==="broadcast"&&!(!((m=(d=(u=this.params)===null||u===void 0?void 0:u.config)===null||d===void 0?void 0:d.broadcast)===null||m===void 0)&&m.ack)&&c("ok"),p.receive("ok",()=>c("ok")),p.receive("error",()=>c("error")),p.receive("timeout",()=>c("timed out"))})}updateJoinPayload(e){this.channelAdapter.updateJoinPayload(e)}async unsubscribe(e=this.timeout){return new Promise(i=>{this.channelAdapter.unsubscribe(e).receive("ok",()=>i("ok")).receive("timeout",()=>i("timed out")).receive("error",()=>i("error"))})}teardown(){this.channelAdapter.teardown()}async _fetchWithTimeout(e,i,a){const l=new AbortController,c=setTimeout(()=>l.abort(),a),u=await this.socket.fetch(e,Object.assign(Object.assign({},i),{signal:l.signal}));return clearTimeout(c),u}_on(e,i,a){const l=e.toLocaleLowerCase(),c=i==null?void 0:i.filter;(c instanceof ZN||typeof c=="object"&&c!==null&&typeof c.build=="function")&&(i=Object.assign(Object.assign({},i),{filter:c.build()}));const u=this.channelAdapter.on(e,a),d={type:l,filter:i,callback:a,ref:u};return this.bindings[l]?this.bindings[l].push(d):this.bindings[l]=[d],this._updateFilterMessage(),this}_onClose(e){this.channelAdapter.onClose(e)}_onError(e){this.channelAdapter.onError(e)}_updateFilterMessage(){this.channelAdapter.updateFilterBindings((e,i,a)=>{var l,c,u,d,m,p,y;const v=e.event.toLocaleLowerCase();if(this._notThisChannelEvent(v,a))return!1;const x=(l=this.bindings[v])===null||l===void 0?void 0:l.find(_=>_.ref===e.ref);if(!x)return!0;if(["broadcast","presence","postgres_changes"].includes(v))if("id"in x){const _=x.id,S=(c=x.filter)===null||c===void 0?void 0:c.event;return _&&((u=i.ids)===null||u===void 0?void 0:u.includes(_))&&(S==="*"||(S==null?void 0:S.toLocaleLowerCase())===((d=i.data)===null||d===void 0?void 0:d.type.toLocaleLowerCase()))}else{const _=(p=(m=x==null?void 0:x.filter)===null||m===void 0?void 0:m.event)===null||p===void 0?void 0:p.toLocaleLowerCase();return _==="*"||_===((y=i==null?void 0:i.event)===null||y===void 0?void 0:y.toLocaleLowerCase())}else return x.type.toLocaleLowerCase()===v})}_notThisChannelEvent(e,i){const{close:a,error:l,leave:c,join:u}=gw;return i&&[a,l,c,u].includes(e)&&i!==this.joinPush.ref}_updateFilterTransform(){this.channelAdapter.updatePayloadTransform((e,i,a)=>{if(typeof i=="object"&&"ids"in i){const l=i.data,{schema:c,table:u,commit_timestamp:d,type:m,errors:p}=l;return Object.assign(Object.assign({},{schema:c,table:u,commit_timestamp:d,eventType:m,new:{},old:{},errors:p}),this._getPayloadRecords(l))}return i})}copyBindings(e){if(this.joinedOnce)throw new Error("cannot copy bindings into joined channel");for(const i in e.bindings)for(const a of e.bindings[i])this._on(a.type,a.filter,a.callback)}static isFilterValueEqual(e,i){return(e??void 0)===(i??void 0)}_getPayloadRecords(e){const i={new:{},old:{}};return(e.type==="INSERT"||e.type==="UPDATE")&&(i.new=Rb(e.columns,e.record)),(e.type==="UPDATE"||e.type==="DELETE")&&(i.old=Rb(e.columns,e.old_record)),i}}class WN{constructor(e,i){this.socket=new VN(e,i)}get timeout(){return this.socket.timeout}get endPoint(){return this.socket.endPoint}get transport(){return this.socket.transport}get heartbeatIntervalMs(){return this.socket.heartbeatIntervalMs}get heartbeatCallback(){return this.socket.heartbeatCallback}set heartbeatCallback(e){this.socket.heartbeatCallback=e}get heartbeatTimer(){return this.socket.heartbeatTimer}get pendingHeartbeatRef(){return this.socket.pendingHeartbeatRef}get reconnectTimer(){return this.socket.reconnectTimer}get vsn(){return this.socket.vsn}get encode(){return this.socket.encode}get decode(){return this.socket.decode}get reconnectAfterMs(){return this.socket.reconnectAfterMs}get sendBuffer(){return this.socket.sendBuffer}get stateChangeCallbacks(){return this.socket.stateChangeCallbacks}connect(){this.socket.connect()}disconnect(e,i,a,l=1e4){return new Promise(c=>{setTimeout(()=>c("timeout"),l),this.socket.disconnect(()=>{e(),c("ok")},i,a)})}push(e){this.socket.push(e)}log(e,i,a){this.socket.log(e,i,a)}makeRef(){return this.socket.makeRef()}onOpen(e){this.socket.onOpen(e)}onClose(e){this.socket.onClose(e)}onError(e){this.socket.onError(e)}onMessage(e){this.socket.onMessage(e)}isConnected(){return this.socket.isConnected()}isConnecting(){return this.socket.connectionState()==cf.connecting}isDisconnecting(){return this.socket.connectionState()==cf.closing}connectionState(){return this.socket.connectionState()}endPointURL(){return this.socket.endPointURL()}sendHeartbeat(){this.socket.sendHeartbeat()}getSocket(){return this.socket}}const Mb={HEARTBEAT_INTERVAL:25e3},eR=[1e3,2e3,5e3,1e4],tR=1e4;function nR(){const n=new Map;return{get length(){return n.size},clear(){n.clear()},getItem(e){return n.has(e)?n.get(e):null},key(e){var i;return(i=Array.from(n.keys())[e])!==null&&i!==void 0?i:null},removeItem(e){n.delete(e)},setItem(e,i){n.set(e,String(i))}}}function sR(){try{if(typeof globalThis<"u"&&globalThis.sessionStorage)return globalThis.sessionStorage}catch{}return nR()}const iR=` + addEventListener("message", (e) => { + if (e.data.event === "start") { + setInterval(() => postMessage({ event: "keepAlive" }), e.data.interval); + } + });`;class aR{get endPoint(){return this.socketAdapter.endPoint}get timeout(){return this.socketAdapter.timeout}get transport(){return this.socketAdapter.transport}get heartbeatCallback(){return this.socketAdapter.heartbeatCallback}get heartbeatIntervalMs(){return this.socketAdapter.heartbeatIntervalMs}get heartbeatTimer(){return this.worker?this._workerHeartbeatTimer:this.socketAdapter.heartbeatTimer}get pendingHeartbeatRef(){return this.worker?this._pendingWorkerHeartbeatRef:this.socketAdapter.pendingHeartbeatRef}get reconnectTimer(){return this.socketAdapter.reconnectTimer}get vsn(){return this.socketAdapter.vsn}get encode(){return this.socketAdapter.encode}get decode(){return this.socketAdapter.decode}get reconnectAfterMs(){return this.socketAdapter.reconnectAfterMs}get sendBuffer(){return this.socketAdapter.sendBuffer}get stateChangeCallbacks(){return this.socketAdapter.stateChangeCallbacks}constructor(e,i){var a;if(this.channels=new Array,this.accessTokenValue=null,this.accessToken=null,this.apiKey=null,this.httpEndpoint="",this.headers={},this.params={},this.ref=0,this.serializer=new EN,this._manuallySetToken=!1,this._authPromise=null,this._workerHeartbeatTimer=void 0,this._pendingWorkerHeartbeatRef=null,this._pendingDisconnectTimer=null,this._disconnectOnEmptyChannelsAfterMs=0,this._resolveFetch=c=>c?(...u)=>c(...u):(...u)=>fetch(...u),!(!((a=i==null?void 0:i.params)===null||a===void 0)&&a.apikey))throw new Error("API key is required to connect to Realtime");this.apiKey=i.params.apikey;const l=this._initializeOptions(i);this.socketAdapter=new WN(e,l),this.httpEndpoint=bw(e),this.fetch=this._resolveFetch(i==null?void 0:i.fetch)}connect(){if(!(this.isConnecting()||this.isDisconnecting()||this.isConnected())){this.accessToken&&!this._authPromise&&this._setAuthSafely("connect"),this._setupConnectionHandlers();try{this.socketAdapter.connect()}catch(e){const i=e.message;throw new Error(`WebSocket not available: ${i}`)}this._handleNodeJsRaceCondition()}}endpointURL(){return this.socketAdapter.endPointURL()}async disconnect(e,i){return this._cancelPendingDisconnect(),this.isDisconnecting()?"ok":await this.socketAdapter.disconnect(()=>{clearInterval(this._workerHeartbeatTimer),this._terminateWorker()},e,i)}getChannels(){return this.channels}async removeChannel(e){const i=await e.unsubscribe();return i==="ok"&&e.teardown(),i}async removeAllChannels(){const e=this.channels.map(async a=>{const l=await a.unsubscribe();return a.teardown(),l}),i=await Promise.all(e);return await this.disconnect(),i}log(e,i,a){this.socketAdapter.log(e,i,a)}connectionState(){return this.socketAdapter.connectionState()||cf.closed}isConnected(){return this.socketAdapter.isConnected()}isConnecting(){return this.socketAdapter.isConnecting()}isDisconnecting(){return this.socketAdapter.isDisconnecting()}channel(e,i={config:{}}){const a=`realtime:${e}`,l=this.getChannels().find(c=>c.topic===a);if(l)return l;{const c=new ao(`realtime:${e}`,i,this);return this._cancelPendingDisconnect(),this.channels.push(c),c}}push(e){this.socketAdapter.push(e)}async setAuth(e=null){this._authPromise=this._performAuth(e);try{await this._authPromise}finally{this._authPromise=null}}_isManualToken(){return this._manuallySetToken}async sendHeartbeat(){this.socketAdapter.sendHeartbeat()}onHeartbeat(e){this.socketAdapter.heartbeatCallback=this._wrapHeartbeatCallback(e)}_makeRef(){return this.socketAdapter.makeRef()}_remove(e){this.channels=this.channels.filter(i=>i.topic!==e.topic),this.channels.length===0&&(this.log("transport","no channels remaining, scheduling disconnect"),this._schedulePendingDisconnect())}_schedulePendingDisconnect(){if(this._cancelPendingDisconnect(),this._disconnectOnEmptyChannelsAfterMs===0){this.log("transport","disconnecting immediately - no channels"),this.disconnect();return}this._pendingDisconnectTimer=setTimeout(()=>{this._pendingDisconnectTimer=null,this.channels.length===0&&(this.log("transport","deferred disconnect fired - no channels, disconnecting"),this.disconnect())},this._disconnectOnEmptyChannelsAfterMs),this.log("transport",`deferred disconnect scheduled in ${this._disconnectOnEmptyChannelsAfterMs}ms`)}_cancelPendingDisconnect(){this._pendingDisconnectTimer!==null&&(this.log("transport","pending disconnect cancelled - channel activity detected"),clearTimeout(this._pendingDisconnectTimer),this._pendingDisconnectTimer=null)}async _performAuth(e=null){let i,a=!1;if(e)i=e,a=!0;else if(this.accessToken)try{i=await this.accessToken()}catch(l){this.log("error","Error fetching access token from callback",l),i=this.accessTokenValue}else i=this.accessTokenValue;a?this._manuallySetToken=!0:this.accessToken&&(this._manuallySetToken=!1),this.accessTokenValue!=i&&(this.accessTokenValue=i,this.channels.forEach(l=>{const c={access_token:i,version:xN};i&&l.updateJoinPayload(c),l.joinedOnce&&l.channelAdapter.isJoined()&&l.channelAdapter.push(gw.access_token,{access_token:i})}))}async _waitForAuthIfNeeded(){this._authPromise&&await this._authPromise}_setAuthSafely(e="general"){this._isManualToken()||this.setAuth().catch(i=>{this.log("error",`Error setting auth in ${e}`,i)})}_setupConnectionHandlers(){this.socketAdapter.onOpen(()=>{(this._authPromise||(this.accessToken&&!this.accessTokenValue?this.setAuth():Promise.resolve())).catch(i=>{this.log("error","error waiting for auth on connect",i)}),this.worker&&!this.workerRef&&this._startWorkerHeartbeat()}),this.socketAdapter.onClose(()=>{this.worker&&this.workerRef&&this._terminateWorker()}),this.socketAdapter.onMessage(e=>{e.ref&&e.ref===this._pendingWorkerHeartbeatRef&&(this._pendingWorkerHeartbeatRef=null)})}_handleNodeJsRaceCondition(){this.socketAdapter.isConnected()&&this.socketAdapter.getSocket().onConnOpen()}_wrapHeartbeatCallback(e){return(i,a)=>{i!=="disconnected"&&(i=="sent"&&this._setAuthSafely(),e&&e(i,a))}}_startWorkerHeartbeat(){this.workerUrl?this.log("worker",`starting worker for from ${this.workerUrl}`):this.log("worker","starting default worker");const e=this._workerObjectUrl(this.workerUrl);this.workerRef=new Worker(e),this.workerRef.onerror=i=>{this.log("worker","worker error",i.message),this._terminateWorker(),this.disconnect()},this.workerRef.onmessage=i=>{i.data.event==="keepAlive"&&this.sendHeartbeat()},this.workerRef.postMessage({event:"start",interval:this.heartbeatIntervalMs})}_terminateWorker(){this.workerRef&&(this.log("worker","terminating worker"),this.workerRef.terminate(),this.workerRef=void 0)}_workerObjectUrl(e){let i;if(e)i=e;else{const a=new Blob([iR],{type:"application/javascript"});i=URL.createObjectURL(a)}return i}_initializeOptions(e){var i,a,l,c,u,d,m,p,y,v,x,_;this.worker=(i=e==null?void 0:e.worker)!==null&&i!==void 0?i:!1,this.accessToken=(a=e==null?void 0:e.accessToken)!==null&&a!==void 0?a:null;const S={};S.timeout=(l=e==null?void 0:e.timeout)!==null&&l!==void 0?l:SN,S.heartbeatIntervalMs=(c=e==null?void 0:e.heartbeatIntervalMs)!==null&&c!==void 0?c:Mb.HEARTBEAT_INTERVAL,this._disconnectOnEmptyChannelsAfterMs=(u=e==null?void 0:e.disconnectOnEmptyChannelsAfterMs)!==null&&u!==void 0?u:2*((d=e==null?void 0:e.heartbeatIntervalMs)!==null&&d!==void 0?d:Mb.HEARTBEAT_INTERVAL),S.transport=(m=e==null?void 0:e.transport)!==null&&m!==void 0?m:bN.getWebSocketConstructor(),S.params=e==null?void 0:e.params,S.logger=e==null?void 0:e.logger,S.heartbeatCallback=this._wrapHeartbeatCallback(e==null?void 0:e.heartbeatCallback),S.sessionStorage=(p=e==null?void 0:e.sessionStorage)!==null&&p!==void 0?p:sR(),S.reconnectAfterMs=(y=e==null?void 0:e.reconnectAfterMs)!==null&&y!==void 0?y:(M=>eR[M-1]||tR);let T,j;const k=(v=e==null?void 0:e.vsn)!==null&&v!==void 0?v:_N;switch(k){case wN:T=(M,C)=>C(JSON.stringify(M)),j=(M,C)=>C(JSON.parse(M));break;case pw:T=this.serializer.encode.bind(this.serializer),j=this.serializer.decode.bind(this.serializer);break;default:throw new Error(`Unsupported serializer version: ${S.vsn}`)}if(S.vsn=k,S.encode=(x=e==null?void 0:e.encode)!==null&&x!==void 0?x:T,S.decode=(_=e==null?void 0:e.decode)!==null&&_!==void 0?_:j,S.beforeReconnect=this._reconnectAuth.bind(this),(e!=null&&e.logLevel||e!=null&&e.log_level)&&(this.logLevel=e.logLevel||e.log_level,S.params=Object.assign(Object.assign({},S.params),{log_level:this.logLevel})),this.worker){if(typeof window<"u"&&!window.Worker)throw new Error("Web Worker is not supported");this.workerUrl=e==null?void 0:e.workerUrl,S.autoSendHeartbeat=!this.worker}return S}async _reconnectAuth(){await this._waitForAuthIfNeeded(),this.isConnected()||this.connect()}}var fo=class extends Error{constructor(n,e){var i;super(n),this.name="IcebergError",this.status=e.status,this.icebergType=e.icebergType,this.icebergCode=e.icebergCode,this.details=e.details,this.isCommitStateUnknown=e.icebergType==="CommitStateUnknownException"||[500,502,504].includes(e.status)&&((i=e.icebergType)==null?void 0:i.includes("CommitState"))===!0}isNotFound(){return this.status===404}isConflict(){return this.status===409}isAuthenticationTimeout(){return this.status===419}};function rR(n,e,i){const a=new URL(e,n);if(i)for(const[l,c]of Object.entries(i))c!==void 0&&a.searchParams.set(l,c);return a.toString()}async function oR(n){return!n||n.type==="none"?{}:n.type==="bearer"?{Authorization:`Bearer ${n.token}`}:n.type==="header"?{[n.name]:n.value}:n.type==="custom"?await n.getHeaders():{}}function lR(n){const e=n.fetchImpl??globalThis.fetch;return{async request({method:i,path:a,query:l,body:c,headers:u}){const d=rR(n.baseUrl,a,l),m=await oR(n.auth),p=await e(d,{method:i,headers:{...c?{"Content-Type":"application/json"}:{},...m,...u},body:c?JSON.stringify(c):void 0}),y=await p.text(),v=(p.headers.get("content-type")||"").includes("application/json"),x=v&&y?JSON.parse(y):y;if(!p.ok){const _=v?x:void 0,S=_==null?void 0:_.error;throw new fo((S==null?void 0:S.message)??`Request failed with status ${p.status}`,{status:p.status,icebergType:S==null?void 0:S.type,icebergCode:S==null?void 0:S.code,details:_})}return{status:p.status,headers:p.headers,data:x}}}}function Wl(n){return n.join("")}var cR=class{constructor(n,e=""){this.client=n,this.prefix=e}async listNamespaces(n){const e=n?{parent:Wl(n.namespace)}:void 0;return(await this.client.request({method:"GET",path:`${this.prefix}/namespaces`,query:e})).data.namespaces.map(a=>({namespace:a}))}async createNamespace(n,e){const i={namespace:n.namespace,properties:e==null?void 0:e.properties};return(await this.client.request({method:"POST",path:`${this.prefix}/namespaces`,body:i})).data}async dropNamespace(n){await this.client.request({method:"DELETE",path:`${this.prefix}/namespaces/${Wl(n.namespace)}`})}async loadNamespaceMetadata(n){return{properties:(await this.client.request({method:"GET",path:`${this.prefix}/namespaces/${Wl(n.namespace)}`})).data.properties}}async namespaceExists(n){try{return await this.client.request({method:"HEAD",path:`${this.prefix}/namespaces/${Wl(n.namespace)}`}),!0}catch(e){if(e instanceof fo&&e.status===404)return!1;throw e}}async createNamespaceIfNotExists(n,e){try{return await this.createNamespace(n,e)}catch(i){if(i instanceof fo&&i.status===409)return;throw i}}};function Aa(n){return n.join("")}var uR=class{constructor(n,e="",i){this.client=n,this.prefix=e,this.accessDelegation=i}async listTables(n){return(await this.client.request({method:"GET",path:`${this.prefix}/namespaces/${Aa(n.namespace)}/tables`})).data.identifiers}async createTable(n,e){const i={};return this.accessDelegation&&(i["X-Iceberg-Access-Delegation"]=this.accessDelegation),(await this.client.request({method:"POST",path:`${this.prefix}/namespaces/${Aa(n.namespace)}/tables`,body:e,headers:i})).data.metadata}async updateTable(n,e){const i=await this.client.request({method:"POST",path:`${this.prefix}/namespaces/${Aa(n.namespace)}/tables/${n.name}`,body:e});return{"metadata-location":i.data["metadata-location"],metadata:i.data.metadata}}async dropTable(n,e){await this.client.request({method:"DELETE",path:`${this.prefix}/namespaces/${Aa(n.namespace)}/tables/${n.name}`,query:{purgeRequested:String((e==null?void 0:e.purge)??!1)}})}async loadTable(n){const e={};return this.accessDelegation&&(e["X-Iceberg-Access-Delegation"]=this.accessDelegation),(await this.client.request({method:"GET",path:`${this.prefix}/namespaces/${Aa(n.namespace)}/tables/${n.name}`,headers:e})).data.metadata}async tableExists(n){const e={};this.accessDelegation&&(e["X-Iceberg-Access-Delegation"]=this.accessDelegation);try{return await this.client.request({method:"HEAD",path:`${this.prefix}/namespaces/${Aa(n.namespace)}/tables/${n.name}`,headers:e}),!0}catch(i){if(i instanceof fo&&i.status===404)return!1;throw i}}async createTableIfNotExists(n,e){try{return await this.createTable(n,e)}catch(i){if(i instanceof fo&&i.status===409)return await this.loadTable({namespace:n.namespace,name:e.name});throw i}}},hR=class{constructor(n){var a;let e="v1";n.catalogName&&(e+=`/${n.catalogName}`);const i=n.baseUrl.endsWith("/")?n.baseUrl:`${n.baseUrl}/`;this.client=lR({baseUrl:i,auth:n.auth,fetchImpl:n.fetch}),this.accessDelegation=(a=n.accessDelegation)==null?void 0:a.join(","),this.namespaceOps=new cR(this.client,e),this.tableOps=new uR(this.client,e,this.accessDelegation)}async listNamespaces(n){return this.namespaceOps.listNamespaces(n)}async createNamespace(n,e){return this.namespaceOps.createNamespace(n,e)}async dropNamespace(n){await this.namespaceOps.dropNamespace(n)}async loadNamespaceMetadata(n){return this.namespaceOps.loadNamespaceMetadata(n)}async listTables(n){return this.tableOps.listTables(n)}async createTable(n,e){return this.tableOps.createTable(n,e)}async updateTable(n,e){return this.tableOps.updateTable(n,e)}async dropTable(n,e){await this.tableOps.dropTable(n,e)}async loadTable(n){return this.tableOps.loadTable(n)}async namespaceExists(n){return this.namespaceOps.namespaceExists(n)}async tableExists(n){return this.tableOps.tableExists(n)}async createNamespaceIfNotExists(n,e){return this.namespaceOps.createNamespaceIfNotExists(n,e)}async createTableIfNotExists(n,e){return this.tableOps.createTableIfNotExists(n,e)}};function mo(n){"@babel/helpers - typeof";return mo=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},mo(n)}function dR(n,e){if(mo(n)!="object"||!n)return n;var i=n[Symbol.toPrimitive];if(i!==void 0){var a=i.call(n,e);if(mo(a)!="object")return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(n)}function fR(n){var e=dR(n,"string");return mo(e)=="symbol"?e:e+""}function mR(n,e,i){return(e=fR(e))in n?Object.defineProperty(n,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):n[e]=i,n}function Bb(n,e){var i=Object.keys(n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(n);e&&(a=a.filter(function(l){return Object.getOwnPropertyDescriptor(n,l).enumerable})),i.push.apply(i,a)}return i}function fe(n){for(var e=1;en?(...e)=>n(...e):(...e)=>fetch(...e),yR=n=>{if(typeof n!="object"||n===null)return!1;const e=Object.getPrototypeOf(n);return(e===null||e===Object.prototype||Object.getPrototypeOf(e)===null)&&!(Symbol.toStringTag in n)&&!(Symbol.iterator in n)},mf=n=>{if(Array.isArray(n))return n.map(i=>mf(i));if(typeof n=="function"||n!==Object(n))return n;const e={};return Object.entries(n).forEach(([i,a])=>{const l=i.replace(/([-_][a-z])/gi,c=>c.toUpperCase().replace(/[-_]/g,""));e[l]=mf(a)}),e},bR=n=>!n||typeof n!="string"||n.length===0||n.length>100||n.trim()!==n||n.includes("/")||n.includes("\\")?!1:/^[\w!.\*'() &$@=;:+,?-]+$/.test(n),Ub=n=>{if(typeof n=="object"&&n!==null){const e=n;if(typeof e.msg=="string")return e.msg;if(typeof e.message=="string")return e.message;if(typeof e.error_description=="string")return e.error_description;if(typeof e.error=="string")return e.error;if(typeof e.error=="object"&&e.error!==null){const i=e.error;if(typeof i.message=="string")return i.message}}return JSON.stringify(n)},vR=async(n,e,i,a)=>{if(n!==null&&typeof n=="object"&&"json"in n&&typeof n.json=="function"){const l=n;let c=parseInt(String(l.status),10);Number.isFinite(c)||(c=500),l.json().then(u=>{const d=(u==null?void 0:u.statusCode)||(u==null?void 0:u.code)||c+"";e(new ff(Ub(u),c,d,a))}).catch(()=>{const u=c+"";e(new ff(l.statusText||`HTTP ${c} error`,c,u,a))})}else e(new xw(Ub(n),n,a))},xR=(n,e,i,a)=>{const l={method:n,headers:(e==null?void 0:e.headers)||{}};if(n==="GET"||n==="HEAD"||!a)return fe(fe({},l),i);if(yR(a)){var c;const u=(e==null?void 0:e.headers)||{};let d;for(const[m,p]of Object.entries(u))m.toLowerCase()==="content-type"&&(d=p);l.headers=Nc(u,"Content-Type",(c=d)!==null&&c!==void 0?c:"application/json"),l.body=JSON.stringify(a)}else l.body=a;return e!=null&&e.duplex&&(l.duplex=e.duplex),fe(fe({},l),i)};async function Gr(n,e,i,a,l,c,u){return new Promise((d,m)=>{n(i,xR(e,a,l,c)).then(p=>{if(!p.ok)throw p;if(a!=null&&a.noResolveJson)return p;if(u==="vectors"){const y=p.headers.get("content-type");if(p.headers.get("content-length")==="0"||p.status===204)return{};if(!y||!y.includes("application/json"))return{}}return p.json()}).then(p=>d(p)).catch(p=>vR(p,m,a,u))})}function ww(n="storage"){return{get:async(e,i,a,l)=>Gr(e,"GET",i,a,l,void 0,n),post:async(e,i,a,l,c)=>Gr(e,"POST",i,l,c,a,n),put:async(e,i,a,l,c)=>Gr(e,"PUT",i,l,c,a,n),head:async(e,i,a,l)=>Gr(e,"HEAD",i,fe(fe({},a),{},{noResolveJson:!0}),l,void 0,n),remove:async(e,i,a,l,c)=>Gr(e,"DELETE",i,l,c,a,n)}}const wR=ww("storage"),{get:po,post:Pn,put:pf,head:_R,remove:go}=wR,on=ww("vectors");var Ja=class{constructor(n,e={},i,a="storage"){this.shouldThrowOnError=!1,this.url=n,this.headers=pR(e),this.fetch=gR(i),this.namespace=a}throwOnError(){return this.shouldThrowOnError=!0,this}setHeader(n,e){return this.headers=Nc(this.headers,n,e),this}async handleOperation(n){var e=this;try{return{data:await n(),error:null}}catch(i){if(e.shouldThrowOnError)throw i;if(qc(i))return{data:null,error:i};throw i}}};let _w;_w=Symbol.toStringTag;var SR=class{constructor(n,e){this.downloadFn=n,this.shouldThrowOnError=e,this[_w]="StreamDownloadBuilder",this.promise=null}then(n,e){return this.getPromise().then(n,e)}catch(n){return this.getPromise().catch(n)}finally(n){return this.getPromise().finally(n)}getPromise(){return this.promise||(this.promise=this.execute()),this.promise}async execute(){var n=this;try{return{data:(await n.downloadFn()).body,error:null}}catch(e){if(n.shouldThrowOnError)throw e;if(qc(e))return{data:null,error:e};throw e}}};let Sw;Sw=Symbol.toStringTag;var TR=class{constructor(n,e){this.downloadFn=n,this.shouldThrowOnError=e,this[Sw]="BlobDownloadBuilder",this.promise=null}asStream(){return new SR(this.downloadFn,this.shouldThrowOnError)}then(n,e){return this.getPromise().then(n,e)}catch(n){return this.getPromise().catch(n)}finally(n){return this.getPromise().finally(n)}getPromise(){return this.promise||(this.promise=this.execute()),this.promise}async execute(){var n=this;try{return{data:await(await n.downloadFn()).blob(),error:null}}catch(e){if(n.shouldThrowOnError)throw e;if(qc(e))return{data:null,error:e};throw e}}};const Sd={limit:100,offset:0,sortBy:{column:"name",order:"asc"}},Lb={cacheControl:"3600",contentType:"text/plain;charset=UTF-8",upsert:!1};var ER=class extends Ja{constructor(n,e={},i,a){super(n,e,a,"storage"),this.bucketId=i}async uploadOrUpdate(n,e,i,a){var l=this;return l.handleOperation(async()=>{let c;const u=fe(fe({},Lb),a);let d=fe(fe({},l.headers),n==="POST"&&{"x-upsert":String(u.upsert)});const m=u.metadata;if(typeof Blob<"u"&&i instanceof Blob?(c=new FormData,c.append("cacheControl",u.cacheControl),m&&c.append("metadata",l.encodeMetadata(m)),c.append("",i)):typeof FormData<"u"&&i instanceof FormData?(c=i,c.has("cacheControl")||c.append("cacheControl",u.cacheControl),m&&!c.has("metadata")&&c.append("metadata",l.encodeMetadata(m))):(c=i,d["cache-control"]=`max-age=${u.cacheControl}`,d["content-type"]=u.contentType,m&&(d["x-metadata"]=l.toBase64(l.encodeMetadata(m))),(typeof ReadableStream<"u"&&c instanceof ReadableStream||c&&typeof c=="object"&&"pipe"in c&&typeof c.pipe=="function")&&!u.duplex&&(u.duplex="half")),a!=null&&a.headers)for(const[x,_]of Object.entries(a.headers))d=Nc(d,x,_);const p=l._removeEmptyFolders(e),y=l._getFinalPath(p),v=await(n=="PUT"?pf:Pn)(l.fetch,`${l.url}/object/${y}`,c,fe({headers:d},u!=null&&u.duplex?{duplex:u.duplex}:{}));return{path:p,id:v.Id,fullPath:v.Key}})}async upload(n,e,i){return this.uploadOrUpdate("POST",n,e,i)}async uploadToSignedUrl(n,e,i,a){var l=this;const c=l._removeEmptyFolders(n),u=l._getFinalPath(c),d=new URL(l.url+`/object/upload/sign/${u}`);return d.searchParams.set("token",e),l.handleOperation(async()=>{let m;const p=fe(fe({},Lb),a);let y=fe(fe({},l.headers),{"x-upsert":String(p.upsert)});const v=p.metadata;if(typeof Blob<"u"&&i instanceof Blob?(m=new FormData,m.append("cacheControl",p.cacheControl),v&&m.append("metadata",l.encodeMetadata(v)),m.append("",i)):typeof FormData<"u"&&i instanceof FormData?(m=i,m.has("cacheControl")||m.append("cacheControl",p.cacheControl),v&&!m.has("metadata")&&m.append("metadata",l.encodeMetadata(v))):(m=i,y["cache-control"]=`max-age=${p.cacheControl}`,y["content-type"]=p.contentType,v&&(y["x-metadata"]=l.toBase64(l.encodeMetadata(v))),(typeof ReadableStream<"u"&&m instanceof ReadableStream||m&&typeof m=="object"&&"pipe"in m&&typeof m.pipe=="function")&&!p.duplex&&(p.duplex="half")),a!=null&&a.headers)for(const[x,_]of Object.entries(a.headers))y=Nc(y,x,_);return{path:c,fullPath:(await pf(l.fetch,d.toString(),m,fe({headers:y},p!=null&&p.duplex?{duplex:p.duplex}:{}))).Key}})}async createSignedUploadUrl(n,e){var i=this;return i.handleOperation(async()=>{let a=i._getFinalPath(n);const l=fe({},i.headers);e!=null&&e.upsert&&(l["x-upsert"]="true");const c=await Pn(i.fetch,`${i.url}/object/upload/sign/${a}`,{},{headers:l}),u=new URL(i.url+c.url),d=u.searchParams.get("token");if(!d)throw new $c("No token returned by API");return{signedUrl:u.toString(),path:n,token:d}})}async update(n,e,i){return this.uploadOrUpdate("PUT",n,e,i)}async move(n,e,i){var a=this;return a.handleOperation(async()=>await Pn(a.fetch,`${a.url}/object/move`,{bucketId:a.bucketId,sourceKey:n,destinationKey:e,destinationBucket:i==null?void 0:i.destinationBucket},{headers:a.headers}))}async copy(n,e,i){var a=this;return a.handleOperation(async()=>({path:(await Pn(a.fetch,`${a.url}/object/copy`,{bucketId:a.bucketId,sourceKey:n,destinationKey:e,destinationBucket:i==null?void 0:i.destinationBucket},{headers:a.headers})).Key}))}async createSignedUrl(n,e,i){var a=this;return a.handleOperation(async()=>{let l=a._getFinalPath(n);const c=typeof(i==null?void 0:i.transform)=="object"&&i.transform!==null&&Object.keys(i.transform).length>0;let u=await Pn(a.fetch,`${a.url}/object/sign/${l}`,fe({expiresIn:e},c?{transform:i.transform}:{}),{headers:a.headers});const d=new URLSearchParams;i!=null&&i.download&&d.set("download",i.download===!0?"":i.download),(i==null?void 0:i.cacheNonce)!=null&&d.set("cacheNonce",String(i.cacheNonce));const m=d.toString();return{signedUrl:encodeURI(`${a.url}${u.signedURL}${m?`&${m}`:""}`)}})}async createSignedUrls(n,e,i){var a=this;return a.handleOperation(async()=>{const l=await Pn(a.fetch,`${a.url}/object/sign/${a.bucketId}`,{expiresIn:e,paths:n},{headers:a.headers}),c=new URLSearchParams;i!=null&&i.download&&c.set("download",i.download===!0?"":i.download),(i==null?void 0:i.cacheNonce)!=null&&c.set("cacheNonce",String(i.cacheNonce));const u=c.toString();return l.map(d=>fe(fe({},d),{},{signedUrl:d.signedURL?encodeURI(`${a.url}${d.signedURL}${u?`&${u}`:""}`):null}))})}download(n,e,i){const a=typeof(e==null?void 0:e.transform)=="object"&&e.transform!==null&&Object.keys(e.transform).length>0?"render/image/authenticated":"object",l=new URLSearchParams;e!=null&&e.transform&&this.applyTransformOptsToQuery(l,e.transform),(e==null?void 0:e.cacheNonce)!=null&&l.set("cacheNonce",String(e.cacheNonce));const c=l.toString(),u=this._getFinalPath(n),d=()=>po(this.fetch,`${this.url}/${a}/${u}${c?`?${c}`:""}`,{headers:this.headers,noResolveJson:!0},i);return new TR(d,this.shouldThrowOnError)}async info(n){var e=this;const i=e._getFinalPath(n);return e.handleOperation(async()=>mf(await po(e.fetch,`${e.url}/object/info/${i}`,{headers:e.headers})))}async exists(n){var e=this;const i=e._getFinalPath(n);try{return await _R(e.fetch,`${e.url}/object/${i}`,{headers:e.headers}),{data:!0,error:null}}catch(l){if(e.shouldThrowOnError)throw l;if(qc(l)){var a;const c=l instanceof ff?l.status:l instanceof xw?(a=l.originalError)===null||a===void 0?void 0:a.status:void 0;if(c!==void 0&&[400,404].includes(c))return{data:!1,error:l}}throw l}}getPublicUrl(n,e){const i=this._getFinalPath(n),a=new URLSearchParams;e!=null&&e.download&&a.set("download",e.download===!0?"":e.download),e!=null&&e.transform&&this.applyTransformOptsToQuery(a,e.transform),(e==null?void 0:e.cacheNonce)!=null&&a.set("cacheNonce",String(e.cacheNonce));const l=a.toString(),c=typeof(e==null?void 0:e.transform)=="object"&&e.transform!==null&&Object.keys(e.transform).length>0?"render/image":"object";return{data:{publicUrl:encodeURI(`${this.url}/${c}/public/${i}`)+(l?`?${l}`:"")}}}async remove(n){var e=this;return e.handleOperation(async()=>await go(e.fetch,`${e.url}/object/${e.bucketId}`,{prefixes:n},{headers:e.headers}))}async purgeCache(n,e,i){var a=this;return a.handleOperation(async()=>{const l=a._getFinalPath(n),c=new URLSearchParams;e!=null&&e.transformations&&c.set("transformations","true");const u=c.toString();return await go(a.fetch,`${a.url}/cdn/${l}${u?`?${u}`:""}`,{},{headers:a.headers},i)})}async list(n,e,i){var a=this;return a.handleOperation(async()=>{const l=e!=null&&e.sortBy?fe(fe({},Sd.sortBy),e.sortBy):Sd.sortBy,c=fe(fe(fe({},Sd),e),{},{sortBy:l,prefix:n||""});return await Pn(a.fetch,`${a.url}/object/list/${a.bucketId}`,c,{headers:a.headers},i)})}async listV2(n,e){var i=this;return i.handleOperation(async()=>{const a=fe({},n);return await Pn(i.fetch,`${i.url}/object/list-v2/${i.bucketId}`,a,{headers:i.headers},e)})}encodeMetadata(n){return JSON.stringify(n)}toBase64(n){return typeof Buffer<"u"?Buffer.from(n).toString("base64"):btoa(n)}_getFinalPath(n){return`${this.bucketId}/${n.replace(/^\/+/,"")}`}_removeEmptyFolders(n){return n.replace(/^\/|\/$/g,"").replace(/\/+/g,"/")}applyTransformOptsToQuery(n,e){return e.width&&n.set("width",e.width.toString()),e.height&&n.set("height",e.height.toString()),e.resize&&n.set("resize",e.resize),e.format&&n.set("format",e.format),e.quality&&n.set("quality",e.quality.toString()),n}};const AR="2.110.2",To={"X-Client-Info":`storage-js/${AR}`};var jR=class extends Ja{constructor(n,e={},i,a){const l=new URL(n);a!=null&&a.useNewHostname&&/supabase\.(co|in|red)$/.test(l.hostname)&&!l.hostname.includes("storage.supabase.")&&(l.hostname=l.hostname.replace("supabase.","storage.supabase."));const c=l.href.replace(/\/$/,""),u=fe(fe({},To),e);super(c,u,i,"storage")}async listBuckets(n){var e=this;return e.handleOperation(async()=>{const i=e.listBucketOptionsToQueryString(n);return await po(e.fetch,`${e.url}/bucket${i}`,{headers:e.headers})})}async getBucket(n){var e=this;return e.handleOperation(async()=>await po(e.fetch,`${e.url}/bucket/${n}`,{headers:e.headers}))}async createBucket(n,e={public:!1}){var i=this;return i.handleOperation(async()=>await Pn(i.fetch,`${i.url}/bucket`,{id:n,name:n,type:e.type,public:e.public,file_size_limit:e.fileSizeLimit,allowed_mime_types:e.allowedMimeTypes},{headers:i.headers}))}async updateBucket(n,e){var i=this;return i.handleOperation(async()=>await pf(i.fetch,`${i.url}/bucket/${n}`,{id:n,name:n,public:e.public,file_size_limit:e.fileSizeLimit,allowed_mime_types:e.allowedMimeTypes},{headers:i.headers}))}async emptyBucket(n){var e=this;return e.handleOperation(async()=>await Pn(e.fetch,`${e.url}/bucket/${n}/empty`,{},{headers:e.headers}))}async deleteBucket(n){var e=this;return e.handleOperation(async()=>await go(e.fetch,`${e.url}/bucket/${n}`,{},{headers:e.headers}))}async purgeBucketCache(n,e,i){var a=this;return a.handleOperation(async()=>{const l=new URLSearchParams;e!=null&&e.transformations&&l.set("transformations","true");const c=l.toString();return await go(a.fetch,`${a.url}/cdn/${n}${c?`?${c}`:""}`,{},{headers:a.headers},i)})}listBucketOptionsToQueryString(n){const e={};return n&&("limit"in n&&(e.limit=String(n.limit)),"offset"in n&&(e.offset=String(n.offset)),n.search&&(e.search=n.search),n.sortColumn&&(e.sortColumn=n.sortColumn),n.sortOrder&&(e.sortOrder=n.sortOrder)),Object.keys(e).length>0?"?"+new URLSearchParams(e).toString():""}},NR=class extends Ja{constructor(n,e={},i){const a=n.replace(/\/$/,""),l=fe(fe({},To),e);super(a,l,i,"storage")}async createBucket(n){var e=this;return e.handleOperation(async()=>await Pn(e.fetch,`${e.url}/bucket`,{name:n},{headers:e.headers}))}async listBuckets(n){var e=this;return e.handleOperation(async()=>{const i=new URLSearchParams;(n==null?void 0:n.limit)!==void 0&&i.set("limit",n.limit.toString()),(n==null?void 0:n.offset)!==void 0&&i.set("offset",n.offset.toString()),n!=null&&n.sortColumn&&i.set("sortColumn",n.sortColumn),n!=null&&n.sortOrder&&i.set("sortOrder",n.sortOrder),n!=null&&n.search&&i.set("search",n.search);const a=i.toString(),l=a?`${e.url}/bucket?${a}`:`${e.url}/bucket`;return await po(e.fetch,l,{headers:e.headers})})}async deleteBucket(n){var e=this;return e.handleOperation(async()=>await go(e.fetch,`${e.url}/bucket/${n}`,{},{headers:e.headers}))}from(n){var e=this;if(!bR(n))throw new $c("Invalid bucket name: File, folder, and bucket names must follow AWS object key naming guidelines and should avoid the use of any other characters.");const i=new hR({baseUrl:this.url,catalogName:n,auth:{type:"custom",getHeaders:async()=>e.headers},fetch:this.fetch}),a=this.shouldThrowOnError;return new Proxy(i,{get(l,c){const u=l[c];return typeof u!="function"?u:async(...d)=>{try{return{data:await u.apply(l,d),error:null}}catch(m){if(a)throw m;return{data:null,error:m}}}}})}},RR=class extends Ja{constructor(n,e={},i){const a=n.replace(/\/$/,""),l=fe(fe({},To),{},{"Content-Type":"application/json"},e);super(a,l,i,"vectors")}async createIndex(n){var e=this;return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/CreateIndex`,n,{headers:e.headers})||{})}async getIndex(n,e){var i=this;return i.handleOperation(async()=>await on.post(i.fetch,`${i.url}/GetIndex`,{vectorBucketName:n,indexName:e},{headers:i.headers}))}async listIndexes(n){var e=this;return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/ListIndexes`,n,{headers:e.headers}))}async deleteIndex(n,e){var i=this;return i.handleOperation(async()=>await on.post(i.fetch,`${i.url}/DeleteIndex`,{vectorBucketName:n,indexName:e},{headers:i.headers})||{})}},kR=class extends Ja{constructor(n,e={},i){const a=n.replace(/\/$/,""),l=fe(fe({},To),{},{"Content-Type":"application/json"},e);super(a,l,i,"vectors")}async putVectors(n){var e=this;if(n.vectors.length<1||n.vectors.length>500)throw new Error("Vector batch size must be between 1 and 500 items");return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/PutVectors`,n,{headers:e.headers})||{})}async getVectors(n){var e=this;return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/GetVectors`,n,{headers:e.headers}))}async listVectors(n){var e=this;if(n.segmentCount!==void 0){if(n.segmentCount<1||n.segmentCount>16)throw new Error("segmentCount must be between 1 and 16");if(n.segmentIndex!==void 0&&(n.segmentIndex<0||n.segmentIndex>=n.segmentCount))throw new Error(`segmentIndex must be between 0 and ${n.segmentCount-1}`)}return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/ListVectors`,n,{headers:e.headers}))}async queryVectors(n){var e=this;return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/QueryVectors`,n,{headers:e.headers}))}async deleteVectors(n){var e=this;if(n.keys.length<1||n.keys.length>500)throw new Error("Keys batch size must be between 1 and 500 items");return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/DeleteVectors`,n,{headers:e.headers})||{})}},CR=class extends Ja{constructor(n,e={},i){const a=n.replace(/\/$/,""),l=fe(fe({},To),{},{"Content-Type":"application/json"},e);super(a,l,i,"vectors")}async createBucket(n){var e=this;return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/CreateVectorBucket`,{vectorBucketName:n},{headers:e.headers})||{})}async getBucket(n){var e=this;return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/GetVectorBucket`,{vectorBucketName:n},{headers:e.headers}))}async listBuckets(n={}){var e=this;return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/ListVectorBuckets`,n,{headers:e.headers}))}async deleteBucket(n){var e=this;return e.handleOperation(async()=>await on.post(e.fetch,`${e.url}/DeleteVectorBucket`,{vectorBucketName:n},{headers:e.headers})||{})}},OR=class extends CR{constructor(n,e={}){super(n,e.headers||{},e.fetch)}from(n){return new DR(this.url,this.headers,n,this.fetch)}async createBucket(n){var e=()=>super.createBucket,i=this;return e().call(i,n)}async getBucket(n){var e=()=>super.getBucket,i=this;return e().call(i,n)}async listBuckets(n={}){var e=()=>super.listBuckets,i=this;return e().call(i,n)}async deleteBucket(n){var e=()=>super.deleteBucket,i=this;return e().call(i,n)}},DR=class extends RR{constructor(n,e,i,a){super(n,e,a),this.vectorBucketName=i}async createIndex(n){var e=()=>super.createIndex,i=this;return e().call(i,fe(fe({},n),{},{vectorBucketName:i.vectorBucketName}))}async listIndexes(n={}){var e=()=>super.listIndexes,i=this;return e().call(i,fe(fe({},n),{},{vectorBucketName:i.vectorBucketName}))}async getIndex(n){var e=()=>super.getIndex,i=this;return e().call(i,i.vectorBucketName,n)}async deleteIndex(n){var e=()=>super.deleteIndex,i=this;return e().call(i,i.vectorBucketName,n)}index(n){return new MR(this.url,this.headers,this.vectorBucketName,n,this.fetch)}},MR=class extends kR{constructor(n,e,i,a,l){super(n,e,l),this.vectorBucketName=i,this.indexName=a}async putVectors(n){var e=()=>super.putVectors,i=this;return e().call(i,fe(fe({},n),{},{vectorBucketName:i.vectorBucketName,indexName:i.indexName}))}async getVectors(n){var e=()=>super.getVectors,i=this;return e().call(i,fe(fe({},n),{},{vectorBucketName:i.vectorBucketName,indexName:i.indexName}))}async listVectors(n={}){var e=()=>super.listVectors,i=this;return e().call(i,fe(fe({},n),{},{vectorBucketName:i.vectorBucketName,indexName:i.indexName}))}async queryVectors(n){var e=()=>super.queryVectors,i=this;return e().call(i,fe(fe({},n),{},{vectorBucketName:i.vectorBucketName,indexName:i.indexName}))}async deleteVectors(n){var e=()=>super.deleteVectors,i=this;return e().call(i,fe(fe({},n),{},{vectorBucketName:i.vectorBucketName,indexName:i.indexName}))}},BR=class extends jR{constructor(n,e={},i,a){super(n,e,i,a)}from(n){return new ER(this.url,this.headers,n,this.fetch)}get vectors(){return new OR(this.url+"/vector",{headers:this.headers,fetch:this.fetch})}get analytics(){return new NR(this.url+"/iceberg",this.headers,this.fetch)}};const Tw="2.110.2",ks=30*1e3,Qr=3,Td=Qr*ks,UR=2*ks,LR="http://localhost:9999",zR="supabase.auth.token",PR={"X-Client-Info":`gotrue-js/${Tw}`},gf="X-Supabase-Api-Version",Ew={"2024-01-01":{timestamp:Date.parse("2024-01-01T00:00:00.0Z"),name:"2024-01-01"}},VR=/^([a-z0-9_-]{4})*($|[a-z0-9_-]{3}$|[a-z0-9_-]{2}$)$/i,HR=600*1e3;class yo extends Error{constructor(e,i,a){super(e),this.__isAuthError=!0,this.name="AuthError",this.status=i,this.code=a}toJSON(){return{name:this.name,message:this.message,status:this.status,code:this.code}}}function te(n){return typeof n=="object"&&n!==null&&"__isAuthError"in n}class $R extends yo{constructor(e,i,a){super(e,i,a),this.name="AuthApiError",this.status=i,this.code=a}}function qR(n){return te(n)&&n.name==="AuthApiError"}class Vn extends yo{constructor(e,i){super(e),this.name="AuthUnknownError",this.originalError=i}}class is extends yo{constructor(e,i,a,l){super(e,a,l),this.name=i,this.status=a}}class kt extends is{constructor(){super("Auth session missing!","AuthSessionMissingError",400,void 0)}}function ec(n){return te(n)&&n.name==="AuthSessionMissingError"}class ja extends is{constructor(){super("Auth session or user missing","AuthInvalidTokenResponseError",500,void 0)}}class tc extends is{constructor(e){super(e,"AuthInvalidCredentialsError",400,void 0)}}class nc extends is{constructor(e,i=null){super(e,"AuthImplicitGrantRedirectError",500,void 0),this.details=null,this.details=i}toJSON(){return Object.assign(Object.assign({},super.toJSON()),{details:this.details})}}function FR(n){return te(n)&&n.name==="AuthImplicitGrantRedirectError"}class zb extends is{constructor(e,i=null){super(e,"AuthPKCEGrantCodeExchangeError",500,void 0),this.details=null,this.details=i}toJSON(){return Object.assign(Object.assign({},super.toJSON()),{details:this.details})}}class IR extends is{constructor(){super("PKCE code verifier not found in storage. This can happen if the auth flow was initiated in a different browser or device, or if the storage was cleared. For SSR frameworks (Next.js, SvelteKit, etc.), use @supabase/ssr on both the server and client to store the code verifier in cookies.","AuthPKCECodeVerifierMissingError",400,"pkce_code_verifier_not_found")}}class yf extends is{constructor(e,i){super(e,"AuthRetryableFetchError",i,void 0)}}function Pb(n){return te(n)&&n.name==="AuthRetryableFetchError"}class Vb extends is{constructor(e="Refresh result discarded: session state changed mid-flight (e.g., concurrent signOut)"){super(e,"AuthRefreshDiscardedError",409,void 0)}}function GR(n){return te(n)&&n.name==="AuthRefreshDiscardedError"}class Hb extends is{constructor(e,i,a){super(e,"AuthWeakPasswordError",i,"weak_password"),this.reasons=a}toJSON(){return Object.assign(Object.assign({},super.toJSON()),{reasons:this.reasons})}}class Rc extends is{constructor(e){super(e,"AuthInvalidJwtError",400,"invalid_jwt")}}const kc="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".split(""),$b=` +\r=`.split(""),KR=(()=>{const n=new Array(128);for(let e=0;e=6;){const a=e.queue>>e.queuedBits-6&63;i(kc[a]),e.queuedBits-=6}else if(e.queuedBits>0)for(e.queue=e.queue<<6-e.queuedBits,e.queuedBits=6;e.queuedBits>=6;){const a=e.queue>>e.queuedBits-6&63;i(kc[a]),e.queuedBits-=6}}function Aw(n,e,i){const a=KR[n];if(a>-1)for(e.queue=e.queue<<6|a,e.queuedBits+=6;e.queuedBits>=8;)i(e.queue>>e.queuedBits-8&255),e.queuedBits-=8;else{if(a===-2)return;throw new Error(`Invalid Base64-URL character "${String.fromCharCode(n)}"`)}}function Fb(n){const e=[],i=u=>{e.push(String.fromCodePoint(u))},a={utf8seq:0,codepoint:0},l={queue:0,queuedBits:0},c=u=>{JR(u,a,i)};for(let u=0;u>6),e(128|n&63);return}else if(n<=65535){e(224|n>>12),e(128|n>>6&63),e(128|n&63);return}else if(n<=1114111){e(240|n>>18),e(128|n>>12&63),e(128|n>>6&63),e(128|n&63);return}throw new Error(`Unrecognized Unicode codepoint: ${n.toString(16)}`)}function XR(n,e){for(let i=0;i55295&&a<=56319){const l=(a-55296)*1024&65535;a=(n.charCodeAt(i+1)-56320&65535|l)+65536,i+=1}YR(a,e)}}function JR(n,e,i){if(e.utf8seq===0){if(n<=127){i(n);return}for(let a=1;a<6;a+=1)if((n>>7-a&1)===0){e.utf8seq=a;break}if(e.utf8seq===2)e.codepoint=n&31;else if(e.utf8seq===3)e.codepoint=n&15;else if(e.utf8seq===4)e.codepoint=n&7;else throw new Error("Invalid UTF-8 sequence");e.utf8seq-=1}else if(e.utf8seq>0){if(n<=127)throw new Error("Invalid UTF-8 sequence");e.codepoint=e.codepoint<<6|n&63,e.utf8seq-=1,e.utf8seq===0&&i(e.codepoint)}}function $a(n){const e=[],i={queue:0,queuedBits:0},a=l=>{e.push(l)};for(let l=0;le.push(i)),new Uint8Array(e)}function Pi(n){const e=[],i={queue:0,queuedBits:0},a=l=>{e.push(l)};return n.forEach(l=>qb(l,i,a)),qb(null,i,a),e.join("")}function ZR(n){return Math.round(Date.now()/1e3)+n}function WR(){return Symbol("auth-callback")}const Pt=()=>typeof window<"u"&&typeof document<"u",Oi={tested:!1,writable:!1},jw=()=>{if(!Pt())return!1;try{if(typeof globalThis.localStorage!="object")return!1}catch{return!1}if(Oi.tested)return Oi.writable;const n=`lswt-${Math.random()}${Math.random()}`;try{globalThis.localStorage.setItem(n,n),globalThis.localStorage.removeItem(n),Oi.tested=!0,Oi.writable=!0}catch{Oi.tested=!0,Oi.writable=!1}return Oi.writable};function ek(n){const e={},i=new URL(n);if(i.hash&&i.hash[0]==="#")try{new URLSearchParams(i.hash.substring(1)).forEach((l,c)=>{e[c]=l})}catch{}return i.searchParams.forEach((a,l)=>{e[l]=a}),e}const Nw=n=>n?(...e)=>n(...e):(...e)=>fetch(...e),tk=n=>typeof n=="object"&&n!==null&&"status"in n&&"ok"in n&&"json"in n&&typeof n.json=="function",Ma=async(n,e,i)=>{await n.setItem(e,JSON.stringify(i))},Bn=async(n,e)=>{const i=await n.getItem(e);if(!i)return null;try{return JSON.parse(i)}catch{return null}},pt=async(n,e)=>{await n.removeItem(e)};class Fc{constructor(){this.promise=new Fc.promiseConstructor((e,i)=>{this.resolve=e,this.reject=i})}}Fc.promiseConstructor=Promise;function sc(n){const e=n.split(".");if(e.length!==3)throw new Rc("Invalid JWT structure");for(let a=0;a{setTimeout(()=>e(null),n)})}function sk(n,e){return new Promise((a,l)=>{(async()=>{for(let c=0;c<1/0;c++)try{const u=await n(c);if(!e(c,null,u)){a(u);return}}catch(u){if(!e(c,u)){l(u);return}}})()})}function ik(n){return("0"+n.toString(16)).substr(-2)}function ak(){const e=new Uint32Array(56);if(typeof crypto>"u"){const i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",a=i.length;let l="";for(let c=0;c<56;c++)l+=i.charAt(Math.floor(Math.random()*a));return l}return crypto.getRandomValues(e),Array.from(e,ik).join("")}async function rk(n){const i=new TextEncoder().encode(n),a=await crypto.subtle.digest("SHA-256",i),l=new Uint8Array(a);return Array.from(l).map(c=>String.fromCharCode(c)).join("")}async function ok(n){if(!(typeof crypto<"u"&&typeof crypto.subtle<"u"&&typeof TextEncoder<"u"))return console.warn("WebCrypto API is not supported. Code challenge method will default to use plain instead of sha256."),n;const i=await rk(n);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function Di(n,e,i=!1){const a=ak();let l=a;i&&(l+="/recovery"),await Ma(n,`${e}-code-verifier`,l);const c=await ok(a);return[c,a===c?"plain":"s256"]}const lk=/^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[0-1])$/i;function ck(n){const e=n.headers.get(gf);if(!e||!e.match(lk))return null;try{return new Date(`${e}T00:00:00.0Z`)}catch{return null}}function uk(n){if(!n)throw new Error("Missing exp claim");const e=Math.floor(Date.now()/1e3);if(n<=e)throw new Error("JWT has expired")}function hk(n){switch(n){case"RS256":return{name:"RSASSA-PKCS1-v1_5",hash:{name:"SHA-256"}};case"ES256":return{name:"ECDSA",namedCurve:"P-256",hash:{name:"SHA-256"}};default:throw new Error("Invalid alg claim")}}const dk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;function As(n){if(!dk.test(n))throw new Error("@supabase/auth-js: Expected parameter to be UUID but is not")}function zn(n){if(!n.passkey)throw new Error("@supabase/auth-js: the passkey API is experimental and disabled by default. Enable it by passing `auth: { experimental: { passkey: true } }` to createClient (or to the GoTrueClient constructor).")}function Ed(){const n={};return new Proxy(n,{get:(e,i)=>{if(i==="__isUserNotAvailableProxy")return!0;if(typeof i=="symbol"){const a=i.toString();if(a==="Symbol(Symbol.toPrimitive)"||a==="Symbol(Symbol.toStringTag)"||a==="Symbol(util.inspect.custom)")return}throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Accessing the "${i}" property of the session object is not supported. Please use getUser() instead.`)},set:(e,i)=>{throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Setting the "${i}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`)},deleteProperty:(e,i)=>{throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Deleting the "${i}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`)}})}function fk(n,e){return new Proxy(n,{get:(i,a,l)=>{if(a==="__isInsecureUserWarningProxy")return!0;if(typeof a=="symbol"){const c=a.toString();if(c==="Symbol(Symbol.toPrimitive)"||c==="Symbol(Symbol.toStringTag)"||c==="Symbol(util.inspect.custom)"||c==="Symbol(nodejs.util.inspect.custom)")return Reflect.get(i,a,l)}return!e.value&&typeof a=="string"&&(console.warn("Using the user object as returned from supabase.auth.getSession() or from some supabase.auth.onAuthStateChange() events could be insecure! This value comes directly from the storage medium (usually cookies on the server) and may not be authentic. Use supabase.auth.getUser() instead which authenticates the data by contacting the Supabase Auth server."),e.value=!0),Reflect.get(i,a,l)}})}function Ib(n){return JSON.parse(JSON.stringify(n))}const Bi=n=>{if(typeof n=="object"&&n!==null){const e=n;if(typeof e.msg=="string")return e.msg;if(typeof e.message=="string")return e.message;if(typeof e.error_description=="string")return e.error_description;if(typeof e.error=="string")return e.error}return JSON.stringify(n)},mk=[500,501,502,503,504,520,521,522,523,524,525,526,527,528,529,530];async function Gb(n){var e;if(!tk(n))throw new yf(Bi(n),0);if(mk.includes(n.status))throw new yf(Bi(n),n.status);let i;try{i=await n.json()}catch(c){throw new Vn(Bi(c),c)}let a;const l=ck(n);if(l&&l.getTime()>=Ew["2024-01-01"].timestamp&&typeof i=="object"&&i&&typeof i.code=="string"?a=i.code:typeof i=="object"&&i&&typeof i.error_code=="string"&&(a=i.error_code),a){if(a==="weak_password")throw new Hb(Bi(i),n.status,((e=i.weak_password)===null||e===void 0?void 0:e.reasons)||[]);if(a==="session_not_found")throw new kt}else if(typeof i=="object"&&i&&typeof i.weak_password=="object"&&i.weak_password&&Array.isArray(i.weak_password.reasons)&&i.weak_password.reasons.length&&i.weak_password.reasons.reduce((c,u)=>c&&typeof u=="string",!0))throw new Hb(Bi(i),n.status,i.weak_password.reasons);throw new $R(Bi(i),n.status||500,a)}const pk=(n,e,i,a)=>{const l={method:n,headers:(e==null?void 0:e.headers)||{}};return n==="GET"?l:(l.headers=Object.assign({"Content-Type":"application/json;charset=UTF-8"},e==null?void 0:e.headers),l.body=JSON.stringify(a),Object.assign(Object.assign({},l),i))};async function oe(n,e,i,a){var l;const c=Object.assign({},a==null?void 0:a.headers);c[gf]||(c[gf]=Ew["2024-01-01"].name),a!=null&&a.jwt&&(c.Authorization=`Bearer ${a.jwt}`);const u=(l=a==null?void 0:a.query)!==null&&l!==void 0?l:{};a!=null&&a.redirectTo&&(u.redirect_to=a.redirectTo);const d=Object.keys(u).length?"?"+new URLSearchParams(u).toString():"",m=await gk(n,e,i+d,{headers:c,noResolveJson:a==null?void 0:a.noResolveJson},{},a==null?void 0:a.body);return a!=null&&a.xform?a==null?void 0:a.xform(m):{data:Object.assign({},m),error:null}}async function gk(n,e,i,a,l,c){const u=pk(e,a,l,c);let d;try{d=await n(i,Object.assign({},u))}catch(m){throw console.error(m),new yf(Bi(m),0)}if(d.ok||await Gb(d),a!=null&&a.noResolveJson)return d;try{return await d.json()}catch(m){await Gb(m)}}function Sn(n){var e;let i=null;vk(n)&&(i=Object.assign({},n),n.expires_at||(i.expires_at=ZR(n.expires_in)));const a=(e=n.user)!==null&&e!==void 0?e:typeof(n==null?void 0:n.id)=="string"?n:null;return{data:{session:i,user:a},error:null}}function Kb(n){const e=Sn(n);return!e.error&&n.weak_password&&typeof n.weak_password=="object"&&Array.isArray(n.weak_password.reasons)&&n.weak_password.reasons.length&&n.weak_password.message&&typeof n.weak_password.message=="string"&&n.weak_password.reasons.reduce((i,a)=>i&&typeof a=="string",!0)&&(e.data.weak_password=n.weak_password),e}function ii(n){var e;return{data:{user:(e=n.user)!==null&&e!==void 0?e:n},error:null}}function yk(n){return{data:n,error:null}}function bk(n){const{action_link:e,email_otp:i,hashed_token:a,redirect_to:l,verification_type:c}=n,u=Hc(n,["action_link","email_otp","hashed_token","redirect_to","verification_type"]),d={action_link:e,email_otp:i,hashed_token:a,redirect_to:l,verification_type:c},m=Object.assign({},u);return{data:{properties:d,user:m},error:null}}function Yb(n){return n}function vk(n){return!!n.access_token&&!!n.refresh_token&&!!n.expires_in}const Ad=["global","local","others"];class xk{constructor({url:e="",headers:i={},fetch:a,experimental:l}){this.url=e,this.headers=i,this.fetch=Nw(a),this.experimental=l??{},this.mfa={listFactors:this._listFactors.bind(this),deleteFactor:this._deleteFactor.bind(this)},this.oauth={listClients:this._listOAuthClients.bind(this),createClient:this._createOAuthClient.bind(this),getClient:this._getOAuthClient.bind(this),updateClient:this._updateOAuthClient.bind(this),deleteClient:this._deleteOAuthClient.bind(this),regenerateClientSecret:this._regenerateOAuthClientSecret.bind(this)},this.customProviders={listProviders:this._listCustomProviders.bind(this),createProvider:this._createCustomProvider.bind(this),getProvider:this._getCustomProvider.bind(this),updateProvider:this._updateCustomProvider.bind(this),deleteProvider:this._deleteCustomProvider.bind(this)},this.passkey={listPasskeys:this._adminListPasskeys.bind(this),deletePasskey:this._adminDeletePasskey.bind(this)}}async signOut(e,i=Ad[0]){if(Ad.indexOf(i)<0)throw new Error(`@supabase/auth-js: Parameter scope must be one of ${Ad.join(", ")}`);try{return await oe(this.fetch,"POST",`${this.url}/logout?scope=${i}`,{headers:this.headers,jwt:e,noResolveJson:!0}),{data:null,error:null}}catch(a){if(te(a))return{data:null,error:a};throw a}}async inviteUserByEmail(e,i={}){try{return await oe(this.fetch,"POST",`${this.url}/invite`,{body:{email:e,data:i.data},headers:this.headers,redirectTo:i.redirectTo,xform:ii})}catch(a){if(te(a))return{data:{user:null},error:a};throw a}}async generateLink(e){try{const{options:i}=e,a=Hc(e,["options"]),l=Object.assign(Object.assign({},a),i);return"newEmail"in a&&(l.new_email=a==null?void 0:a.newEmail,delete l.newEmail),await oe(this.fetch,"POST",`${this.url}/admin/generate_link`,{body:l,headers:this.headers,xform:bk,redirectTo:i==null?void 0:i.redirectTo})}catch(i){if(te(i))return{data:{properties:null,user:null},error:i};throw i}}async createUser(e){try{return await oe(this.fetch,"POST",`${this.url}/admin/users`,{body:e,headers:this.headers,xform:ii})}catch(i){if(te(i))return{data:{user:null},error:i};throw i}}async listUsers(e){var i,a,l,c,u,d,m;try{const p={nextPage:null,lastPage:0,total:0},y=await oe(this.fetch,"GET",`${this.url}/admin/users`,{headers:this.headers,noResolveJson:!0,query:{page:(a=(i=e==null?void 0:e.page)===null||i===void 0?void 0:i.toString())!==null&&a!==void 0?a:"",per_page:(c=(l=e==null?void 0:e.perPage)===null||l===void 0?void 0:l.toString())!==null&&c!==void 0?c:""},xform:Yb});if(y.error)throw y.error;const v=await y.json(),x=(u=y.headers.get("x-total-count"))!==null&&u!==void 0?u:0,_=(m=(d=y.headers.get("link"))===null||d===void 0?void 0:d.split(","))!==null&&m!==void 0?m:[];return _.length>0&&(_.forEach(S=>{const T=parseInt(S.split(";")[0].split("=")[1].substring(0,1)),j=JSON.parse(S.split(";")[1].split("=")[1]);p[`${j}Page`]=T}),p.total=parseInt(x)),{data:Object.assign(Object.assign({},v),p),error:null}}catch(p){if(te(p))return{data:{users:[]},error:p};throw p}}async getUserById(e){As(e);try{return await oe(this.fetch,"GET",`${this.url}/admin/users/${e}`,{headers:this.headers,xform:ii})}catch(i){if(te(i))return{data:{user:null},error:i};throw i}}async updateUserById(e,i){As(e);try{return await oe(this.fetch,"PUT",`${this.url}/admin/users/${e}`,{body:i,headers:this.headers,xform:ii})}catch(a){if(te(a))return{data:{user:null},error:a};throw a}}async deleteUser(e,i=!1){As(e);try{return await oe(this.fetch,"DELETE",`${this.url}/admin/users/${e}`,{headers:this.headers,body:{should_soft_delete:i},xform:ii})}catch(a){if(te(a))return{data:{user:null},error:a};throw a}}async _listFactors(e){As(e.userId);try{const{data:i,error:a}=await oe(this.fetch,"GET",`${this.url}/admin/users/${e.userId}/factors`,{headers:this.headers,xform:l=>({data:{factors:l},error:null})});return{data:i,error:a}}catch(i){if(te(i))return{data:null,error:i};throw i}}async _deleteFactor(e){As(e.userId),As(e.id);try{return{data:await oe(this.fetch,"DELETE",`${this.url}/admin/users/${e.userId}/factors/${e.id}`,{headers:this.headers}),error:null}}catch(i){if(te(i))return{data:null,error:i};throw i}}async _listOAuthClients(e){var i,a,l,c,u,d,m;try{const p={nextPage:null,lastPage:0,total:0},y=await oe(this.fetch,"GET",`${this.url}/admin/oauth/clients`,{headers:this.headers,noResolveJson:!0,query:{page:(a=(i=e==null?void 0:e.page)===null||i===void 0?void 0:i.toString())!==null&&a!==void 0?a:"",per_page:(c=(l=e==null?void 0:e.perPage)===null||l===void 0?void 0:l.toString())!==null&&c!==void 0?c:""},xform:Yb});if(y.error)throw y.error;const v=await y.json(),x=(u=y.headers.get("x-total-count"))!==null&&u!==void 0?u:0,_=(m=(d=y.headers.get("link"))===null||d===void 0?void 0:d.split(","))!==null&&m!==void 0?m:[];return _.length>0&&(_.forEach(S=>{const T=parseInt(S.split(";")[0].split("=")[1].substring(0,1)),j=JSON.parse(S.split(";")[1].split("=")[1]);p[`${j}Page`]=T}),p.total=parseInt(x)),{data:Object.assign(Object.assign({},v),p),error:null}}catch(p){if(te(p))return{data:{clients:[]},error:p};throw p}}async _createOAuthClient(e){try{return await oe(this.fetch,"POST",`${this.url}/admin/oauth/clients`,{body:e,headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(te(i))return{data:null,error:i};throw i}}async _getOAuthClient(e){try{return await oe(this.fetch,"GET",`${this.url}/admin/oauth/clients/${e}`,{headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(te(i))return{data:null,error:i};throw i}}async _updateOAuthClient(e,i){try{return await oe(this.fetch,"PUT",`${this.url}/admin/oauth/clients/${e}`,{body:i,headers:this.headers,xform:a=>({data:a,error:null})})}catch(a){if(te(a))return{data:null,error:a};throw a}}async _deleteOAuthClient(e){try{return await oe(this.fetch,"DELETE",`${this.url}/admin/oauth/clients/${e}`,{headers:this.headers,noResolveJson:!0}),{data:null,error:null}}catch(i){if(te(i))return{data:null,error:i};throw i}}async _regenerateOAuthClientSecret(e){try{return await oe(this.fetch,"POST",`${this.url}/admin/oauth/clients/${e}/regenerate_secret`,{headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(te(i))return{data:null,error:i};throw i}}async _listCustomProviders(e){try{const i={};return e!=null&&e.type&&(i.type=e.type),await oe(this.fetch,"GET",`${this.url}/admin/custom-providers`,{headers:this.headers,query:i,xform:a=>{var l;return{data:{providers:(l=a==null?void 0:a.providers)!==null&&l!==void 0?l:[]},error:null}}})}catch(i){if(te(i))return{data:{providers:[]},error:i};throw i}}async _createCustomProvider(e){try{return await oe(this.fetch,"POST",`${this.url}/admin/custom-providers`,{body:e,headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(te(i))return{data:null,error:i};throw i}}async _getCustomProvider(e){try{return await oe(this.fetch,"GET",`${this.url}/admin/custom-providers/${e}`,{headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(te(i))return{data:null,error:i};throw i}}async _updateCustomProvider(e,i){try{return await oe(this.fetch,"PUT",`${this.url}/admin/custom-providers/${e}`,{body:i,headers:this.headers,xform:a=>({data:a,error:null})})}catch(a){if(te(a))return{data:null,error:a};throw a}}async _deleteCustomProvider(e){try{return await oe(this.fetch,"DELETE",`${this.url}/admin/custom-providers/${e}`,{headers:this.headers,noResolveJson:!0}),{data:null,error:null}}catch(i){if(te(i))return{data:null,error:i};throw i}}async _adminListPasskeys(e){zn(this.experimental),As(e.userId);try{return await oe(this.fetch,"GET",`${this.url}/admin/users/${e.userId}/passkeys`,{headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(te(i))return{data:null,error:i};throw i}}async _adminDeletePasskey(e){zn(this.experimental),As(e.userId),As(e.passkeyId);try{return await oe(this.fetch,"DELETE",`${this.url}/admin/users/${e.userId}/passkeys/${e.passkeyId}`,{headers:this.headers,noResolveJson:!0}),{data:null,error:null}}catch(i){if(te(i))return{data:null,error:i};throw i}}}function Xb(n={}){return{getItem:e=>n[e]||null,setItem:(e,i)=>{n[e]=i},removeItem:e=>{delete n[e]}}}globalThis&&jw()&&globalThis.localStorage&&globalThis.localStorage.getItem("supabase.gotrue-js.locks.debug");class wk extends Error{constructor(e){super(e),this.isAcquireTimeout=!0}}function _k(){if(typeof globalThis!="object")try{Object.defineProperty(Object.prototype,"__magic__",{get:function(){return this},configurable:!0}),__magic__.globalThis=__magic__,delete Object.prototype.__magic__}catch{typeof self<"u"&&(self.globalThis=self)}}function Rw(n){if(!/^0x[a-fA-F0-9]{40}$/.test(n))throw new Error(`@supabase/auth-js: Address "${n}" is invalid.`);return n.toLowerCase()}function Sk(n){return parseInt(n,16)}function Tk(n){const e=new TextEncoder().encode(n);return"0x"+Array.from(e,a=>a.toString(16).padStart(2,"0")).join("")}function Ek(n){var e;const{chainId:i,domain:a,expirationTime:l,issuedAt:c=new Date,nonce:u,notBefore:d,requestId:m,resources:p,scheme:y,uri:v,version:x}=n;{if(!Number.isInteger(i))throw new Error(`@supabase/auth-js: Invalid SIWE message field "chainId". Chain ID must be a EIP-155 chain ID. Provided value: ${i}`);if(!a)throw new Error('@supabase/auth-js: Invalid SIWE message field "domain". Domain must be provided.');if(u&&u.length<8)throw new Error(`@supabase/auth-js: Invalid SIWE message field "nonce". Nonce must be at least 8 characters. Provided value: ${u}`);if(!v)throw new Error('@supabase/auth-js: Invalid SIWE message field "uri". URI must be provided.');if(x!=="1")throw new Error(`@supabase/auth-js: Invalid SIWE message field "version". Version must be '1'. Provided value: ${x}`);if(!((e=n.statement)===null||e===void 0)&&e.includes(` +`))throw new Error(`@supabase/auth-js: Invalid SIWE message field "statement". Statement must not include '\\n'. Provided value: ${n.statement}`)}const _=Rw(n.address),S=y?`${y}://${a}`:a,T=n.statement?`${n.statement} +`:"",j=`${S} wants you to sign in with your Ethereum account: +${_} + +${T}`;let k=`URI: ${v} +Version: ${x} +Chain ID: ${i}${u?` +Nonce: ${u}`:""} +Issued At: ${c.toISOString()}`;if(l&&(k+=` +Expiration Time: ${l.toISOString()}`),d&&(k+=` +Not Before: ${d.toISOString()}`),m&&(k+=` +Request ID: ${m}`),p){let M=` +Resources:`;for(const C of p){if(!C||typeof C!="string")throw new Error(`@supabase/auth-js: Invalid SIWE message field "resources". Every resource must be a valid string. Provided value: ${C}`);M+=` +- ${C}`}k+=M}return`${j} +${k}`}class _t extends Error{constructor({message:e,code:i,cause:a,name:l}){var c;super(e,{cause:a}),this.__isWebAuthnError=!0,this.name=(c=l??(a instanceof Error?a.name:void 0))!==null&&c!==void 0?c:"Unknown Error",this.code=i}toJSON(){return{name:this.name,message:this.message,code:this.code}}}class Cc extends _t{constructor(e,i){super({code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:i,message:e}),this.name="WebAuthnUnknownError",this.originalError=i}}function Ak({error:n,options:e}){var i,a,l;const{publicKey:c}=e;if(!c)throw Error("options was missing required publicKey property");if(n.name==="AbortError"){if(e.signal instanceof AbortSignal)return new _t({message:"Registration ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:n})}else if(n.name==="ConstraintError"){if(((i=c.authenticatorSelection)===null||i===void 0?void 0:i.requireResidentKey)===!0)return new _t({message:"Discoverable credentials were required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",cause:n});if(e.mediation==="conditional"&&((a=c.authenticatorSelection)===null||a===void 0?void 0:a.userVerification)==="required")return new _t({message:"User verification was required during automatic registration but it could not be performed",code:"ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE",cause:n});if(((l=c.authenticatorSelection)===null||l===void 0?void 0:l.userVerification)==="required")return new _t({message:"User verification was required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",cause:n})}else{if(n.name==="InvalidStateError")return new _t({message:"The authenticator was previously registered",code:"ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",cause:n});if(n.name==="NotAllowedError")return new _t({message:n.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:n});if(n.name==="NotSupportedError")return c.pubKeyCredParams.filter(d=>d.type==="public-key").length===0?new _t({message:'No entry in pubKeyCredParams was of type "public-key"',code:"ERROR_MALFORMED_PUBKEYCREDPARAMS",cause:n}):new _t({message:"No available authenticator supported any of the specified pubKeyCredParams algorithms",code:"ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",cause:n});if(n.name==="SecurityError"){const u=window.location.hostname;if(kw(u)){if(c.rp.id!==u)return new _t({message:`The RP ID "${c.rp.id}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:n})}else return new _t({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:n})}else if(n.name==="TypeError"){if(c.user.id.byteLength<1||c.user.id.byteLength>64)return new _t({message:"User ID was not between 1 and 64 characters",code:"ERROR_INVALID_USER_ID_LENGTH",cause:n})}else if(n.name==="UnknownError")return new _t({message:"The authenticator was unable to process the specified options, or could not create a new credential",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:n})}return new _t({message:"a Non-Webauthn related error has occurred",code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:n})}function jk({error:n,options:e}){const{publicKey:i}=e;if(!i)throw Error("options was missing required publicKey property");if(n.name==="AbortError"){if(e.signal instanceof AbortSignal)return new _t({message:"Authentication ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:n})}else{if(n.name==="NotAllowedError")return new _t({message:n.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:n});if(n.name==="SecurityError"){const a=window.location.hostname;if(kw(a)){if(i.rpId!==a)return new _t({message:`The RP ID "${i.rpId}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:n})}else return new _t({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:n})}else if(n.name==="UnknownError")return new _t({message:"The authenticator was unable to process the specified options, or could not create a new assertion signature",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:n})}return new _t({message:"a Non-Webauthn related error has occurred",code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:n})}class Nk{createNewAbortSignal(){if(this.controller){const i=new Error("Cancelling existing WebAuthn API call for new one");i.name="AbortError",this.controller.abort(i)}const e=new AbortController;return this.controller=e,e.signal}cancelCeremony(){if(this.controller){const e=new Error("Manually cancelling existing WebAuthn API call");e.name="AbortError",this.controller.abort(e),this.controller=void 0}}}const bf=new Nk;function Jb(n){if(!n)throw new Error("Credential creation options are required");if(typeof PublicKeyCredential<"u"&&"parseCreationOptionsFromJSON"in PublicKeyCredential&&typeof PublicKeyCredential.parseCreationOptionsFromJSON=="function")return PublicKeyCredential.parseCreationOptionsFromJSON(n);const{challenge:e,user:i,excludeCredentials:a}=n,l=Hc(n,["challenge","user","excludeCredentials"]),c=$a(e).buffer,u=Object.assign(Object.assign({},i),{id:$a(i.id).buffer}),d=Object.assign(Object.assign({},l),{challenge:c,user:u});if(a&&a.length>0){d.excludeCredentials=new Array(a.length);for(let m=0;m0){c.allowCredentials=new Array(i.length);for(let u=0;ul!==null&&typeof l=="object"&&!Array.isArray(l),i=l=>l instanceof ArrayBuffer||ArrayBuffer.isView(l),a={};for(const l of n)if(l)for(const c in l){const u=l[c];if(u!==void 0)if(Array.isArray(u))a[c]=u;else if(i(u))a[c]=u;else if(e(u)){const d=a[c];e(d)?a[c]=Dc(d,u):a[c]=Dc(u)}else a[c]=u}return a}function Ck(n,e){return Dc(Rk,n,e||{})}function Ok(n,e){return Dc(kk,n,e||{})}class Dk{constructor(e){this.client=e,this.enroll=this._enroll.bind(this),this.challenge=this._challenge.bind(this),this.verify=this._verify.bind(this),this.authenticate=this._authenticate.bind(this),this.register=this._register.bind(this)}async _enroll(e){return this.client.mfa.enroll(Object.assign(Object.assign({},e),{factorType:"webauthn"}))}async _challenge({factorId:e,webauthn:i,friendlyName:a,signal:l},c){var u;try{const{data:d,error:m}=await this.client.mfa.challenge({factorId:e,webauthn:i});if(!d)return{data:null,error:m};const p=l??bf.createNewAbortSignal();if(d.webauthn.type==="create"){const{user:y}=d.webauthn.credential_options.publicKey;if(!y.name){const v=a;if(v)y.name=`${y.id}:${v}`;else{const _=(await this.client.getUser()).data.user,S=((u=_==null?void 0:_.user_metadata)===null||u===void 0?void 0:u.name)||(_==null?void 0:_.email)||(_==null?void 0:_.id)||"User";y.name=`${y.id}:${S}`}}y.displayName||(y.displayName=y.name)}switch(d.webauthn.type){case"create":{const y=Ck(d.webauthn.credential_options.publicKey,c==null?void 0:c.create),{data:v,error:x}=await Cw({publicKey:y,signal:p});return v?{data:{factorId:e,challengeId:d.id,webauthn:{type:d.webauthn.type,credential_response:v}},error:null}:{data:null,error:x}}case"request":{const y=Ok(d.webauthn.credential_options.publicKey,c==null?void 0:c.request),{data:v,error:x}=await Ow(Object.assign(Object.assign({},d.webauthn.credential_options),{publicKey:y,signal:p}));return v?{data:{factorId:e,challengeId:d.id,webauthn:{type:d.webauthn.type,credential_response:v}},error:null}:{data:null,error:x}}}}catch(d){return te(d)?{data:null,error:d}:{data:null,error:new Vn("Unexpected error in challenge",d)}}}async _verify({challengeId:e,factorId:i,webauthn:a}){return this.client.mfa.verify({factorId:i,challengeId:e,webauthn:a})}async _authenticate({factorId:e,webauthn:{rpId:i=typeof window<"u"?window.location.hostname:void 0,rpOrigins:a=typeof window<"u"?[window.location.origin]:void 0,signal:l}={}},c){if(!i)return{data:null,error:new yo("rpId is required for WebAuthn authentication")};try{if(!Oc())return{data:null,error:new Vn("Browser does not support WebAuthn",null)};const{data:u,error:d}=await this.challenge({factorId:e,webauthn:{rpId:i,rpOrigins:a},signal:l},{request:c});if(!u)return{data:null,error:d};const{webauthn:m}=u;return this._verify({factorId:e,challengeId:u.challengeId,webauthn:{type:m.type,rpId:i,rpOrigins:a,credential_response:m.credential_response}})}catch(u){return te(u)?{data:null,error:u}:{data:null,error:new Vn("Unexpected error in authenticate",u)}}}async _register({friendlyName:e,webauthn:{rpId:i=typeof window<"u"?window.location.hostname:void 0,rpOrigins:a=typeof window<"u"?[window.location.origin]:void 0,signal:l}={}},c){if(!i)return{data:null,error:new yo("rpId is required for WebAuthn registration")};try{if(!Oc())return{data:null,error:new Vn("Browser does not support WebAuthn",null)};const{data:u,error:d}=await this._enroll({friendlyName:e});if(!u)return await this.client.mfa.listFactors().then(y=>{var v;return(v=y.data)===null||v===void 0?void 0:v.all.find(x=>x.factor_type==="webauthn"&&x.friendly_name===e&&x.status!=="unverified")}).then(y=>y?this.client.mfa.unenroll({factorId:y==null?void 0:y.id}):void 0),{data:null,error:d};const{data:m,error:p}=await this._challenge({factorId:u.id,friendlyName:u.friendly_name,webauthn:{rpId:i,rpOrigins:a},signal:l},{create:c});return m?this._verify({factorId:u.id,challengeId:m.challengeId,webauthn:{rpId:i,rpOrigins:a,type:m.webauthn.type,credential_response:m.webauthn.credential_response}}):{data:null,error:p}}catch(u){return te(u)?{data:null,error:u}:{data:null,error:new Vn("Unexpected error in register",u)}}}}_k();const Mk={url:LR,storageKey:zR,autoRefreshToken:!0,persistSession:!0,detectSessionInUrl:!0,headers:PR,flowType:"implicit",debug:!1,hasCustomAuthorizationHeader:!1,throwOnError:!1,lockAcquireTimeout:5e3,skipAutoInitialize:!1,experimental:{}},Na={};class bo{get jwks(){var e,i;return(i=(e=Na[this.storageKey])===null||e===void 0?void 0:e.jwks)!==null&&i!==void 0?i:{keys:[]}}set jwks(e){Na[this.storageKey]=Object.assign(Object.assign({},Na[this.storageKey]),{jwks:e})}get jwks_cached_at(){var e,i;return(i=(e=Na[this.storageKey])===null||e===void 0?void 0:e.cachedAt)!==null&&i!==void 0?i:Number.MIN_SAFE_INTEGER}set jwks_cached_at(e){Na[this.storageKey]=Object.assign(Object.assign({},Na[this.storageKey]),{cachedAt:e})}constructor(e){var i,a,l;this.userStorage=null,this.memoryStorage=null,this.stateChangeEmitters=new Map,this.autoRefreshTicker=null,this.autoRefreshTickTimeout=null,this.visibilityChangedCallback=null,this.refreshingDeferred=null,this.lastRefreshFailure=null,this._sessionRemovalEpoch=0,this.initializePromise=null,this._pendingInitNotifications=null,this.detectSessionInUrl=!0,this.hasCustomAuthorizationHeader=!1,this.suppressGetSessionWarning=!1,this.lock=null,this.lockAcquired=!1,this.pendingInLock=[],this.broadcastChannel=null,this.logger=console.log;const c=Object.assign(Object.assign({},Mk),e);if(this.storageKey=c.storageKey,this.instanceID=(i=bo.nextInstanceID[this.storageKey])!==null&&i!==void 0?i:0,bo.nextInstanceID[this.storageKey]=this.instanceID+1,this.logDebugMessages=!!c.debug,typeof c.debug=="function"&&(this.logger=c.debug),this.instanceID>0&&Pt()){const u=`${this._logPrefix()} Multiple GoTrueClient instances detected in the same browser context. It is not an error, but this should be avoided as it may produce undefined behavior when used concurrently under the same storage key.`;console.warn(u),this.logDebugMessages&&console.trace(u)}if(this.persistSession=c.persistSession,this.autoRefreshToken=c.autoRefreshToken,this.experimental=(a=c.experimental)!==null&&a!==void 0?a:{},this.admin=new xk({url:c.url,headers:c.headers,fetch:c.fetch,experimental:this.experimental}),this.url=c.url,this.headers=c.headers,this.fetch=Nw(c.fetch),this.detectSessionInUrl=c.detectSessionInUrl,this.flowType=c.flowType,this.hasCustomAuthorizationHeader=c.hasCustomAuthorizationHeader,this.throwOnError=c.throwOnError,this.lockAcquireTimeout=c.lockAcquireTimeout,c.lock!=null&&(this.lock=c.lock),this.jwks||(this.jwks={keys:[]},this.jwks_cached_at=Number.MIN_SAFE_INTEGER),this.mfa={verify:this._verify.bind(this),enroll:this._enroll.bind(this),unenroll:this._unenroll.bind(this),challenge:this._challenge.bind(this),listFactors:this._listFactors.bind(this),challengeAndVerify:this._challengeAndVerify.bind(this),getAuthenticatorAssuranceLevel:this._getAuthenticatorAssuranceLevel.bind(this),webauthn:new Dk(this)},this.oauth={getAuthorizationDetails:this._getAuthorizationDetails.bind(this),approveAuthorization:this._approveAuthorization.bind(this),denyAuthorization:this._denyAuthorization.bind(this),listGrants:this._listOAuthGrants.bind(this),revokeGrant:this._revokeOAuthGrant.bind(this)},this.passkey={startRegistration:this._startPasskeyRegistration.bind(this),verifyRegistration:this._verifyPasskeyRegistration.bind(this),startAuthentication:this._startPasskeyAuthentication.bind(this),verifyAuthentication:this._verifyPasskeyAuthentication.bind(this),list:this._listPasskeys.bind(this),update:this._updatePasskey.bind(this),delete:this._deletePasskey.bind(this)},this.persistSession?(c.storage?this.storage=c.storage:jw()?this.storage=globalThis.localStorage:(this.memoryStorage={},this.storage=Xb(this.memoryStorage)),c.userStorage&&(this.userStorage=c.userStorage)):(this.memoryStorage={},this.storage=Xb(this.memoryStorage)),Pt()&&globalThis.BroadcastChannel&&this.persistSession&&this.storageKey){try{this.broadcastChannel=new globalThis.BroadcastChannel(this.storageKey)}catch(u){console.error("Failed to create a new BroadcastChannel, multi-tab state changes will not be available",u)}(l=this.broadcastChannel)===null||l===void 0||l.addEventListener("message",async u=>{this._debug("received broadcast notification from other tab or client",u),(u.data.event==="TOKEN_REFRESHED"||u.data.event==="SIGNED_IN")&&(this.lastRefreshFailure=null);try{await this._notifyAllSubscribers(u.data.event,u.data.session,!1)}catch(d){this._debug("#broadcastChannel","error",d)}})}c.skipAutoInitialize||this.initialize().catch(u=>{this._debug("#initialize()","error",u)})}isThrowOnErrorEnabled(){return this.throwOnError}_returnResult(e){if(this.throwOnError&&e&&e.error)throw e.error;return e}_logPrefix(){return`GoTrueClient@${this.storageKey}:${this.instanceID} (${Tw}) ${new Date().toISOString()}`}_debug(...e){return this.logDebugMessages&&this.logger(this._logPrefix(),...e),this}async initialize(){var e;if(this.initializePromise)return await this.initializePromise;this._pendingInitNotifications=[],this.initializePromise=(async()=>this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._initialize()):await this._initialize())();const i=await this.initializePromise,a=(e=this._pendingInitNotifications)!==null&&e!==void 0?e:[];this._pendingInitNotifications=null;for(const l of a)await this._notifyAllSubscribers(l.event,l.session,l.broadcast);return i}async _initialize(){var e;try{let i={},a="none";if(Pt()&&(i=ek(window.location.href),this._isImplicitGrantCallback(i)?a="implicit":await this._isPKCECallback(i)&&(a="pkce")),Pt()&&this.detectSessionInUrl&&a!=="none"){const{data:l,error:c}=await this._getSessionFromURL(i,a);if(c){if(this._debug("#_initialize()","error detecting session from URL",c),FR(c)){const m=(e=c.details)===null||e===void 0?void 0:e.code;if(m==="identity_already_exists"||m==="identity_not_found"||m==="single_identity_not_deletable")return{error:c}}return{error:c}}const{session:u,redirectType:d}=l;return this._debug("#_initialize()","detected session in URL",u,"redirect type",d),await this._saveSession(u),setTimeout(async()=>{d==="recovery"?await this._notifyAllSubscribers("PASSWORD_RECOVERY",u):await this._notifyAllSubscribers("SIGNED_IN",u)},0),{error:null}}return await this._recoverAndRefresh(),{error:null}}catch(i){return te(i)?this._returnResult({error:i}):this._returnResult({error:new Vn("Unexpected error during initialization",i)})}finally{await this._handleVisibilityChange(),this._debug("#_initialize()","end")}}async signInAnonymously(e){var i,a,l;try{const c=await oe(this.fetch,"POST",`${this.url}/signup`,{headers:this.headers,body:{data:(a=(i=e==null?void 0:e.options)===null||i===void 0?void 0:i.data)!==null&&a!==void 0?a:{},gotrue_meta_security:{captcha_token:(l=e==null?void 0:e.options)===null||l===void 0?void 0:l.captchaToken}},xform:Sn}),{data:u,error:d}=c;if(d||!u)return this._returnResult({data:{user:null,session:null},error:d});const m=u.session,p=u.user;return u.session&&(await this._saveSession(u.session),await this._notifyAllSubscribers("SIGNED_IN",m)),this._returnResult({data:{user:p,session:m},error:null})}catch(c){if(te(c))return this._returnResult({data:{user:null,session:null},error:c});throw c}}async signUp(e){var i,a,l;try{let c;if("email"in e){const{email:y,password:v,options:x}=e;let _=null,S=null;this.flowType==="pkce"&&([_,S]=await Di(this.storage,this.storageKey)),c=await oe(this.fetch,"POST",`${this.url}/signup`,{headers:this.headers,redirectTo:x==null?void 0:x.emailRedirectTo,body:{email:y,password:v,data:(i=x==null?void 0:x.data)!==null&&i!==void 0?i:{},gotrue_meta_security:{captcha_token:x==null?void 0:x.captchaToken},code_challenge:_,code_challenge_method:S},xform:Sn})}else if("phone"in e){const{phone:y,password:v,options:x}=e;c=await oe(this.fetch,"POST",`${this.url}/signup`,{headers:this.headers,body:{phone:y,password:v,data:(a=x==null?void 0:x.data)!==null&&a!==void 0?a:{},channel:(l=x==null?void 0:x.channel)!==null&&l!==void 0?l:"sms",gotrue_meta_security:{captcha_token:x==null?void 0:x.captchaToken}},xform:Sn})}else throw new tc("You must provide either an email or phone number and a password");const{data:u,error:d}=c;if(d||!u)return await pt(this.storage,`${this.storageKey}-code-verifier`),this._returnResult({data:{user:null,session:null},error:d});const m=u.session,p=u.user;return u.session&&(await this._saveSession(u.session),await this._notifyAllSubscribers("SIGNED_IN",m)),this._returnResult({data:{user:p,session:m},error:null})}catch(c){if(await pt(this.storage,`${this.storageKey}-code-verifier`),te(c))return this._returnResult({data:{user:null,session:null},error:c});throw c}}async signInWithPassword(e){try{let i;if("email"in e){const{email:c,password:u,options:d}=e;i=await oe(this.fetch,"POST",`${this.url}/token?grant_type=password`,{headers:this.headers,body:{email:c,password:u,gotrue_meta_security:{captcha_token:d==null?void 0:d.captchaToken}},xform:Kb})}else if("phone"in e){const{phone:c,password:u,options:d}=e;i=await oe(this.fetch,"POST",`${this.url}/token?grant_type=password`,{headers:this.headers,body:{phone:c,password:u,gotrue_meta_security:{captcha_token:d==null?void 0:d.captchaToken}},xform:Kb})}else throw new tc("You must provide either an email or phone number and a password");const{data:a,error:l}=i;if(l)return this._returnResult({data:{user:null,session:null},error:l});if(!a||!a.session||!a.user){const c=new ja;return this._returnResult({data:{user:null,session:null},error:c})}return a.session&&(await this._saveSession(a.session),await this._notifyAllSubscribers("SIGNED_IN",a.session)),this._returnResult({data:Object.assign({user:a.user,session:a.session},a.weak_password?{weakPassword:a.weak_password}:null),error:l})}catch(i){if(te(i))return this._returnResult({data:{user:null,session:null},error:i});throw i}}async signInWithOAuth(e){var i,a,l,c;return await this._handleProviderSignIn(e.provider,{redirectTo:(i=e.options)===null||i===void 0?void 0:i.redirectTo,scopes:(a=e.options)===null||a===void 0?void 0:a.scopes,queryParams:(l=e.options)===null||l===void 0?void 0:l.queryParams,skipBrowserRedirect:(c=e.options)===null||c===void 0?void 0:c.skipBrowserRedirect})}async exchangeCodeForSession(e){return await this.initializePromise,this.lock!=null?this._acquireLock(this.lockAcquireTimeout,async()=>this._exchangeCodeForSession(e)):this._exchangeCodeForSession(e)}async signInWithWeb3(e){const{chain:i}=e;switch(i){case"ethereum":return await this.signInWithEthereum(e);case"solana":return await this.signInWithSolana(e);default:throw new Error(`@supabase/auth-js: Unsupported chain "${i}"`)}}async signInWithEthereum(e){var i,a,l,c,u,d,m,p,y,v,x;let _,S;if("message"in e)_=e.message,S=e.signature;else{const{chain:T,wallet:j,statement:k,options:M}=e;let C;if(Pt())if(typeof j=="object")C=j;else{const Z=window;if("ethereum"in Z&&typeof Z.ethereum=="object"&&"request"in Z.ethereum&&typeof Z.ethereum.request=="function")C=Z.ethereum;else throw new Error("@supabase/auth-js: No compatible Ethereum wallet interface on the window object (window.ethereum) detected. Make sure the user already has a wallet installed and connected for this app. Prefer passing the wallet interface object directly to signInWithWeb3({ chain: 'ethereum', wallet: resolvedUserWallet }) instead.")}else{if(typeof j!="object"||!(M!=null&&M.url))throw new Error("@supabase/auth-js: Both wallet and url must be specified in non-browser environments.");C=j}const P=new URL((i=M==null?void 0:M.url)!==null&&i!==void 0?i:window.location.href),K=await C.request({method:"eth_requestAccounts"}).then(Z=>Z).catch(()=>{throw new Error("@supabase/auth-js: Wallet method eth_requestAccounts is missing or invalid")});if(!K||K.length===0)throw new Error("@supabase/auth-js: No accounts available. Please ensure the wallet is connected.");const G=Rw(K[0]);let H=(a=M==null?void 0:M.signInWithEthereum)===null||a===void 0?void 0:a.chainId;if(!H){const Z=await C.request({method:"eth_chainId"});H=Sk(Z)}const Y={domain:P.host,address:G,statement:k,uri:P.href,version:"1",chainId:H,nonce:(l=M==null?void 0:M.signInWithEthereum)===null||l===void 0?void 0:l.nonce,issuedAt:(u=(c=M==null?void 0:M.signInWithEthereum)===null||c===void 0?void 0:c.issuedAt)!==null&&u!==void 0?u:new Date,expirationTime:(d=M==null?void 0:M.signInWithEthereum)===null||d===void 0?void 0:d.expirationTime,notBefore:(m=M==null?void 0:M.signInWithEthereum)===null||m===void 0?void 0:m.notBefore,requestId:(p=M==null?void 0:M.signInWithEthereum)===null||p===void 0?void 0:p.requestId,resources:(y=M==null?void 0:M.signInWithEthereum)===null||y===void 0?void 0:y.resources};_=Ek(Y),S=await C.request({method:"personal_sign",params:[Tk(_),G]})}try{const{data:T,error:j}=await oe(this.fetch,"POST",`${this.url}/token?grant_type=web3`,{headers:this.headers,body:Object.assign({chain:"ethereum",message:_,signature:S},!((v=e.options)===null||v===void 0)&&v.captchaToken?{gotrue_meta_security:{captcha_token:(x=e.options)===null||x===void 0?void 0:x.captchaToken}}:null),xform:Sn});if(j)throw j;if(!T||!T.session||!T.user){const k=new ja;return this._returnResult({data:{user:null,session:null},error:k})}return T.session&&(await this._saveSession(T.session),await this._notifyAllSubscribers("SIGNED_IN",T.session)),this._returnResult({data:Object.assign({},T),error:j})}catch(T){if(te(T))return this._returnResult({data:{user:null,session:null},error:T});throw T}}async signInWithSolana(e){var i,a,l,c,u,d,m,p,y,v,x,_;let S,T;if("message"in e)S=e.message,T=e.signature;else{const{chain:j,wallet:k,statement:M,options:C}=e;let P;if(Pt())if(typeof k=="object")P=k;else{const G=window;if("solana"in G&&typeof G.solana=="object"&&("signIn"in G.solana&&typeof G.solana.signIn=="function"||"signMessage"in G.solana&&typeof G.solana.signMessage=="function"))P=G.solana;else throw new Error("@supabase/auth-js: No compatible Solana wallet interface on the window object (window.solana) detected. Make sure the user already has a wallet installed and connected for this app. Prefer passing the wallet interface object directly to signInWithWeb3({ chain: 'solana', wallet: resolvedUserWallet }) instead.")}else{if(typeof k!="object"||!(C!=null&&C.url))throw new Error("@supabase/auth-js: Both wallet and url must be specified in non-browser environments.");P=k}const K=new URL((i=C==null?void 0:C.url)!==null&&i!==void 0?i:window.location.href);if("signIn"in P&&P.signIn){const G=await P.signIn(Object.assign(Object.assign(Object.assign({issuedAt:new Date().toISOString()},C==null?void 0:C.signInWithSolana),{version:"1",domain:K.host,uri:K.href}),M?{statement:M}:null));let H;if(Array.isArray(G)&&G[0]&&typeof G[0]=="object")H=G[0];else if(G&&typeof G=="object"&&"signedMessage"in G&&"signature"in G)H=G;else throw new Error("@supabase/auth-js: Wallet method signIn() returned unrecognized value");if("signedMessage"in H&&"signature"in H&&(typeof H.signedMessage=="string"||H.signedMessage instanceof Uint8Array)&&H.signature instanceof Uint8Array)S=typeof H.signedMessage=="string"?H.signedMessage:new TextDecoder().decode(H.signedMessage),T=H.signature;else throw new Error("@supabase/auth-js: Wallet method signIn() API returned object without signedMessage and signature fields")}else{if(!("signMessage"in P)||typeof P.signMessage!="function"||!("publicKey"in P)||typeof P!="object"||!P.publicKey||!("toBase58"in P.publicKey)||typeof P.publicKey.toBase58!="function")throw new Error("@supabase/auth-js: Wallet does not have a compatible signMessage() and publicKey.toBase58() API");S=[`${K.host} wants you to sign in with your Solana account:`,P.publicKey.toBase58(),...M?["",M,""]:[""],"Version: 1",`URI: ${K.href}`,`Issued At: ${(l=(a=C==null?void 0:C.signInWithSolana)===null||a===void 0?void 0:a.issuedAt)!==null&&l!==void 0?l:new Date().toISOString()}`,...!((c=C==null?void 0:C.signInWithSolana)===null||c===void 0)&&c.notBefore?[`Not Before: ${C.signInWithSolana.notBefore}`]:[],...!((u=C==null?void 0:C.signInWithSolana)===null||u===void 0)&&u.expirationTime?[`Expiration Time: ${C.signInWithSolana.expirationTime}`]:[],...!((d=C==null?void 0:C.signInWithSolana)===null||d===void 0)&&d.chainId?[`Chain ID: ${C.signInWithSolana.chainId}`]:[],...!((m=C==null?void 0:C.signInWithSolana)===null||m===void 0)&&m.nonce?[`Nonce: ${C.signInWithSolana.nonce}`]:[],...!((p=C==null?void 0:C.signInWithSolana)===null||p===void 0)&&p.requestId?[`Request ID: ${C.signInWithSolana.requestId}`]:[],...!((v=(y=C==null?void 0:C.signInWithSolana)===null||y===void 0?void 0:y.resources)===null||v===void 0)&&v.length?["Resources",...C.signInWithSolana.resources.map(H=>`- ${H}`)]:[]].join(` +`);const G=await P.signMessage(new TextEncoder().encode(S),"utf8");if(!G||!(G instanceof Uint8Array))throw new Error("@supabase/auth-js: Wallet signMessage() API returned an recognized value");T=G}}try{const{data:j,error:k}=await oe(this.fetch,"POST",`${this.url}/token?grant_type=web3`,{headers:this.headers,body:Object.assign({chain:"solana",message:S,signature:Pi(T)},!((x=e.options)===null||x===void 0)&&x.captchaToken?{gotrue_meta_security:{captcha_token:(_=e.options)===null||_===void 0?void 0:_.captchaToken}}:null),xform:Sn});if(k)throw k;if(!j||!j.session||!j.user){const M=new ja;return this._returnResult({data:{user:null,session:null},error:M})}return j.session&&(await this._saveSession(j.session),await this._notifyAllSubscribers("SIGNED_IN",j.session)),this._returnResult({data:Object.assign({},j),error:k})}catch(j){if(te(j))return this._returnResult({data:{user:null,session:null},error:j});throw j}}async _exchangeCodeForSession(e){const i=await Bn(this.storage,`${this.storageKey}-code-verifier`),[a,l]=(i??"").split("/");try{if(!a&&this.flowType==="pkce")throw new IR;const{data:c,error:u}=await oe(this.fetch,"POST",`${this.url}/token?grant_type=pkce`,{headers:this.headers,body:{auth_code:e,code_verifier:a},xform:Sn});if(await pt(this.storage,`${this.storageKey}-code-verifier`),u)throw u;if(!c||!c.session||!c.user){const d=new ja;return this._returnResult({data:{user:null,session:null,redirectType:null},error:d})}return c.session&&(await this._saveSession(c.session),await this._notifyAllSubscribers(l==="recovery"?"PASSWORD_RECOVERY":"SIGNED_IN",c.session)),this._returnResult({data:Object.assign(Object.assign({},c),{redirectType:l??null}),error:u})}catch(c){if(await pt(this.storage,`${this.storageKey}-code-verifier`),te(c))return this._returnResult({data:{user:null,session:null,redirectType:null},error:c});throw c}}async signInWithIdToken(e){try{const{options:i,provider:a,token:l,access_token:c,nonce:u}=e,d=await oe(this.fetch,"POST",`${this.url}/token?grant_type=id_token`,{headers:this.headers,body:{provider:a,id_token:l,access_token:c,nonce:u,gotrue_meta_security:{captcha_token:i==null?void 0:i.captchaToken}},xform:Sn}),{data:m,error:p}=d;if(p)return this._returnResult({data:{user:null,session:null},error:p});if(!m||!m.session||!m.user){const y=new ja;return this._returnResult({data:{user:null,session:null},error:y})}return m.session&&(await this._saveSession(m.session),await this._notifyAllSubscribers("SIGNED_IN",m.session)),this._returnResult({data:m,error:p})}catch(i){if(te(i))return this._returnResult({data:{user:null,session:null},error:i});throw i}}async signInWithOtp(e){var i,a,l,c,u;try{if("email"in e){const{email:d,options:m}=e;let p=null,y=null;this.flowType==="pkce"&&([p,y]=await Di(this.storage,this.storageKey));const{error:v}=await oe(this.fetch,"POST",`${this.url}/otp`,{headers:this.headers,body:{email:d,data:(i=m==null?void 0:m.data)!==null&&i!==void 0?i:{},create_user:(a=m==null?void 0:m.shouldCreateUser)!==null&&a!==void 0?a:!0,gotrue_meta_security:{captcha_token:m==null?void 0:m.captchaToken},code_challenge:p,code_challenge_method:y},redirectTo:m==null?void 0:m.emailRedirectTo});return this._returnResult({data:{user:null,session:null},error:v})}if("phone"in e){const{phone:d,options:m}=e,{data:p,error:y}=await oe(this.fetch,"POST",`${this.url}/otp`,{headers:this.headers,body:{phone:d,data:(l=m==null?void 0:m.data)!==null&&l!==void 0?l:{},create_user:(c=m==null?void 0:m.shouldCreateUser)!==null&&c!==void 0?c:!0,gotrue_meta_security:{captcha_token:m==null?void 0:m.captchaToken},channel:(u=m==null?void 0:m.channel)!==null&&u!==void 0?u:"sms"}});return this._returnResult({data:{user:null,session:null,messageId:p==null?void 0:p.message_id},error:y})}throw new tc("You must provide either an email or phone number.")}catch(d){if(await pt(this.storage,`${this.storageKey}-code-verifier`),te(d))return this._returnResult({data:{user:null,session:null},error:d});throw d}}async verifyOtp(e){var i,a;try{let l,c;"options"in e&&(l=(i=e.options)===null||i===void 0?void 0:i.redirectTo,c=(a=e.options)===null||a===void 0?void 0:a.captchaToken);const{data:u,error:d}=await oe(this.fetch,"POST",`${this.url}/verify`,{headers:this.headers,body:Object.assign(Object.assign({},e),{gotrue_meta_security:{captcha_token:c}}),redirectTo:l,xform:Sn});if(d)throw d;if(!u)throw new Error("An error occurred on token verification.");const m=u.session,p=u.user;return m!=null&&m.access_token&&(await this._saveSession(m),await this._notifyAllSubscribers(e.type=="recovery"?"PASSWORD_RECOVERY":"SIGNED_IN",m)),this._returnResult({data:{user:p,session:m},error:null})}catch(l){if(te(l))return this._returnResult({data:{user:null,session:null},error:l});throw l}}async signInWithSSO(e){var i,a,l,c,u;try{let d=null,m=null;this.flowType==="pkce"&&([d,m]=await Di(this.storage,this.storageKey));const p=await oe(this.fetch,"POST",`${this.url}/sso`,{body:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},"providerId"in e?{provider_id:e.providerId}:null),"domain"in e?{domain:e.domain}:null),{redirect_to:(a=(i=e.options)===null||i===void 0?void 0:i.redirectTo)!==null&&a!==void 0?a:void 0}),!((l=e==null?void 0:e.options)===null||l===void 0)&&l.captchaToken?{gotrue_meta_security:{captcha_token:e.options.captchaToken}}:null),{skip_http_redirect:!0,code_challenge:d,code_challenge_method:m}),headers:this.headers,xform:yk});return!((c=p.data)===null||c===void 0)&&c.url&&Pt()&&!(!((u=e.options)===null||u===void 0)&&u.skipBrowserRedirect)&&window.location.assign(p.data.url),this._returnResult(p)}catch(d){if(await pt(this.storage,`${this.storageKey}-code-verifier`),te(d))return this._returnResult({data:null,error:d});throw d}}async reauthenticate(){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._reauthenticate()):await this._reauthenticate()}async _reauthenticate(){try{return await this._useSession(async e=>{const{data:{session:i},error:a}=e;if(a)throw a;if(!i)throw new kt;const{error:l}=await oe(this.fetch,"GET",`${this.url}/reauthenticate`,{headers:this.headers,jwt:i.access_token});return this._returnResult({data:{user:null,session:null},error:l})})}catch(e){if(te(e))return this._returnResult({data:{user:null,session:null},error:e});throw e}}async resend(e){try{const i=`${this.url}/resend`;if("email"in e){const{email:a,type:l,options:c}=e;let u=null,d=null;this.flowType==="pkce"&&([u,d]=await Di(this.storage,this.storageKey));const{error:m}=await oe(this.fetch,"POST",i,{headers:this.headers,body:{email:a,type:l,gotrue_meta_security:{captcha_token:c==null?void 0:c.captchaToken},code_challenge:u,code_challenge_method:d},redirectTo:c==null?void 0:c.emailRedirectTo});return m&&await pt(this.storage,`${this.storageKey}-code-verifier`),this._returnResult({data:{user:null,session:null},error:m})}else if("phone"in e){const{phone:a,type:l,options:c}=e,{data:u,error:d}=await oe(this.fetch,"POST",i,{headers:this.headers,body:{phone:a,type:l,gotrue_meta_security:{captcha_token:c==null?void 0:c.captchaToken}}});return this._returnResult({data:{user:null,session:null,messageId:u==null?void 0:u.message_id},error:d})}throw new tc("You must provide either an email or phone number and a type")}catch(i){if(await pt(this.storage,`${this.storageKey}-code-verifier`),te(i))return this._returnResult({data:{user:null,session:null},error:i});throw i}}async getSession(){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>this._useSession(async e=>e)):await this._useSession(async e=>e)}async _acquireLock(e,i){this._debug("#_acquireLock","begin",e);try{if(this.lockAcquired){const a=this.pendingInLock.length?this.pendingInLock[this.pendingInLock.length-1]:Promise.resolve(),l=(async()=>(await a,await i()))();return this.pendingInLock.push((async()=>{try{await l}catch{}})()),l}return await this.lock(`lock:${this.storageKey}`,e,async()=>{this._debug("#_acquireLock","lock acquired for storage key",this.storageKey);try{this.lockAcquired=!0;const a=i();for(this.pendingInLock.push((async()=>{try{await a}catch{}})()),await a;this.pendingInLock.length;){const l=[...this.pendingInLock];await Promise.all(l),this.pendingInLock.splice(0,l.length)}return await a}finally{this._debug("#_acquireLock","lock released for storage key",this.storageKey),this.lockAcquired=!1}})}finally{this._debug("#_acquireLock","end")}}async _useSession(e){this._debug("#_useSession","begin");try{const i=await this.__loadSession();return await e(i)}finally{this._debug("#_useSession","end")}}async __loadSession(){this._debug("#__loadSession()","begin"),this.lock!=null&&!this.lockAcquired&&this._debug("#__loadSession()","used outside of an acquired lock!",new Error().stack);try{let e=null;const i=await Bn(this.storage,this.storageKey);if(this._debug("#getSession()","session from storage",i),i!==null&&(this._isValidSession(i)?e=i:(this._debug("#getSession()","session from storage is not valid"),await this._removeSession())),!e)return{data:{session:null},error:null};const a=e.expires_at?e.expires_at*1e3-Date.now()Date.now())){const d=await Bn(this.storage,this.storageKey);if(d&&d.refresh_token===e.refresh_token)return this._returnResult({data:{session:e},error:null})}return this._returnResult({data:{session:null},error:c})}return this._returnResult({data:{session:l},error:null})}finally{this._debug("#__loadSession()","end")}}async getUser(e){if(e)return await this._getUser(e);await this.initializePromise;let i;return this.lock!=null?i=await this._acquireLock(this.lockAcquireTimeout,async()=>await this._getUser()):i=await this._getUser(),i.data.user&&(this.suppressGetSessionWarning=!0),i}async _getUser(e){try{return e?await oe(this.fetch,"GET",`${this.url}/user`,{headers:this.headers,jwt:e,xform:ii}):await this._useSession(async i=>{var a,l,c;const{data:u,error:d}=i;if(d)throw d;return!(!((a=u.session)===null||a===void 0)&&a.access_token)&&!this.hasCustomAuthorizationHeader?{data:{user:null},error:new kt}:await oe(this.fetch,"GET",`${this.url}/user`,{headers:this.headers,jwt:(c=(l=u.session)===null||l===void 0?void 0:l.access_token)!==null&&c!==void 0?c:void 0,xform:ii})})}catch(i){if(te(i))return ec(i)&&(await this._removeSession(),await pt(this.storage,`${this.storageKey}-code-verifier`)),this._returnResult({data:{user:null},error:i});throw i}}async updateUser(e,i={}){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._updateUser(e,i)):await this._updateUser(e,i)}async _updateUser(e,i={}){try{return await this._useSession(async a=>{const{data:l,error:c}=a;if(c)throw c;if(!l.session)throw new kt;const u=l.session;let d=null,m=null;this.flowType==="pkce"&&e.email!=null&&([d,m]=await Di(this.storage,this.storageKey));const{data:p,error:y}=await oe(this.fetch,"PUT",`${this.url}/user`,{headers:this.headers,redirectTo:i==null?void 0:i.emailRedirectTo,body:Object.assign(Object.assign({},e),{code_challenge:d,code_challenge_method:m}),jwt:u.access_token,xform:ii});if(y)throw y;return u.user=p.user,await this._saveSession(u),await this._notifyAllSubscribers("USER_UPDATED",u),this._returnResult({data:{user:u.user},error:null})})}catch(a){if(await pt(this.storage,`${this.storageKey}-code-verifier`),te(a))return this._returnResult({data:{user:null},error:a});throw a}}async setSession(e){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._setSession(e)):await this._setSession(e)}async _setSession(e){try{if(!e.access_token||!e.refresh_token)throw new kt;const i=Date.now()/1e3;let a=i,l=!0,c=null;const{payload:u}=sc(e.access_token);if(u.exp&&(a=u.exp,l=a<=i),l){const{data:d,error:m}=await this._callRefreshToken(e.refresh_token);if(m)return this._returnResult({data:{user:null,session:null},error:m});if(!d)return{data:{user:null,session:null},error:null};c=d}else{const{data:d,error:m}=await this._getUser(e.access_token);if(m)return this._returnResult({data:{user:null,session:null},error:m});c={access_token:e.access_token,refresh_token:e.refresh_token,user:d.user,token_type:"bearer",expires_in:a-i,expires_at:a},await this._saveSession(c),await this._notifyAllSubscribers("SIGNED_IN",c)}return this._returnResult({data:{user:c.user,session:c},error:null})}catch(i){if(te(i))return this._returnResult({data:{session:null,user:null},error:i});throw i}}async refreshSession(e){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._refreshSession(e)):await this._refreshSession(e)}async _refreshSession(e){try{return await this._useSession(async i=>{var a;if(!e){const{data:u,error:d}=i;if(d)throw d;e=(a=u.session)!==null&&a!==void 0?a:void 0}if(!(e!=null&&e.refresh_token))throw new kt;const{data:l,error:c}=await this._callRefreshToken(e.refresh_token);return c?this._returnResult({data:{user:null,session:null},error:c}):l?this._returnResult({data:{user:l.user,session:l},error:null}):this._returnResult({data:{user:null,session:null},error:null})})}catch(i){if(te(i))return this._returnResult({data:{user:null,session:null},error:i});throw i}}async _getSessionFromURL(e,i){var a;try{if(!Pt())throw new nc("No browser detected.");if(e.error||e.error_description||e.error_code)throw new nc(e.error_description||"Error in URL with unspecified error_description",{error:e.error||"unspecified_error",code:e.error_code||"unspecified_code"});switch(i){case"implicit":if(this.flowType==="pkce")throw new zb("Not a valid PKCE flow url.");break;case"pkce":if(this.flowType==="implicit")throw new nc("Not a valid implicit grant flow url.");break;default:}if(i==="pkce"){if(this._debug("#_initialize()","begin","is PKCE flow",!0),!e.code)throw new zb("No code detected.");const{data:C,error:P}=await this._exchangeCodeForSession(e.code);if(P)throw P;const K=new URL(window.location.href);return K.searchParams.delete("code"),window.history.replaceState(window.history.state,"",K.toString()),{data:{session:C.session,redirectType:(a=C.redirectType)!==null&&a!==void 0?a:null},error:null}}const{provider_token:l,provider_refresh_token:c,access_token:u,refresh_token:d,expires_in:m,expires_at:p,token_type:y}=e;if(!u||!m||!d||!y)throw new nc("No session defined in URL");const v=Math.round(Date.now()/1e3),x=parseInt(m);let _=v+x;p&&(_=parseInt(p));const S=_-v;S*1e3<=ks&&console.warn(`@supabase/gotrue-js: Session as retrieved from URL expires in ${S}s, should have been closer to ${x}s`);const T=_-x;v-T>=120?console.warn("@supabase/gotrue-js: Session as retrieved from URL was issued over 120s ago, URL could be stale",T,_,v):v-T<0&&console.warn("@supabase/gotrue-js: Session as retrieved from URL was issued in the future? Check the device clock for skew",T,_,v);const{data:j,error:k}=await this._getUser(u);if(k)throw k;const M={provider_token:l,provider_refresh_token:c,access_token:u,expires_in:x,expires_at:_,refresh_token:d,token_type:y,user:j.user};return window.location.hash="",this._debug("#_getSessionFromURL()","clearing window.location.hash"),this._returnResult({data:{session:M,redirectType:e.type},error:null})}catch(l){if(te(l))return this._returnResult({data:{session:null,redirectType:null},error:l});throw l}}_isImplicitGrantCallback(e){return typeof this.detectSessionInUrl=="function"?this.detectSessionInUrl(new URL(window.location.href),e):!!(e.access_token||e.error||e.error_description||e.error_code)}async _isPKCECallback(e){const i=await Bn(this.storage,`${this.storageKey}-code-verifier`);return!!(e.code&&i)}async signOut(e={scope:"global"}){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._signOut(e)):await this._signOut(e)}async _signOut({scope:e}={scope:"global"}){return await this._useSession(async i=>{var a;const l=async()=>{await this._removeSession(),await pt(this.storage,`${this.storageKey}-code-verifier`)},{data:c,error:u}=i;if(u&&!ec(u))return this._returnResult({error:u});const d=(a=c.session)===null||a===void 0?void 0:a.access_token;if(d){const{error:m}=await this.admin.signOut(d,e);if(m&&!(qR(m)&&(m.status===404||m.status===401||m.status===403)||ec(m)))return e!=="others"&&await l(),this._returnResult({error:m})}return e!=="others"&&await l(),this._returnResult({error:null})})}onAuthStateChange(e){const i=WR(),a={id:i,callback:e,unsubscribe:()=>{this._debug("#unsubscribe()","state change callback with id removed",i),this.stateChangeEmitters.delete(i)}};return this._debug("#onAuthStateChange()","registered callback with id",i),this.stateChangeEmitters.set(i,a),(async()=>(await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>{this._emitInitialSession(i)}):await this._emitInitialSession(i)))(),{data:{subscription:a}}}async _emitInitialSession(e){return await this._useSession(async i=>{var a,l;try{const{data:{session:c},error:u}=i;if(u)throw u;await((a=this.stateChangeEmitters.get(e))===null||a===void 0?void 0:a.callback("INITIAL_SESSION",c)),this._debug("INITIAL_SESSION","callback id",e,"session",c)}catch(c){await((l=this.stateChangeEmitters.get(e))===null||l===void 0?void 0:l.callback("INITIAL_SESSION",null)),this._debug("INITIAL_SESSION","callback id",e,"error",c),ec(c)?console.warn(c):console.error(c)}})}async resetPasswordForEmail(e,i={}){let a=null,l=null;this.flowType==="pkce"&&([a,l]=await Di(this.storage,this.storageKey,!0));try{return await oe(this.fetch,"POST",`${this.url}/recover`,{body:{email:e,code_challenge:a,code_challenge_method:l,gotrue_meta_security:{captcha_token:i.captchaToken}},headers:this.headers,redirectTo:i.redirectTo})}catch(c){if(await pt(this.storage,`${this.storageKey}-code-verifier`),te(c))return this._returnResult({data:null,error:c});throw c}}async getUserIdentities(){var e;try{const{data:i,error:a}=await this.getUser();if(a)throw a;return this._returnResult({data:{identities:(e=i.user.identities)!==null&&e!==void 0?e:[]},error:null})}catch(i){if(te(i))return this._returnResult({data:null,error:i});throw i}}async linkIdentity(e){return"token"in e?this.linkIdentityIdToken(e):this.linkIdentityOAuth(e)}async linkIdentityOAuth(e){var i;try{const{data:a,error:l}=await this._useSession(async c=>{var u,d,m,p,y;const{data:v,error:x}=c;if(x)throw x;const _=await this._getUrlForProvider(`${this.url}/user/identities/authorize`,e.provider,{redirectTo:(u=e.options)===null||u===void 0?void 0:u.redirectTo,scopes:(d=e.options)===null||d===void 0?void 0:d.scopes,queryParams:(m=e.options)===null||m===void 0?void 0:m.queryParams,skipBrowserRedirect:!0});return await oe(this.fetch,"GET",_,{headers:this.headers,jwt:(y=(p=v.session)===null||p===void 0?void 0:p.access_token)!==null&&y!==void 0?y:void 0})});if(l)throw l;return Pt()&&!(!((i=e.options)===null||i===void 0)&&i.skipBrowserRedirect)&&window.location.assign(a==null?void 0:a.url),this._returnResult({data:{provider:e.provider,url:a==null?void 0:a.url},error:null})}catch(a){if(te(a))return this._returnResult({data:{provider:e.provider,url:null},error:a});throw a}}async linkIdentityIdToken(e){return await this._useSession(async i=>{var a;try{const{error:l,data:{session:c}}=i;if(l)throw l;const{options:u,provider:d,token:m,access_token:p,nonce:y}=e,v=await oe(this.fetch,"POST",`${this.url}/token?grant_type=id_token`,{headers:this.headers,jwt:(a=c==null?void 0:c.access_token)!==null&&a!==void 0?a:void 0,body:{provider:d,id_token:m,access_token:p,nonce:y,link_identity:!0,gotrue_meta_security:{captcha_token:u==null?void 0:u.captchaToken}},xform:Sn}),{data:x,error:_}=v;return _?this._returnResult({data:{user:null,session:null},error:_}):!x||!x.session||!x.user?this._returnResult({data:{user:null,session:null},error:new ja}):(x.session&&(await this._saveSession(x.session),await this._notifyAllSubscribers("USER_UPDATED",x.session)),this._returnResult({data:x,error:_}))}catch(l){if(await pt(this.storage,`${this.storageKey}-code-verifier`),te(l))return this._returnResult({data:{user:null,session:null},error:l});throw l}})}async unlinkIdentity(e){try{return await this._useSession(async i=>{var a,l;const{data:c,error:u}=i;if(u)throw u;return await oe(this.fetch,"DELETE",`${this.url}/user/identities/${e.identity_id}`,{headers:this.headers,jwt:(l=(a=c.session)===null||a===void 0?void 0:a.access_token)!==null&&l!==void 0?l:void 0})})}catch(i){if(te(i))return this._returnResult({data:null,error:i});throw i}}async _refreshAccessToken(e){const i="#_refreshAccessToken()";this._debug(i,"begin");try{const a=Date.now();return await sk(async l=>(l>0&&await nk(200*Math.pow(2,l-1)),this._debug(i,"refreshing attempt",l),await oe(this.fetch,"POST",`${this.url}/token?grant_type=refresh_token`,{body:{refresh_token:e},headers:this.headers,xform:Sn})),(l,c)=>{const u=200*Math.pow(2,l);return c&&Pb(c)&&Date.now()+u-aDate.now())?this._debug(l,"proactive refresh failed, access token still valid — preserving session"):await this._removeSession()}return this.lastRefreshFailure={refreshToken:e,result:u,expiresAt:Date.now()+UR},(i=this.refreshingDeferred)===null||i===void 0||i.resolve(u),u}throw(a=this.refreshingDeferred)===null||a===void 0||a.reject(c),c}finally{this.refreshingDeferred=null,this._debug(l,"end")}}async _notifyAllSubscribers(e,i,a=!0){if(this._pendingInitNotifications!==null&&a){this._pendingInitNotifications.push({event:e,session:i,broadcast:a});return}const l=`#_notifyAllSubscribers(${e})`;this._debug(l,"begin",i,`broadcast = ${a}`);try{this.broadcastChannel&&a&&this.broadcastChannel.postMessage({event:e,session:i});const c=[],u=Array.from(this.stateChangeEmitters.values()).map(async d=>{try{await d.callback(e,i)}catch(m){c.push(m)}});if(await Promise.all(u),c.length>0){for(let d=0;dthis._autoRefreshTokenTick(),ks);this.autoRefreshTicker=e,e&&typeof e=="object"&&typeof e.unref=="function"?e.unref():typeof Deno<"u"&&typeof Deno.unrefTimer=="function"&&Deno.unrefTimer(e);const i=setTimeout(async()=>{await this.initializePromise,await this._autoRefreshTokenTick()},0);this.autoRefreshTickTimeout=i,i&&typeof i=="object"&&typeof i.unref=="function"?i.unref():typeof Deno<"u"&&typeof Deno.unrefTimer=="function"&&Deno.unrefTimer(i)}async _stopAutoRefresh(){this._debug("#_stopAutoRefresh()");const e=this.autoRefreshTicker;this.autoRefreshTicker=null,e&&clearInterval(e);const i=this.autoRefreshTickTimeout;this.autoRefreshTickTimeout=null,i&&clearTimeout(i)}async startAutoRefresh(){this._removeVisibilityChangedCallback(),await this._startAutoRefresh()}async stopAutoRefresh(){this._removeVisibilityChangedCallback(),await this._stopAutoRefresh()}async dispose(){var e;this._removeVisibilityChangedCallback(),await this._stopAutoRefresh(),(e=this.broadcastChannel)===null||e===void 0||e.close(),this.broadcastChannel=null,this.stateChangeEmitters.clear()}async _autoRefreshTokenTick(){if(this._debug("#_autoRefreshTokenTick()","begin"),this.lock!=null){try{await this._acquireLock(0,async()=>{try{const e=Date.now();try{return await this._useSession(async i=>{const{data:{session:a}}=i;if(!a||!a.refresh_token||!a.expires_at){this._debug("#_autoRefreshTokenTick()","no session");return}const l=Math.floor((a.expires_at*1e3-e)/ks);this._debug("#_autoRefreshTokenTick()",`access token expires in ${l} ticks, a tick lasts ${ks}ms, refresh threshold is ${Qr} ticks`),l<=Qr&&await this._callRefreshToken(a.refresh_token)})}catch(i){console.error("Auto refresh tick failed with error. This is likely a transient error.",i)}}finally{this._debug("#_autoRefreshTokenTick()","end")}})}catch(e){if(e instanceof wk)this._debug("auto refresh token tick lock not available");else throw e}return}if(this.refreshingDeferred!==null){this._debug("#_autoRefreshTokenTick()","refresh already in flight, skipping");return}try{const e=Date.now();try{await this._useSession(async i=>{const{data:{session:a}}=i;if(!a||!a.refresh_token||!a.expires_at){this._debug("#_autoRefreshTokenTick()","no session");return}const l=Math.floor((a.expires_at*1e3-e)/ks);this._debug("#_autoRefreshTokenTick()",`access token expires in ${l} ticks, a tick lasts ${ks}ms, refresh threshold is ${Qr} ticks`),l<=Qr&&await this._callRefreshToken(a.refresh_token)})}catch(i){console.error("Auto refresh tick failed with error. This is likely a transient error.",i)}}finally{this._debug("#_autoRefreshTokenTick()","end")}}async _handleVisibilityChange(){if(this._debug("#_handleVisibilityChange()"),!Pt()||!(window!=null&&window.addEventListener))return this.autoRefreshToken&&this.startAutoRefresh(),!1;try{this.visibilityChangedCallback=async()=>{try{await this._onVisibilityChanged(!1)}catch(e){this._debug("#visibilityChangedCallback","error",e)}},window==null||window.addEventListener("visibilitychange",this.visibilityChangedCallback),await this._onVisibilityChanged(!0)}catch(e){console.error("_handleVisibilityChange",e)}}async _onVisibilityChanged(e){const i=`#_onVisibilityChanged(${e})`;if(this._debug(i,"visibilityState",document.visibilityState),document.visibilityState==="visible"){if(this.autoRefreshToken&&this._startAutoRefresh(),!e)if(await this.initializePromise,this.lock!=null)await this._acquireLock(this.lockAcquireTimeout,async()=>{if(document.visibilityState!=="visible"){this._debug(i,"acquired the lock to recover the session, but the browser visibilityState is no longer visible, aborting");return}await this._recoverAndRefresh()});else{if(document.visibilityState!=="visible"){this._debug(i,"visibilityState is no longer visible, skipping recovery");return}await this._recoverAndRefresh()}}else document.visibilityState==="hidden"&&this.autoRefreshToken&&this._stopAutoRefresh()}async _getUrlForProvider(e,i,a){const l=[`provider=${encodeURIComponent(i)}`];if(a!=null&&a.redirectTo&&l.push(`redirect_to=${encodeURIComponent(a.redirectTo)}`),a!=null&&a.scopes&&l.push(`scopes=${encodeURIComponent(a.scopes)}`),this.flowType==="pkce"){const[c,u]=await Di(this.storage,this.storageKey),d=new URLSearchParams({code_challenge:`${encodeURIComponent(c)}`,code_challenge_method:`${encodeURIComponent(u)}`});l.push(d.toString())}if(a!=null&&a.queryParams){const c=new URLSearchParams(a.queryParams);l.push(c.toString())}return a!=null&&a.skipBrowserRedirect&&l.push(`skip_http_redirect=${a.skipBrowserRedirect}`),`${e}?${l.join("&")}`}async _unenroll(e){try{return await this._useSession(async i=>{var a;const{data:l,error:c}=i;return c?this._returnResult({data:null,error:c}):await oe(this.fetch,"DELETE",`${this.url}/factors/${e.factorId}`,{headers:this.headers,jwt:(a=l==null?void 0:l.session)===null||a===void 0?void 0:a.access_token})})}catch(i){if(te(i))return this._returnResult({data:null,error:i});throw i}}async _enroll(e){try{return await this._useSession(async i=>{var a,l;const{data:c,error:u}=i;if(u)return this._returnResult({data:null,error:u});const d=Object.assign({friendly_name:e.friendlyName,factor_type:e.factorType},e.factorType==="phone"?{phone:e.phone}:e.factorType==="totp"?{issuer:e.issuer}:{}),{data:m,error:p}=await oe(this.fetch,"POST",`${this.url}/factors`,{body:d,headers:this.headers,jwt:(a=c==null?void 0:c.session)===null||a===void 0?void 0:a.access_token});return p?this._returnResult({data:null,error:p}):(e.factorType==="totp"&&m.type==="totp"&&(!((l=m==null?void 0:m.totp)===null||l===void 0)&&l.qr_code)&&(m.totp.qr_code=`data:image/svg+xml;utf-8,${m.totp.qr_code}`),this._returnResult({data:m,error:null}))})}catch(i){if(te(i))return this._returnResult({data:null,error:i});throw i}}async _verify(e){const i=async()=>{try{return await this._useSession(async a=>{var l;const{data:c,error:u}=a;if(u)return this._returnResult({data:null,error:u});const d=Object.assign({challenge_id:e.challengeId},"webauthn"in e?{webauthn:Object.assign(Object.assign({},e.webauthn),{credential_response:e.webauthn.type==="create"?Zb(e.webauthn.credential_response):Wb(e.webauthn.credential_response)})}:{code:e.code}),{data:m,error:p}=await oe(this.fetch,"POST",`${this.url}/factors/${e.factorId}/verify`,{body:d,headers:this.headers,jwt:(l=c==null?void 0:c.session)===null||l===void 0?void 0:l.access_token});return p?this._returnResult({data:null,error:p}):(await this._saveSession(Object.assign({expires_at:Math.round(Date.now()/1e3)+m.expires_in},m)),await this._notifyAllSubscribers("MFA_CHALLENGE_VERIFIED",m),this._returnResult({data:m,error:p}))})}catch(a){if(te(a))return this._returnResult({data:null,error:a});throw a}};return this.lock!=null?this._acquireLock(this.lockAcquireTimeout,i):i()}async _challenge(e){const i=async()=>{try{return await this._useSession(async a=>{var l;const{data:c,error:u}=a;if(u)return this._returnResult({data:null,error:u});const d=await oe(this.fetch,"POST",`${this.url}/factors/${e.factorId}/challenge`,{body:e,headers:this.headers,jwt:(l=c==null?void 0:c.session)===null||l===void 0?void 0:l.access_token});if(d.error)return d;const{data:m}=d;if(m.type!=="webauthn")return{data:m,error:null};switch(m.webauthn.type){case"create":return{data:Object.assign(Object.assign({},m),{webauthn:Object.assign(Object.assign({},m.webauthn),{credential_options:Object.assign(Object.assign({},m.webauthn.credential_options),{publicKey:Jb(m.webauthn.credential_options.publicKey)})})}),error:null};case"request":return{data:Object.assign(Object.assign({},m),{webauthn:Object.assign(Object.assign({},m.webauthn),{credential_options:Object.assign(Object.assign({},m.webauthn.credential_options),{publicKey:Qb(m.webauthn.credential_options.publicKey)})})}),error:null}}})}catch(a){if(te(a))return this._returnResult({data:null,error:a});throw a}};return this.lock!=null?this._acquireLock(this.lockAcquireTimeout,i):i()}async _challengeAndVerify(e){const{data:i,error:a}=await this._challenge({factorId:e.factorId});return a?this._returnResult({data:null,error:a}):await this._verify({factorId:e.factorId,challengeId:i.id,code:e.code})}async _listFactors(){var e;const{data:{user:i},error:a}=await this.getUser();if(a)return{data:null,error:a};const l={all:[],phone:[],totp:[],webauthn:[]};for(const c of(e=i==null?void 0:i.factors)!==null&&e!==void 0?e:[])l.all.push(c),c.status==="verified"&&l[c.factor_type].push(c);return{data:l,error:null}}async _getAuthenticatorAssuranceLevel(e){var i,a,l,c;if(e)try{const{payload:_}=sc(e);let S=null;_.aal&&(S=_.aal);let T=S;const{data:{user:j},error:k}=await this.getUser(e);if(k)return this._returnResult({data:null,error:k});((a=(i=j==null?void 0:j.factors)===null||i===void 0?void 0:i.filter(P=>P.status==="verified"))!==null&&a!==void 0?a:[]).length>0&&(T="aal2");const C=_.amr||[];return{data:{currentLevel:S,nextLevel:T,currentAuthenticationMethods:C},error:null}}catch(_){if(te(_))return this._returnResult({data:null,error:_});throw _}const{data:{session:u},error:d}=await this.getSession();if(d)return this._returnResult({data:null,error:d});if(!u)return{data:{currentLevel:null,nextLevel:null,currentAuthenticationMethods:[]},error:null};const{payload:m}=sc(u.access_token);let p=null;m.aal&&(p=m.aal);let y=p;((c=(l=u.user.factors)===null||l===void 0?void 0:l.filter(_=>_.status==="verified"))!==null&&c!==void 0?c:[]).length>0&&(y="aal2");const x=m.amr||[];return{data:{currentLevel:p,nextLevel:y,currentAuthenticationMethods:x},error:null}}async _getAuthorizationDetails(e){try{return await this._useSession(async i=>{const{data:{session:a},error:l}=i;return l?this._returnResult({data:null,error:l}):a?await oe(this.fetch,"GET",`${this.url}/oauth/authorizations/${e}`,{headers:this.headers,jwt:a.access_token,xform:c=>({data:c,error:null})}):this._returnResult({data:null,error:new kt})})}catch(i){if(te(i))return this._returnResult({data:null,error:i});throw i}}async _approveAuthorization(e,i){try{return await this._useSession(async a=>{const{data:{session:l},error:c}=a;if(c)return this._returnResult({data:null,error:c});if(!l)return this._returnResult({data:null,error:new kt});const u=await oe(this.fetch,"POST",`${this.url}/oauth/authorizations/${e}/consent`,{headers:this.headers,jwt:l.access_token,body:{action:"approve"},xform:d=>({data:d,error:null})});return u.data&&u.data.redirect_url&&Pt()&&!(i!=null&&i.skipBrowserRedirect)&&window.location.assign(u.data.redirect_url),u})}catch(a){if(te(a))return this._returnResult({data:null,error:a});throw a}}async _denyAuthorization(e,i){try{return await this._useSession(async a=>{const{data:{session:l},error:c}=a;if(c)return this._returnResult({data:null,error:c});if(!l)return this._returnResult({data:null,error:new kt});const u=await oe(this.fetch,"POST",`${this.url}/oauth/authorizations/${e}/consent`,{headers:this.headers,jwt:l.access_token,body:{action:"deny"},xform:d=>({data:d,error:null})});return u.data&&u.data.redirect_url&&Pt()&&!(i!=null&&i.skipBrowserRedirect)&&window.location.assign(u.data.redirect_url),u})}catch(a){if(te(a))return this._returnResult({data:null,error:a});throw a}}async _listOAuthGrants(){try{return await this._useSession(async e=>{const{data:{session:i},error:a}=e;return a?this._returnResult({data:null,error:a}):i?await oe(this.fetch,"GET",`${this.url}/user/oauth/grants`,{headers:this.headers,jwt:i.access_token,xform:l=>({data:l,error:null})}):this._returnResult({data:null,error:new kt})})}catch(e){if(te(e))return this._returnResult({data:null,error:e});throw e}}async _revokeOAuthGrant(e){try{return await this._useSession(async i=>{const{data:{session:a},error:l}=i;return l?this._returnResult({data:null,error:l}):a?(await oe(this.fetch,"DELETE",`${this.url}/user/oauth/grants`,{headers:this.headers,jwt:a.access_token,query:{client_id:e.clientId},noResolveJson:!0}),{data:{},error:null}):this._returnResult({data:null,error:new kt})})}catch(i){if(te(i))return this._returnResult({data:null,error:i});throw i}}async fetchJwk(e,i={keys:[]}){let a=i.keys.find(d=>d.kid===e);if(a)return a;const l=Date.now();if(a=this.jwks.keys.find(d=>d.kid===e),a&&this.jwks_cached_at+HR>l)return a;const{data:c,error:u}=await oe(this.fetch,"GET",`${this.url}/.well-known/jwks.json`,{headers:this.headers});if(u)throw u;return!c.keys||c.keys.length===0||(this.jwks=c,this.jwks_cached_at=l,a=c.keys.find(d=>d.kid===e),!a)?null:a}async getClaims(e,i={}){try{let a=e;if(!a){const{data:_,error:S}=await this.getSession();if(S||!_.session)return this._returnResult({data:null,error:S});a=_.session.access_token}const{header:l,payload:c,signature:u,raw:{header:d,payload:m}}=sc(a);if(!(i!=null&&i.allowExpired))try{uk(c.exp)}catch(_){throw new Rc(_ instanceof Error?_.message:"JWT validation failed")}const p=!l.alg||l.alg.startsWith("HS")||!l.kid||!("crypto"in globalThis&&"subtle"in globalThis.crypto)?null:await this.fetchJwk(l.kid,i!=null&&i.keys?{keys:i.keys}:i==null?void 0:i.jwks);if(!p){const{error:_}=await this.getUser(a);if(_)throw _;return{data:{claims:c,header:l,signature:u},error:null}}const y=hk(l.alg),v=await crypto.subtle.importKey("jwk",p,y,!0,["verify"]);if(!await crypto.subtle.verify(y,v,u,QR(`${d}.${m}`)))throw new Rc("Invalid JWT signature");return{data:{claims:c,header:l,signature:u},error:null}}catch(a){if(te(a))return this._returnResult({data:null,error:a});throw a}}async signInWithPasskey(e){var i,a,l;zn(this.experimental);try{if(!Oc())return this._returnResult({data:null,error:new Vn("Browser does not support WebAuthn",null)});const{data:c,error:u}=await this._startPasskeyAuthentication({options:{captchaToken:(i=e==null?void 0:e.options)===null||i===void 0?void 0:i.captchaToken}});if(u||!c)return this._returnResult({data:null,error:u});const d=Qb(c.options),m=(l=(a=e==null?void 0:e.options)===null||a===void 0?void 0:a.signal)!==null&&l!==void 0?l:bf.createNewAbortSignal(),{data:p,error:y}=await Ow({publicKey:d,signal:m});if(y||!p)return this._returnResult({data:null,error:y??new Vn("WebAuthn ceremony failed",null)});const v=Wb(p);return this._verifyPasskeyAuthentication({challengeId:c.challenge_id,credential:v})}catch(c){if(te(c))return this._returnResult({data:null,error:c});throw c}}async registerPasskey(e){var i,a;zn(this.experimental);try{if(!Oc())return this._returnResult({data:null,error:new Vn("Browser does not support WebAuthn",null)});const{data:l,error:c}=await this._startPasskeyRegistration();if(c||!l)return this._returnResult({data:null,error:c});const u=Jb(l.options),d=(a=(i=e==null?void 0:e.options)===null||i===void 0?void 0:i.signal)!==null&&a!==void 0?a:bf.createNewAbortSignal(),{data:m,error:p}=await Cw({publicKey:u,signal:d});if(p||!m)return this._returnResult({data:null,error:p??new Vn("WebAuthn ceremony failed",null)});const y=Zb(m);return this._verifyPasskeyRegistration({challengeId:l.challenge_id,credential:y})}catch(l){if(te(l))return this._returnResult({data:null,error:l});throw l}}async _startPasskeyRegistration(){zn(this.experimental);try{return await this._useSession(async e=>{const{data:{session:i},error:a}=e;if(a)return this._returnResult({data:null,error:a});if(!i)return this._returnResult({data:null,error:new kt});const{data:l,error:c}=await oe(this.fetch,"POST",`${this.url}/passkeys/registration/options`,{headers:this.headers,jwt:i.access_token,body:{}});return c?this._returnResult({data:null,error:c}):this._returnResult({data:l,error:null})})}catch(e){if(te(e))return this._returnResult({data:null,error:e});throw e}}async _verifyPasskeyRegistration(e){zn(this.experimental);try{return await this._useSession(async i=>{const{data:{session:a},error:l}=i;if(l)return this._returnResult({data:null,error:l});if(!a)return this._returnResult({data:null,error:new kt});const{data:c,error:u}=await oe(this.fetch,"POST",`${this.url}/passkeys/registration/verify`,{headers:this.headers,jwt:a.access_token,body:{challenge_id:e.challengeId,credential:e.credential}});return u?this._returnResult({data:null,error:u}):this._returnResult({data:c,error:null})})}catch(i){if(te(i))return this._returnResult({data:null,error:i});throw i}}async _startPasskeyAuthentication(e){var i;zn(this.experimental);try{const{data:a,error:l}=await oe(this.fetch,"POST",`${this.url}/passkeys/authentication/options`,{headers:this.headers,body:{gotrue_meta_security:{captcha_token:(i=e==null?void 0:e.options)===null||i===void 0?void 0:i.captchaToken}}});return l?this._returnResult({data:null,error:l}):this._returnResult({data:a,error:null})}catch(a){if(te(a))return this._returnResult({data:null,error:a});throw a}}async _verifyPasskeyAuthentication(e){zn(this.experimental);try{const{data:i,error:a}=await oe(this.fetch,"POST",`${this.url}/passkeys/authentication/verify`,{headers:this.headers,body:{challenge_id:e.challengeId,credential:e.credential},xform:Sn});return a?this._returnResult({data:null,error:a}):(i.session&&(await this._saveSession(i.session),await this._notifyAllSubscribers("SIGNED_IN",i.session)),this._returnResult({data:i,error:null}))}catch(i){if(te(i))return this._returnResult({data:null,error:i});throw i}}async _listPasskeys(){zn(this.experimental);try{return await this._useSession(async e=>{const{data:{session:i},error:a}=e;if(a)return this._returnResult({data:null,error:a});if(!i)return this._returnResult({data:null,error:new kt});const{data:l,error:c}=await oe(this.fetch,"GET",`${this.url}/passkeys`,{headers:this.headers,jwt:i.access_token,xform:u=>({data:u,error:null})});return c?this._returnResult({data:null,error:c}):this._returnResult({data:l,error:null})})}catch(e){if(te(e))return this._returnResult({data:null,error:e});throw e}}async _updatePasskey(e){zn(this.experimental);try{return await this._useSession(async i=>{const{data:{session:a},error:l}=i;if(l)return this._returnResult({data:null,error:l});if(!a)return this._returnResult({data:null,error:new kt});const{data:c,error:u}=await oe(this.fetch,"PATCH",`${this.url}/passkeys/${e.passkeyId}`,{headers:this.headers,jwt:a.access_token,body:{friendly_name:e.friendlyName}});return u?this._returnResult({data:null,error:u}):this._returnResult({data:c,error:null})})}catch(i){if(te(i))return this._returnResult({data:null,error:i});throw i}}async _deletePasskey(e){zn(this.experimental);try{return await this._useSession(async i=>{const{data:{session:a},error:l}=i;if(l)return this._returnResult({data:null,error:l});if(!a)return this._returnResult({data:null,error:new kt});const{error:c}=await oe(this.fetch,"DELETE",`${this.url}/passkeys/${e.passkeyId}`,{headers:this.headers,jwt:a.access_token,noResolveJson:!0});return c?this._returnResult({data:null,error:c}):this._returnResult({data:null,error:null})})}catch(i){if(te(i))return this._returnResult({data:null,error:i});throw i}}}bo.nextInstanceID={};const Bk=bo,Uk="2.110.2";let Zr="",Mc;if(typeof Deno<"u"){var jd;Zr="deno",Mc=(jd=Deno.version)===null||jd===void 0?void 0:jd.deno}else if(typeof document<"u")Zr="web";else if(typeof navigator<"u"&&navigator.product==="ReactNative")Zr="react-native";else{var Nd;Zr="node",Mc=typeof process<"u"?(Nd=process.version)===null||Nd===void 0?void 0:Nd.replace(/^v/,""):void 0}const Dw=[`runtime=${Zr}`];Mc&&Dw.push(`runtime-version=${Mc}`);const Lk={"X-Client-Info":`supabase-js/${Uk}; ${Dw.join("; ")}`},zk={headers:Lk},Pk={schema:"public"},Vk={autoRefreshToken:!0,persistSession:!0,detectSessionInUrl:!0,flowType:"implicit"},Hk={},$k={enabled:!1,respectSamplingDecision:!0};function qk(n,e,i,a){function l(c){return c instanceof i?c:new i(function(u){u(c)})}return new(i||(i=Promise))(function(c,u){function d(y){try{p(a.next(y))}catch(v){u(v)}}function m(y){try{p(a.throw(y))}catch(v){u(v)}}function p(y){y.done?c(y.value):l(y.value).then(d,m)}p((a=a.apply(n,[])).next())})}let Rd=null;const Fk="@opentelemetry/api";function Ik(){return Rd===null&&(Rd=import(Fk).catch(()=>null)),Rd}function Gk(){return qk(this,void 0,void 0,function*(){try{const n=yield Ik();if(!n||!n.propagation||!n.context)return null;const e={};n.propagation.inject(n.context.active(),e);const i=e.traceparent;return i?{traceparent:i,tracestate:e.tracestate,baggage:e.baggage}:null}catch{return null}})}function Kk(n){if(!n||typeof n!="string")return null;const e=n.split("-");if(e.length!==4)return null;const[i,a,l,c]=e;if(i.length!==2||a.length!==32||l.length!==16||c.length!==2)return null;const u=/^[0-9a-f]+$/i;return!u.test(i)||!u.test(a)||!u.test(l)||!u.test(c)||a==="00000000000000000000000000000000"||l==="0000000000000000"?null:{version:i,traceId:a,parentId:l,traceFlags:c,isSampled:(parseInt(c,16)&1)===1}}function Yk(n,e){if(!n||!e||e.length===0)return!1;let i;if(n instanceof URL)i=n;else try{i=new URL(n)}catch{return!1}for(const a of e)try{if(typeof a=="string"){if(Xk(i.hostname,a))return!0}else if(a instanceof RegExp){if(a.test(i.hostname))return!0}else if(typeof a=="function"&&a(i))return!0}catch{continue}return!1}function Xk(n,e){if(e===n)return!0;if(e.startsWith("*.")){const i=e.slice(2);if(n.endsWith(i)&&(n===i||n.endsWith("."+i)))return!0}return!1}function Jk(n){const e=[];try{const i=new URL(n);e.push(i.hostname)}catch{}return e.push("*.supabase.co","*.supabase.in"),e.push("localhost","127.0.0.1","[::1]"),e}function vo(n){"@babel/helpers - typeof";return vo=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},vo(n)}function Qk(n,e){if(vo(n)!="object"||!n)return n;var i=n[Symbol.toPrimitive];if(i!==void 0){var a=i.call(n,e);if(vo(a)!="object")return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(n)}function Zk(n){var e=Qk(n,"string");return vo(e)=="symbol"?e:e+""}function Wk(n,e,i){return(e=Zk(e))in n?Object.defineProperty(n,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):n[e]=i,n}function ev(n,e){var i=Object.keys(n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(n);e&&(a=a.filter(function(l){return Object.getOwnPropertyDescriptor(n,l).enumerable})),i.push.apply(i,a)}return i}function ct(n){for(var e=1;en?(...e)=>n(...e):(...e)=>fetch(...e),tC=()=>Headers,nC=(n,e,i,a,l)=>{const c=eC(a),u=tC(),d=(l==null?void 0:l.enabled)===!0,m=(l==null?void 0:l.respectSamplingDecision)!==!1,p=d?Jk(e):null;return async(y,v)=>{var x;const _=(x=await i())!==null&&x!==void 0?x:n;let S=new u(v==null?void 0:v.headers);if(S.has("apikey")||S.set("apikey",n),S.has("Authorization")||S.set("Authorization",`Bearer ${_}`),p){const T=await sC(y,p,m);T&&(T.traceparent&&!S.has("traceparent")&&S.set("traceparent",T.traceparent),T.tracestate&&!S.has("tracestate")&&S.set("tracestate",T.tracestate),T.baggage&&!S.has("baggage")&&S.set("baggage",T.baggage))}return c(y,ct(ct({},v),{},{headers:S}))}};async function sC(n,e,i){if(!Yk(typeof n=="string"||n instanceof URL?n:n.url,e))return null;const a=await Gk();if(!a||!a.traceparent)return null;if(i){const l=Kk(a.traceparent);if(l&&!l.isSampled)return null}return a}function tv(n){return typeof n=="boolean"?{enabled:n}:n}function iC(n){return n.endsWith("/")?n:n+"/"}function aC(n,e){var i,a,l,c,u,d;const{db:m,auth:p,realtime:y,global:v}=n,{db:x,auth:_,realtime:S,global:T}=e,j=tv(n.tracePropagation),k=tv(e.tracePropagation),M={db:ct(ct({},x),m),auth:ct(ct({},_),p),realtime:ct(ct({},S),y),storage:{},global:ct(ct(ct({},T),v),{},{headers:ct(ct({},(i=T==null?void 0:T.headers)!==null&&i!==void 0?i:{}),(a=v==null?void 0:v.headers)!==null&&a!==void 0?a:{})}),tracePropagation:{enabled:(l=(c=j==null?void 0:j.enabled)!==null&&c!==void 0?c:k==null?void 0:k.enabled)!==null&&l!==void 0?l:!1,respectSamplingDecision:(u=(d=j==null?void 0:j.respectSamplingDecision)!==null&&d!==void 0?d:k==null?void 0:k.respectSamplingDecision)!==null&&u!==void 0?u:!0},accessToken:async()=>""};return n.accessToken?M.accessToken=n.accessToken:delete M.accessToken,M}function rC(n){const e=n==null?void 0:n.trim();if(!e)throw new Error("supabaseUrl is required.");if(!e.match(/^https?:\/\//i))throw new Error("Invalid supabaseUrl: Must be a valid HTTP or HTTPS URL.");try{return new URL(iC(e))}catch{throw Error("Invalid supabaseUrl: Provided URL is malformed.")}}var oC=class extends Bk{constructor(n){super(n)}},lC=class{constructor(n,e,i){var a,l;this.supabaseUrl=n,this.supabaseKey=e;const c=rC(n);if(!e)throw new Error("supabaseKey is required.");this.realtimeUrl=new URL("realtime/v1",c),this.realtimeUrl.protocol=this.realtimeUrl.protocol.replace("http","ws"),this.authUrl=new URL("auth/v1",c),this.storageUrl=new URL("storage/v1",c),this.functionsUrl=new URL("functions/v1",c);const u=`sb-${c.hostname.split(".")[0]}-auth-token`,d={db:Pk,realtime:Hk,auth:ct(ct({},Vk),{},{storageKey:u}),global:zk,tracePropagation:$k},m=aC(i??{},d);if(this.settings=m,this.storageKey=(a=m.auth.storageKey)!==null&&a!==void 0?a:"",this.headers=(l=m.global.headers)!==null&&l!==void 0?l:{},m.accessToken)this.accessToken=m.accessToken,this.auth=new Proxy({},{get:(y,v)=>{throw new Error(`@supabase/supabase-js: Supabase Client is configured with the accessToken option, accessing supabase.auth.${String(v)} is not possible`)}});else{var p;this.auth=this._initSupabaseAuthClient((p=m.auth)!==null&&p!==void 0?p:{},this.headers,m.global.fetch)}this.fetch=nC(e,n,this._getAccessToken.bind(this),m.global.fetch,m.tracePropagation),this.realtime=this._initRealtimeClient(ct({headers:this.headers,accessToken:this._getAccessToken.bind(this),fetch:this.fetch},m.realtime)),this.accessToken&&Promise.resolve(this.accessToken()).then(y=>this.realtime.setAuth(y)).catch(y=>console.warn("Failed to set initial Realtime auth token:",y)),this.rest=new yN(new URL("rest/v1",c).href,{headers:this.headers,schema:m.db.schema,fetch:this.fetch,timeout:m.db.timeout,urlLengthLimit:m.db.urlLengthLimit}),this.storage=new BR(this.storageUrl.href,this.headers,this.fetch,i==null?void 0:i.storage),m.accessToken||this._listenForAuthEvents()}get functions(){return new lN(this.functionsUrl.href,{headers:this.headers,customFetch:this.fetch})}from(n){return this.rest.from(n)}schema(n){return this.rest.schema(n)}rpc(n,e={},i={head:!1,get:!1,count:void 0}){return this.rest.rpc(n,e,i)}channel(n,e={config:{}}){return this.realtime.channel(n,e)}getChannels(){return this.realtime.getChannels()}removeChannel(n){return this.realtime.removeChannel(n)}removeAllChannels(){return this.realtime.removeAllChannels()}async _getAccessToken(){var n=this,e,i;if(n.accessToken)return await n.accessToken();const{data:a}=await n.auth.getSession();return(e=(i=a.session)===null||i===void 0?void 0:i.access_token)!==null&&e!==void 0?e:n.supabaseKey}_initSupabaseAuthClient({autoRefreshToken:n,persistSession:e,detectSessionInUrl:i,storage:a,userStorage:l,storageKey:c,flowType:u,lock:d,debug:m,throwOnError:p,experimental:y,lockAcquireTimeout:v,skipAutoInitialize:x},_,S){const T={Authorization:`Bearer ${this.supabaseKey}`,apikey:`${this.supabaseKey}`};return new oC({url:this.authUrl.href,headers:ct(ct({},T),_),storageKey:c,autoRefreshToken:n,persistSession:e,detectSessionInUrl:i,storage:a,userStorage:l,flowType:u,lock:d,debug:m,throwOnError:p,experimental:y,fetch:S,lockAcquireTimeout:v,skipAutoInitialize:x,hasCustomAuthorizationHeader:Object.keys(this.headers).some(j=>j.toLowerCase()==="authorization")})}_initRealtimeClient(n){return new aR(this.realtimeUrl.href,ct(ct({},n),{},{params:ct(ct({},{apikey:this.supabaseKey}),n==null?void 0:n.params)}))}_listenForAuthEvents(){return this.auth.onAuthStateChange((n,e)=>{this._handleTokenChanged(n,"CLIENT",e==null?void 0:e.access_token)})}_handleTokenChanged(n,e,i){(n==="TOKEN_REFRESHED"||n==="SIGNED_IN")&&this.changedAccessToken!==i?(this.changedAccessToken=i,this.realtime.setAuth(i)):n==="SIGNED_OUT"&&(this.realtime.setAuth(),e=="STORAGE"&&this.auth.signOut(),this.changedAccessToken=void 0)}};const cC=(n,e,i)=>new lC(n,e,i);function uC(){if(typeof window<"u")return!1;const n=globalThis.process;if(!n)return!1;const e=n.version;if(e==null)return!1;const i=e.match(/^v(\d+)\./);return i?parseInt(i[1],10)<=20:!1}uC()&&console.warn("⚠️ Node.js 20 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 22 or later. For more information, visit: https://github.com/orgs/supabase/discussions/45715");const Mw=void 0,hC=void 0,dC=!!Mw,es=dC?cC(Mw,hC,{auth:{persistSession:!0,autoRefreshToken:!0,detectSessionInUrl:!0}}):null,fC=180,mC=8e3;async function pC(n=fC){if(!es)return null;const{data:e,error:i}=await es.auth.getSession();if(i)throw i;let a=e.session;if(!a)throw new Error("Tu sesión expiró. Inicia sesión nuevamente antes de continuar.");const l=Number(a.expires_at||0)*1e3;if(!l||l-Date.now()<=n*1e3){const u=await es.auth.refreshSession();if(u.error)throw u.error;if(a=u.data.session,!a)throw new Error("Tu sesión expiró. Inicia sesión nuevamente antes de continuar.")}return a}async function nv(n){if(typeof window>"u"||typeof fetch>"u")return;if(typeof navigator<"u"&&navigator.onLine===!1)throw new Error("No hay conexión a Internet. Verifica tu conexión e intenta nuevamente.");let e;try{e=new URL(n,window.location.origin)}catch{return}if(e.origin===window.location.origin)return;const i=new URL("/favicon.ico",e.origin);i.searchParams.set("_glm_resume",String(Date.now()));const a=new AbortController,l=window.setTimeout(()=>a.abort(),mC);try{await fetch(i.toString(),{method:"GET",mode:"no-cors",cache:"no-store",credentials:"omit",signal:a.signal})}catch(c){if(typeof navigator<"u"&&navigator.onLine===!1)throw new Error("No hay conexión a Internet. Verifica tu conexión e intenta nuevamente.");console.warn("No se pudo precalentar la conexión con n8n:",c)}finally{window.clearTimeout(l)}}function sv(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`glm-${Date.now()}-${Math.random().toString(36).slice(2,12)}`}function iv(n,e){try{const i=new URL(n,window.location.origin);return i.searchParams.set("client_request_id",e),i.searchParams.set("_ts",String(Date.now())),i.toString()}catch{return n}}const kd=["Nombre mal escrito en BambooHR","Apodo o nombre de uso","Nombre incompleto / nombres adicionales","Otro"];function Bw({row:n,country:e,periodRange:i,operatorName:a,operatorEmail:l,executionId:c,reportUrl:u,onClose:d,onSuccess:m,onShowToast:p}){const y=n.bestBambooCandidate,[v,x]=D.useState((y==null?void 0:y.employeeName)||""),[_,S]=D.useState((y==null?void 0:y.employeeNumber)||""),[T,j]=D.useState(kd[0]),[k,M]=D.useState(""),[C,P]=D.useState(!1),[K,G]=D.useState(!1);D.useEffect(()=>{x((y==null?void 0:y.employeeName)||""),S((y==null?void 0:y.employeeNumber)||""),j(kd[0]),M(""),P(!1)},[n.id,y==null?void 0:y.employeeName,y==null?void 0:y.employeeNumber]);const H=D.useMemo(()=>e.code==="TT"?"Laurele Nicome-Jack":e.code==="PA"?"Delarys Peñalba":e.code==="SV"?"Carlos Antonio Malta Méndez":e.code==="HN"?"Melody Chang Blandin":e.code==="PR"||e.code==="RD"?"Noralmy Laureano":"haguirre@gomezleemarketing.com",[e.code]);D.useMemo(()=>Array.from(new Set([n.employee,n.bankNameFile,n.bankAccountHolder].map(Z=>String(Z||"").trim()).filter(Boolean))),[n.employee,n.bankNameFile,n.bankAccountHolder]);const Y=async()=>{{p("Falta configurar VITE_REPORTAR_BAMBOO_URL.","error");return}};return g.jsxs("div",{className:"fixed inset-0 z-[90] flex items-center justify-center px-4 py-6",children:[g.jsx("button",{type:"button",className:"absolute inset-0 bg-black/45",onClick:K?void 0:d,"aria-label":"Cerrar"}),g.jsxs("div",{className:"relative w-full max-w-2xl bg-white border border-[#D0D0D0] shadow-2xl max-h-[92vh] overflow-y-auto",children:[g.jsx("div",{className:"h-1.5 bg-[#6CC24A]"}),g.jsxs("div",{className:"px-6 py-5 border-b border-neutral-200 flex items-start justify-between gap-4",children:[g.jsxs("div",{children:[g.jsx("p",{className:"text-[10px] uppercase tracking-[0.18em] font-black text-[#6B8FA3]",children:"Banco sin BambooHR"}),g.jsx("h2",{className:"text-xl font-black text-[#4F758B] mt-1",children:"Reportar corrección de identidad a RRHH"}),g.jsx("p",{className:"text-xs text-neutral-500 mt-2 leading-relaxed",children:"Esta validación crea una equivalencia permanente para que el mismo falso positivo no vuelva a aparecer mientras RRHH corrige BambooHR."})]}),g.jsx("button",{type:"button",onClick:d,disabled:K,className:"p-2 text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100 disabled:opacity-40","aria-label":"Cerrar modal",children:g.jsx(Ga,{className:"w-5 h-5"})})]}),g.jsxs("div",{className:"px-6 py-5 space-y-5",children:[g.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3 bg-[#F5F5F5] border border-neutral-200 p-4",children:[g.jsxs("div",{children:[g.jsx("p",{className:"text-[9px] uppercase tracking-wider font-black text-[#6B8FA3]",children:"Nombre detectado"}),g.jsx("p",{className:"text-sm font-black text-neutral-800 mt-1",children:n.employee})]}),g.jsxs("div",{children:[g.jsx("p",{className:"text-[9px] uppercase tracking-wider font-black text-[#6B8FA3]",children:"Cuenta bancaria"}),g.jsx("p",{className:"text-sm font-mono font-bold text-neutral-700 mt-1",children:n.account||"—"})]}),g.jsxs("div",{className:"sm:col-span-2",children:[g.jsx("p",{className:"text-[9px] uppercase tracking-wider font-black text-[#6B8FA3]",children:"Se notificará a"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700 mt-1",children:H})]})]}),(y==null?void 0:y.employeeName)&&g.jsxs("div",{className:"border border-[#D6E8F4] bg-[#F7FBFD] p-4 flex items-start gap-3",children:[g.jsx(Ac,{className:"w-4 h-4 text-[#4F758B] mt-0.5 flex-shrink-0"}),g.jsxs("div",{className:"text-xs text-neutral-600 leading-relaxed",children:[g.jsx("strong",{className:"text-[#4F758B]",children:"Candidato sugerido por el cruce:"})," ",y.employeeName,y.employeeNumber?` · Employee Number ${y.employeeNumber}`:"",". Verifícalo manualmente antes de confirmar."]})]}),g.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[g.jsxs("label",{className:"sm:col-span-2",children:[g.jsx("span",{className:"block text-[10px] uppercase tracking-wider font-black text-[#4F758B] mb-1.5",children:"Nombre correcto en BambooHR *"}),g.jsx("input",{type:"text",value:v,onChange:Z=>x(Z.target.value),placeholder:"Ej.: Jonathan Alexander Pérez",className:"w-full border border-[#D0D0D0] px-3 py-2.5 text-sm font-medium focus:outline-none focus:border-[#4F758B]"})]}),g.jsxs("label",{children:[g.jsx("span",{className:"block text-[10px] uppercase tracking-wider font-black text-[#4F758B] mb-1.5",children:"Employee Number"}),g.jsx("input",{type:"text",value:_,onChange:Z=>S(Z.target.value),placeholder:"Recomendado para mayor seguridad",className:"w-full border border-[#D0D0D0] px-3 py-2.5 text-sm font-medium focus:outline-none focus:border-[#4F758B]"})]}),g.jsxs("label",{children:[g.jsx("span",{className:"block text-[10px] uppercase tracking-wider font-black text-[#4F758B] mb-1.5",children:"Motivo *"}),g.jsx("select",{value:T,onChange:Z=>j(Z.target.value),className:"w-full border border-[#D0D0D0] px-3 py-2.5 text-sm font-medium focus:outline-none focus:border-[#4F758B] bg-white",children:kd.map(Z=>g.jsx("option",{value:Z,children:Z},Z))})]}),g.jsxs("label",{className:"sm:col-span-2",children:[g.jsx("span",{className:"block text-[10px] uppercase tracking-wider font-black text-[#4F758B] mb-1.5",children:"Comentario para RRHH"}),g.jsx("textarea",{value:k,onChange:Z=>M(Z.target.value),rows:3,placeholder:"Detalle adicional que ayude a RRHH a corregir el registro.",className:"w-full border border-[#D0D0D0] px-3 py-2.5 text-sm font-medium focus:outline-none focus:border-[#4F758B] resize-y"})]})]}),g.jsxs("label",{className:"flex items-start gap-3 border border-[#D0D0D0] p-4 cursor-pointer",children:[g.jsx("input",{type:"checkbox",checked:C,onChange:Z=>P(Z.target.checked),className:"mt-0.5 accent-[#6CC24A]"}),g.jsxs("span",{className:"text-xs text-neutral-600 leading-relaxed",children:["Confirmo que revisé el caso manualmente y que ",g.jsx("strong",{children:n.employee})," corresponde a la misma persona indicada arriba en BambooHR."]})]})]}),g.jsxs("div",{className:"px-6 py-4 border-t border-neutral-200 bg-neutral-50 flex flex-col-reverse sm:flex-row sm:justify-end gap-2",children:[g.jsx("button",{type:"button",onClick:d,disabled:K,className:"px-4 py-2.5 border border-neutral-300 bg-white text-neutral-600 text-xs font-black uppercase tracking-wider disabled:opacity-40",children:"Cancelar"}),g.jsx("button",{type:"button",onClick:Y,disabled:K||!C||!v.trim(),className:"px-5 py-2.5 bg-[#4F758B] text-white text-xs font-black uppercase tracking-wider inline-flex items-center justify-center gap-2 border-l-4 border-[#6CC24A] disabled:bg-neutral-300 disabled:border-neutral-300 disabled:cursor-not-allowed",children:K?g.jsxs(g.Fragment,{children:[g.jsx("span",{className:"w-4 h-4 border-2 border-white/40 border-t-white rounded-full animate-spin"}),"Enviando..."]}):g.jsxs(g.Fragment,{children:[g.jsx(hw,{className:"w-4 h-4"}),"Enviar a RRHH"]})})]})]})]})}const gC="https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-reportar";function yC(n){try{return n?JSON.parse(n):null}catch{return null}}function bC(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`report-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Uw({country:n,operatorName:e,operatorEmail:i,section:a,onShowToast:l}){const[c,u]=D.useState(!1),[d,m]=D.useState(""),[p,y]=D.useState(!1),v=()=>{p||u(!1)},x=async()=>{const _=d.trim();if(!_){l("Escribe una descripción del reporte.","error");return}if(!es){l("Supabase no está configurado en esta aplicación.","error");return}y(!0);try{const S=await pC(300),T=S==null?void 0:S.access_token;if(!T)throw new Error("Tu sesión expiró. Inicia sesión nuevamente antes de enviar el reporte.");const j={message:_.slice(0,5e3),userName:e,userEmail:i,country:n.code,countryName:n.name,section:a,submittedAt:new Date().toISOString(),pageUrl:window.location.href,appSessionId:bC()},k=new FormData;k.append("payload",JSON.stringify(j)),k.append("access_token",T);const M=await fetch(gC,{method:"POST",body:k}),C=await M.text(),P=yC(C);if(!M.ok||(P==null?void 0:P.ok)===!1){const K=(P==null?void 0:P.message)||(P==null?void 0:P.error)||C||"No se pudo enviar el reporte.";throw new Error(String(K))}m(""),u(!1),l("Reporte enviado correctamente.","success")}catch(S){l(S instanceof Error?S.message:"No se pudo enviar el reporte.","error")}finally{y(!1)}};return g.jsxs(g.Fragment,{children:[g.jsxs("button",{type:"button",onClick:()=>u(!0),className:"inline-flex items-center justify-center gap-2 border border-[#4F758B]/25 bg-white text-[#4F758B] h-9 px-2.5 sm:px-3 text-xs font-black hover:border-[#4F758B]/55 hover:bg-[#4F758B]/5 transition-colors shadow-sm",title:"Reportar un error o incidencia","aria-label":"Reportar",children:[g.jsx(F2,{className:"w-4 h-4"}),g.jsx("span",{className:"hidden sm:inline",children:"Reportar"})]}),c&&g.jsxs("div",{className:"fixed inset-0 z-[90] flex items-center justify-center px-4 py-6",children:[g.jsx("button",{type:"button",className:"absolute inset-0 bg-black/45",onClick:v,"aria-label":"Cerrar reporte"}),g.jsxs("div",{className:"relative w-full max-w-2xl bg-white border border-[#D0D0D0] shadow-2xl",children:[g.jsx("div",{className:"h-1.5 bg-[#6CC24A]"}),g.jsxs("div",{className:"px-6 py-5 border-b border-neutral-200 flex items-center justify-between gap-4",children:[g.jsx("h2",{className:"text-xl font-black text-[#4F758B]",children:"Reporte"}),g.jsx("button",{type:"button",onClick:v,disabled:p,className:"p-2 text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100 disabled:opacity-40","aria-label":"Cerrar modal",children:g.jsx(Ga,{className:"w-5 h-5"})})]}),g.jsxs("div",{className:"px-6 py-5",children:[g.jsxs("label",{className:"block",children:[g.jsx("span",{className:"block text-[10px] uppercase tracking-wider font-black text-[#4F758B] mb-1.5",children:"Descripción del Reporte *"}),g.jsx("textarea",{value:d,onChange:_=>m(_.target.value.slice(0,5e3)),rows:7,autoFocus:!0,disabled:p,placeholder:"Escribe aquí el error, incidencia o mejora que deseas reportar...",className:"w-full resize-y min-h-[150px] border border-[#D0D0D0] bg-white px-3.5 py-3 text-sm text-neutral-700 placeholder-neutral-400 focus:outline-none focus:border-[#4F758B] disabled:bg-neutral-50"})]}),g.jsxs("div",{className:"mt-1.5 text-right text-[10px] text-neutral-400",children:[d.length,"/5000"]})]}),g.jsxs("div",{className:"px-6 py-4 border-t border-neutral-200 bg-neutral-50 flex items-center justify-end gap-3",children:[g.jsx("button",{type:"button",onClick:v,disabled:p,className:"border border-neutral-300 bg-white text-neutral-600 px-4 py-2.5 text-xs font-bold hover:bg-neutral-100 disabled:opacity-50",children:"Cancelar"}),g.jsxs("button",{type:"button",onClick:()=>void x(),disabled:p||!d.trim(),className:"bg-[#4F758B] hover:bg-[#3F6174] text-white px-4 py-2.5 text-xs font-black inline-flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed",children:[p?g.jsx(Ha,{className:"w-4 h-4 animate-spin"}):g.jsx(hw,{className:"w-4 h-4"}),g.jsx("span",{children:p?"Enviando...":"Enviar reporte"})]})]})]})]})]})}const Lw=[{value:1,label:"Enero"},{value:2,label:"Febrero"},{value:3,label:"Marzo"},{value:4,label:"Abril"},{value:5,label:"Mayo"},{value:6,label:"Junio"},{value:7,label:"Julio"},{value:8,label:"Agosto"},{value:9,label:"Septiembre"},{value:10,label:"Octubre"},{value:11,label:"Noviembre"},{value:12,label:"Diciembre"}],av=[{value:"quincena_15",label:"Quincena 15",description:"Del día 1 al 15 del mes."},{value:"quincena_30",label:"Quincena 30 / fin de mes",description:"Del día 16 al último día del mes."}];function vC(n){return n==="TT"?"":n==="PA"?"https://agenteit.digitalcompass.agency/webhook/nominapa-bamboo-test":n==="SV"?"https://agenteit.digitalcompass.agency/webhook/nominasv-bamboo-test":n==="HN"?"https://agenteit.digitalcompass.agency/webhook/nominahn-bamboo-test":n==="PR"?"https://agenteit.digitalcompass.agency/webhook/nominapr-bamboo-test":n==="RD"?"https://agenteit.digitalcompass.agency/webhook/nominard-bamboo-test":""}function xC(){return""}function wC(){const n=new Date().getFullYear(),e=n-5,i=n+10;return Array.from({length:i-e+1},(a,l)=>e+l)}function _C(){const n=new Date,e=n.getDate();let i=n.getFullYear(),a=n.getMonth()+1,l="quincena_15";return e<=15&&(a-=1,l="quincena_30",a===0&&(a=12,i-=1)),{year:i,month:a,periodType:l}}function Bc(n){return n<1024*1024?`${(n/1024).toFixed(1)} KB`:`${(n/(1024*1024)).toFixed(2)} MB`}function Kr(n){const e=n.name.toLowerCase();return e.endsWith(".xlsx")||e.endsWith(".xls")}function Cd(n){return n.name.toLowerCase().endsWith(".csv")}function rv(n){return n.name.toLowerCase().endsWith(".pdf")}function SC(n){return Array.from(n).map(e=>({name:e.name,size:Bc(e.size),type:"payroll",rawFile:e}))}function Od(n){return Array.from(n).map(e=>({name:e.name,size:Bc(e.size),type:"bank",rawFile:e}))}function Va(n,e,i){return`${n}-${String(e).padStart(2,"0")}-${String(i).padStart(2,"0")}`}function ov(n){const e=/^(\d{4})-(\d{2})-(\d{2})$/.exec(n);return e?`${e[3]}-${e[2]}-${e[1]}`:n}function lv(n,e,i){var c;const a=new Date(n,e,0).getDate(),l=((c=Lw.find(u=>u.value===e))==null?void 0:c.label)??"Mes";return i==="quincena_15"?{start:Va(n,e,1),end:Va(n,e,15),label:`${l} ${n} · Quincena 15`}:{start:Va(n,e,16),end:Va(n,e,a),label:`${l} ${n} · Quincena 30 / fin de mes`}}function TC(n){const e=n-1;return{start:Va(e,7,1),end:Va(n,6,30),label:`Bono 14 ${n} · Julio ${e} a junio ${n}`}}function Dd(n,e,i){if(n==null||Number.isNaN(n))return"—";const a=i==="USD"||i==="GTQ"||i==="TTD"?i:e.currency,l=a==="USD"?"en-US":e.locale;return new Intl.NumberFormat(l,{style:"currency",currency:a,minimumFractionDigits:2}).format(n)}function Un(n,e=0){const i=Number(n);return Number.isFinite(i)?i:e}function At(n){return n.normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase()}function EC(n,e){const i=At(String(n??e??""));return i.includes("coincid")?"Coincidencia":i.includes("resuelto")?"Resuelto":i.includes("no encontrado")?"No encontrado":i.includes("pendiente")?"Pendiente revisión":i.includes("riesgo")||i.includes("discrep")||i.includes("mal digitada")?"Riesgo":e==="coincidencia"?"Coincidencia":e==="posible_cuenta_mal_digitada"||e==="discrepancia"?"Riesgo":"Pendiente revisión"}function ic(n,e){for(const i of e){if(typeof n[i]=="number")return n[i];if(typeof n[i]=="string"&&n[i]!==""){const a=n[i].replace(/[Q,$\s]/g,"").replace(/,/g,""),l=Number(a);if(Number.isFinite(l))return l}}return null}function cv(n){return Array.isArray(n)?n.map((e,i)=>{const a=e,l=String(a.category??a.categoria??a.tipo??a.source??a.fuente??""),c=ic(a,["amountPayroll","monto_nomina","payroll_amount","amount_payroll","montoNomina"]),u=ic(a,["amountBank","monto_banco","bank_amount","amount_bank","montoBanco"]),d=ic(a,["difference","diferencia","diff"]);return{id:String(a.id??a.employeeNumber??a.employee_number??a.account??a.cuenta??`row-${i+1}`),employee:String(a.employee??a.empleado??a.name??a.nombre??a.employee_name??"Sin nombre"),employeeNumber:String(a.employeeNumber??a.employee_number??a.codigo??""),account:a.account||a.cuenta||a.bank_account?String(a.account??a.cuenta??a.bank_account):void 0,currency:String(a.currency??a.moneda??"").toUpperCase()||void 0,amountPayroll:c,amountBank:u,difference:d??(c!==null&&u!==null?c-u:null),status:EC(a.status??a.estado,l),category:l,observation:String(a.observation??a.observacion??a.note??a.nota??a.comentario??""),source:a.source??a.fuente??l,bankNameFile:String(a.bank_name_file??a.bankNameFile??""),bankAccountHolder:String(a.bank_account_holder??a.bankAccountHolder??""),bestBambooCandidate:a.best_bamboo_candidate&&typeof a.best_bamboo_candidate=="object"?{employeeNumber:String(a.best_bamboo_candidate.employee_number??""),employeeName:String(a.best_bamboo_candidate.employee_name??""),score:ic(a.best_bamboo_candidate,["score"])}:null,ambiguousBambooMatch:!!a.ambiguous_bamboo_match}}):[]}function uv(n){const i=(Array.isArray(n)?n[0]:n)??{},a=i.originalResponse??i.original_response??i.response??i,l=a.summary??a.resumen??i.summary??i.resumen??{},c=cv(a.rows??i.rows??a.resultados??i.resultados??[]),u=cv(a.bankWithoutBamboo??i.bankWithoutBamboo??a.banco_sin_bamboo_rows??i.banco_sin_bamboo_rows??[]).map(G=>({...G,category:G.category||"banco_sin_bamboo",source:"banco_sin_bamboo",status:G.status==="Coincidencia"?"Pendiente revisión":G.status})),d=new Map;[...c,...u].forEach((G,H)=>{const Y=G.id||`${G.source??G.category??"row"}-${H}`;d.set(Y,G)});const m=Array.from(d.values()),p=Un(l.matches??l.coincidencias,c.filter(G=>G.status==="Coincidencia").length),y=Un(l.discrepancies??l.discrepancias,c.filter(G=>{const H=At(String(G.category??G.source??""));return H.includes("discrepancia")||H.includes("posible_cuenta_mal_digitada")}).length),v=Un(l.bankWithoutPayroll??l.bancoSinNomina??l.banco_sin_nomina,c.filter(G=>Ba(G,"banco_sin_nomina")).length),x=Un(l.bankWithoutBamboo??l.bancoSinBamboo??l.banco_sin_bamboo,u.length),_=Un(l.payrollWithoutAccount??l.nominaSinCuenta??l.nomina_sin_cuenta),S=Un(l.nameDifferences??l.diferenciasNombreBanco??l.diferencias_nombre_banco,c.filter(G=>At(String(G.category??"")).includes("diferencia_nombre_banco")).length),T=Un(l.possibleWrongAccounts??l.posiblesCuentasMalDigitadas??l.posibles_cuentas_mal_digitadas,c.filter(G=>At(String(G.category??"")).includes("posible_cuenta_mal_digitada")).length),j=a.metadata??i.metadata??{},k=String(j.country??j.country_code??"").toUpperCase(),M=y+v+x+_+S,C=y+v+_+S+T,P=k==="RD"?Un(l.totalPending??l.pendientes??l.pendientes_cruce_principal??l.total_pending,C):M,K=String(j.period_type??j.periodType??"").toLowerCase();return{ok:!!(a.ok??i.ok??!0),reportKind:K==="bono14"?"bono14":"nomina",executionId:a.executionId||a.execution_id||i.executionId||i.execution_id?String(a.executionId??a.execution_id??i.executionId??i.execution_id):void 0,reportUrl:a.reportUrl||a.report_url||i.reportUrl||i.report_url||i.google_sheet_url?String(a.reportUrl??a.report_url??i.reportUrl??i.report_url??i.google_sheet_url):void 0,summary:{matches:p,discrepancies:y,bankWithoutPayroll:v,bankWithoutBamboo:x,payrollWithoutAccount:_,nameDifferences:S,possibleWrongAccounts:T,totalPending:P,totalRows:m.length,totalPayroll:Un(l.totalNomina??l.total_nomina,void 0),totalBank:Un(l.totalBanco??l.total_banco,void 0),totalDifference:Un(l.diferenciaTotal??l.diferencia_total,void 0)},rows:m,message:a.message||i.message?String(a.message??i.message):void 0}}function AC(n){return n==="Coincidencia"?"bg-emerald-50 text-emerald-800 border-emerald-200":n==="Resuelto"?"bg-blue-50 text-blue-800 border-blue-200":n==="No encontrado"?"bg-amber-50 text-amber-800 border-amber-200":n==="Pendiente revisión"?"bg-neutral-100 text-neutral-700 border-neutral-300":"bg-red-50 text-[#ba1a1a] border-red-200"}function hv(n){const e=At(String(n.category??n.source??"")),i=At(n.observation??"");return n.status==="Coincidencia"||e.includes("coincidencia")?90:e.includes("posible_cuenta_mal_digitada")||i.includes("mal digitada")?1:e.includes("discrepancia")||n.status==="Riesgo"?2:e.includes("banco_sin_bamboo")?3:e.includes("banco_sin_nomina")?4:e.includes("diferencia_nombre_banco")?5:e.includes("nomina_sin_cuenta")?6:n.status==="Pendiente revisión"?7:n.status==="No encontrado"?10:20}function jC(n){return[...n].sort((e,i)=>{const a=hv(e)-hv(i);return a!==0?a:e.employee.localeCompare(i.employee,"es")})}function NC(n){const e=At(String(n.category??n.source??""));return e.includes("discrepancia")||e.includes("posible_cuenta_mal_digitada")}function Ba(n,e){return n.source===e||At(String(n.category??"")).includes(e)}function RC(n,e="nomina"){const i=At(String(n??""));return i?i.includes("posible_cuenta_mal_digitada")?"Posible cuenta mal digitada":i.includes("banco_sin_bamboo")?"Banco sin Bamboo":i.includes("banco_sin_nomina")?e==="bono14"?"Banco sin Bono 14":"Banco sin nómina":i.includes("diferencia_nombre_banco")?"Diferencia nombre banco":i.includes("nomina_sin_cuenta")?e==="bono14"?"Bono 14 sin cuenta":"Nómina sin cuenta":i.includes("discrepancia")?"Discrepancia":i.includes("coincidencia")?"Coincidencia":String(n).replace(/_/g," "):"—"}function dv(n){const e=n instanceof Error?n.message:"";return e.includes("planillas del banco repetidas")||e.toLowerCase().includes("sesión expiró")||e.toLowerCase().includes("no hay conexión a internet")?e:"No se pudo procesar el cruce. Verifica los archivos e intenta nuevamente."}function kC(n){try{return new TextDecoder("windows-1252").decode(n)}catch{return new TextDecoder("utf-8").decode(n)}}function fv(n,e){let i=0,a=!1;for(let l=0;lfv(n,a)>fv(n,i)?a:i)}function mv(n,e=zw(n)){const i=[];let a="",l=!1;for(let c=0;cc.replace(/^\uFEFF/,"").trim())}function CC(n){const e=String(n??"").replace(/\D/g,"");return/^\d{1,20}$/.test(e)?e:null}function OC(n){const e=n.split(/\r?\n/).slice(0,120);for(const i of e.slice(0,25)){const l=At(i).match(/(?:consulta\s+(?:del\s+)?)?detalle\s+(?:del\s+)?envio\s+(\d{1,20})/);if(l!=null&&l[1])return l[1]}for(let i=0;iAt(m).trim()).findIndex(m=>m==="numero de envio"||m.includes("numero de envio"));if(!(d<0))for(let m=i+1;mi.length>1).map(([i,a])=>({shipmentNumber:i,fileNames:a}))}const MC={1:["enero","january","jan"],2:["febrero","february","feb"],3:["marzo","march","mar"],4:["abril","april","apr"],5:["mayo","may"],6:["junio","june","jun"],7:["julio","july","jul"],8:["agosto","august","aug"],9:["septiembre","setiembre","september","sep"],10:["octubre","october","oct"],11:["noviembre","november","nov"],12:["diciembre","december","dec"]};function BC(n,e){const i=At(n).replace(/[_\-.()]+/g," ").replace(/\s+/g," ").trim(),a=i.match(/\b(20\d{2})\b/),l=a?Number(a[1]):void 0;let c;for(const[m,p]of Object.entries(MC))if(p.some(y=>new RegExp(`\\b${y}\\b`,"i").test(i))){c=Number(m);break}const u=i.match(/\b(1[0-2]|[1-9])\s+(1|2)\s+(20\d{2})\b/);!c&&u&&(c=Number(u[1]));let d;if((u==null?void 0:u[2])==="1")d="quincena_15";else if((u==null?void 0:u[2])==="2")d="quincena_30";else if(/\b(?:1q|q1|quincena\s*15|primera\s+quincena)\b/.test(i))d="quincena_15";else if(/\b(?:2q|q2|quincena\s*30|segunda\s+quincena|fin\s+de\s+mes)\b/.test(i))d="quincena_30";else if(/\b15\b/.test(i))d="quincena_15";else if(/\b(?:30|31)\b/.test(i))d="quincena_30";else if(e==="RD"&&l&&c){const m=new Date(l,c,0).getDate();new RegExp(`\\b${m}\\b`).test(i)&&(d="quincena_30")}return{year:l,month:c,periodType:d}}function gv(n){const e=_C();try{const i=window.localStorage.getItem(`glm_cruce_period_${n}`);if(!i)return e;const a=JSON.parse(i);if(Number.isInteger(a.year)&&Number.isInteger(a.month)&&a.month>=1&&a.month<=12&&(a.periodType==="quincena_15"||a.periodType==="quincena_30"))return a}catch{}return e}async function UC(n,e){const i=BC(n,e.code);return{...i,source:"local_fallback",requiresManualReview:!(Number.isInteger(i.year)&&Number.isInteger(i.month)&&(i.periodType==="quincena_15"||i.periodType==="quincena_30"))}}function LC({onShowToast:n,uploadedPayroll:e,setUploadedPayroll:i,uploadedPayrollFiles:a,setUploadedPayrollFiles:l,uploadedBankFiles:c,setUploadedBankFiles:u,isCruceExecuted:d,setIsCruceExecuted:m,response:p,setResponse:y,onOpenSidebar:v,operatorName:x,operatorEmail:_,resetToken:S=0,country:T}){const j=D.useMemo(()=>gv(T.code),[T.code]),k=T.code==="PA",M=T.code==="SV",C=T.code==="HN",P=T.code==="PR",K=T.code==="RD",G=k||M,H=K?"CSV / PDF":P?"PDF":"CSV",Y=K?".csv, .pdf":P?".pdf":".csv",Z=R=>K?Cd(R)||rv(R):P?rv(R):Cd(R),[se,me]=D.useState(!1),[ye,Ae]=D.useState(""),[Ne,Be]=D.useState("todos"),[L,W]=D.useState(j.year),[Q,le]=D.useState(j.month),[ue,A]=D.useState(j.periodType),[q,J]=D.useState(1),[ne,de]=D.useState(""),[ge,we]=D.useState(""),[ke,qe]=D.useState(null),[at,jn]=D.useState([]),[Nn,as]=D.useState(""),[ee,Ce]=D.useState(null),[ze,Re]=D.useState(()=>new Set),rt=`glm_cruce_period_${T.code}`,st=D.useRef(null),ht=D.useRef(null),it=D.useRef(null),Qt=D.useRef(null),$n=D.useMemo(()=>wC(),[]),Ze=D.useMemo(()=>lv(L,Q,ue),[L,Q,ue]),ci=T.code==="GT"&&Q===7&&ue==="quincena_15",gt=D.useMemo(()=>TC(L),[L]),jt=(p==null?void 0:p.reportKind)==="bono14",qn=jt?gt.label:Ze.label,Rn=D.useMemo(()=>jC((p==null?void 0:p.rows)??[]),[p==null?void 0:p.rows]),Cs=D.useMemo(()=>{const R=At(ge.trim());return c.map((X,ae)=>({file:X,originalIndex:ae})).filter(({file:X})=>!R||At(X.name).includes(R))},[c,ge]),$i=D.useMemo(()=>{const R=At(Nn.trim());return at.map((X,ae)=>({file:X,originalIndex:ae})).filter(({file:X})=>!R||At(X.name).includes(R))},[at,Nn]),ui=Rn.filter(R=>{const X=At(ne.trim());return At(`${R.employee} ${R.employeeNumber} ${R.account??""} ${R.observation} ${R.category??""} ${R.source??""}`).includes(X)?Ne==="discrepancias"?NC(R):Ne==="coincidencias"?R.status==="Coincidencia":Ne==="banco_sin_nomina"?Ba(R,"banco_sin_nomina"):Ne==="banco_sin_bamboo"?Ba(R,"banco_sin_bamboo"):Ne==="diferencia_nombre_banco"?Ba(R,"diferencia_nombre_banco"):Ne==="nomina_sin_cuenta"?Ba(R,"nomina_sin_cuenta"):!0:!1}),rs=10,yt=Math.max(1,Math.ceil(ui.length/rs)),cn=ui.slice((q-1)*rs,q*rs);D.useEffect(()=>{q>yt&&J(yt)},[q,yt]);const Vt=D.useMemo(()=>{var R;return((R=av.find(X=>X.value===ue))==null?void 0:R.description)??""},[ue]);D.useEffect(()=>{const R=gv(T.code);W(R.year),le(R.month),A(R.periodType),J(1),de(""),we(""),as(""),qe(null),jn([]),Be("todos"),Ce(null),Re(new Set)},[T.code]),D.useEffect(()=>{window.localStorage.setItem(rt,JSON.stringify({year:L,month:Q,periodType:ue}))},[rt,L,Q,ue]),D.useEffect(()=>{de(""),we(""),as(""),qe(null),jn([]),Be("todos"),J(1),Ae(""),me(!1),Ce(null),Re(new Set),st.current&&(st.current.value=""),ht.current&&(ht.current.value=""),it.current&&(it.current.value=""),Qt.current&&(Qt.current.value="")},[S]),D.useEffect(()=>{c.length===0&&ge&&we("")},[c.length,ge]),D.useEffect(()=>{at.length===0&&Nn&&as("")},[at.length,Nn]);const Ct=()=>{m(!1),y(null),J(1),de(""),Be("todos")},Eo=async(R,X=1)=>{const ae=await UC(R.name,T);if(Number.isInteger(ae.year)&&Number.isInteger(ae.month)&&(ae.periodType==="quincena_15"||ae.periodType==="quincena_30")){W(ae.year),le(ae.month),A(ae.periodType);const hn=lv(ae.year,ae.month,ae.periodType),dt=X>1?`${X} archivos de nómina cargados.`:"Nómina cargada.";return ae.requiresManualReview?n(`${dt} Período sugerido: ${hn.label}. Confirma los datos antes de ejecutar.`,"info"):n(`${dt} Período detectado: ${hn.label}.`,"success"),!0}return!1},Ao=async R=>{i({name:R.name,size:Bc(R.size),type:"payroll",rawFile:R}),l([]),Ct(),await Eo(R)||n("Archivo de nómina cargado con éxito.","success")},hi=async R=>{const X=R.filter(Kr);if(X.length===0){n(`Formato inválido. ${T.name} requiere uno o varios archivos Excel (.xlsx, .xls).`,"error");return}const ae=new Set(a.map(Je=>{var tt;return`${Je.name}|${((tt=Je.rawFile)==null?void 0:tt.size)??Je.size}`})),un=SC(X).filter(Je=>{var tt;return!ae.has(`${Je.name}|${((tt=Je.rawFile)==null?void 0:tt.size)??Je.size}`)}),hn=[...a,...un];l(hn),i(null),Ct();const dt=X.find(Je=>/quincenal/i.test(Je.name))||X[0];await Eo(dt,hn.length)||n(`${un.length} archivo(s) de nómina de ${T.name} cargado(s) con éxito.`,"success")},Fn=R=>{R.preventDefault()},di=async R=>{R.preventDefault();const X=Array.from(R.dataTransfer.files);if(X.length===0)return;if(G){await hi(X);return}const ae=X[0];Kr(ae)?await Ao(ae):n("Formato inválido. Por favor carga un archivo Excel (.xlsx, .xls).","error")},os=R=>{R.preventDefault();const ae=Array.from(R.dataTransfer.files).filter(Z);if(ae.length===0){n(`Formato inválido. Por favor carga uno o varios archivos ${H} (${Y}).`,"error");return}u([...c,...Od(ae)]),Ct(),n(`${ae.length} archivo(s) del banco cargado(s) con éxito.`,"success")},qi=async R=>{const X=Array.from(R.target.files||[]);if(X.length===0)return;if(G){await hi(X);return}const ae=X[0];Kr(ae)?await Ao(ae):n("Formato inválido. Por favor carga un archivo Excel (.xlsx, .xls).","error")},fi=R=>{l(a.filter((X,ae)=>ae!==R)),st.current&&(st.current.value=""),Ct(),n("Archivo de nómina removido.","info")},Gc=R=>{const X=R.target.files;if(!X||X.length===0)return;const ae=Array.from(X).filter(Z);if(ae.length===0){n(`Formato inválido. Por favor carga uno o varios archivos ${H} (${Y}).`,"error");return}u([...c,...Od(ae)]),Ct(),n(`${ae.length} archivo(s) del banco cargado(s) con éxito.`,"success")},jo=R=>{u(c.filter((X,ae)=>ae!==R)),ht.current&&(ht.current.value=""),Ct(),n("Planilla de banco removida.","info")},Qa=()=>{i(null),l([]),u([]),we(""),st.current&&(st.current.value=""),ht.current&&(ht.current.value=""),Ct(),n("Todos los archivos cargados fueron eliminados.","info")},Os=R=>{qe({name:R.name,size:Bc(R.size),type:"payroll",rawFile:R}),Ct(),n("Archivo Excel de Bono 14 cargado con éxito.","success")},Kc=R=>{R.preventDefault();const X=R.dataTransfer.files[0];if(X){if(!Kr(X)){n("Formato inválido. El Bono 14 requiere un archivo Excel (.xlsx, .xls).","error");return}Os(X)}},No=R=>{var ae;const X=(ae=R.target.files)==null?void 0:ae[0];if(X){if(!Kr(X)){n("Formato inválido. El Bono 14 requiere un archivo Excel (.xlsx, .xls).","error");return}Os(X)}},Za=R=>{const X=R.filter(Cd);if(X.length===0){n("Formato inválido. Carga uno o varios archivos CSV del Bono 14.","error");return}jn([...at,...Od(X)]),Ct(),n(`${X.length} archivo(s) bancario(s) de Bono 14 cargado(s).`,"success")},Ro=R=>{R.preventDefault(),Za(Array.from(R.dataTransfer.files))},Wa=R=>{var X;(X=R.target.files)!=null&&X.length&&Za(Array.from(R.target.files))},er=R=>{jn(at.filter((X,ae)=>ae!==R)),Qt.current&&(Qt.current.value=""),Ct(),n("Archivo bancario de Bono 14 removido.","info")},ko=async()=>{if(se)return;if(!L||!Q||!ue){n("Debes seleccionar año, mes y tipo de cruce antes de ejecutar.","error");return}const R=G?a:e?[e]:[];if(R.length===0||R.some(X=>!X.rawFile)){n(G?`Debes cargar todos los archivos de nómina de ${T.name} correspondientes al período antes de ejecutar el cruce.`:"Debes cargar la nómina antes de ejecutar el cruce.","error");return}if(c.length===0||c.some(X=>!X.rawFile)){n("Debes cargar al menos una planilla del banco antes de ejecutar el cruce.","error");return}me(!0),Ae("Validando archivos..."),J(1);try{const X=P||K?[]:await pv(c);if(X.length>0){const Ue=X.map(Ve=>`Número de envío ${Ve.shipmentNumber}: ${Ve.fileNames.join(", ")}`).join(` +`);throw new Error(`Hay planillas del banco repetidas. Revisa los archivos cargados antes de continuar. +${Ue}`)}const ae=vC(T.code);if(!ae)throw new Error("No se pudo procesar el cruce. El servicio de conciliación no está disponible.");const un=sv();Ae("Reactivando conexión segura..."),await nv(ae);const hn=iv(ae,un),dt=R.find(Ue=>/quincenal/i.test(Ue.name))||R[0],dn={country:T.code,country_name:T.name,year:L,month:Q,period_type:ue,period_label:Ze.label,period_start:Ze.start,period_end:Ze.end,payroll_file_name:dt.name,payroll_file_names:R.map(Ue=>Ue.name),bank_file_names:c.map(Ue=>Ue.name),requested_by_name:x,requested_by_email:_,auth_mode:"temporal_sin_login",source_app:"portal-cruce-cuentas-glm",client_request_id:un};Ae("Procesando cruce de cuentas...");const Je=new FormData;Je.append("metadata",JSON.stringify(dn)),Object.entries(dn).forEach(([Ue,Ve])=>{Je.append(Ue,Array.isArray(Ve)?JSON.stringify(Ve):String(Ve))}),G&&R.forEach((Ue,Ve)=>{Ue.rawFile&&(Je.append("payroll_files",Ue.rawFile,Ue.name),Je.append(`payroll_file_${Ve+1}`,Ue.rawFile,Ue.name))}),dt.rawFile&&Je.append("payroll_file",dt.rawFile,dt.name),c.forEach((Ue,Ve)=>{Ue.rawFile&&(Je.append("bank_files",Ue.rawFile,Ue.name),Je.append(`bank_file_${Ve+1}`,Ue.rawFile,Ue.name))});const tt=await fetch(hn,{method:"POST",body:Je,cache:"no-store",credentials:"omit"});Ae("Generando reporte...");const Pe=(tt.headers.get("content-type")??"").includes("application/json")?await tt.json():{ok:tt.ok,message:await tt.text()};if(!tt.ok||(Pe==null?void 0:Pe.ok)===!1)throw new Error(typeof(Pe==null?void 0:Pe.message)=="string"?Pe.message:"No se pudo procesar el cruce. Verifica los archivos e intenta nuevamente.");const Nt=uv(Pe);Nt.reportKind="nomina",y(Nt),m(!0),n(Nt.message||"Cruce procesado correctamente.","success"),setTimeout(()=>{const Ue=document.getElementById("resultados-seccion");Ue&&Ue.scrollIntoView({behavior:"smooth",block:"start"})},150)}catch(X){const ae=dv(X);m(!1),y(null),n(ae,"error")}finally{me(!1),Ae("")}},Co=async()=>{if(!se){if(!ci){n("El cruce de Bono 14 solo está disponible en Guatemala para julio · Quincena 15.","error");return}if(!(ke!=null&&ke.rawFile)){n("Debes cargar el Excel de Bono 14 antes de generar el reporte.","error");return}if(at.length===0||at.some(R=>!R.rawFile)){n("Debes cargar al menos un CSV bancario del Bono 14.","error");return}me(!0),Ae("Validando archivos de Bono 14..."),J(1);try{const R=await pv(at);if(R.length>0){const Pe=R.map(Nt=>`Número de envío ${Nt.shipmentNumber}: ${Nt.fileNames.join(", ")}`).join(` +`);throw new Error(`Hay planillas del banco repetidas. Revisa los archivos cargados antes de continuar. +${Pe}`)}const X=xC();if(!X)throw new Error("No se pudo procesar el Bono 14. El webhook VITE_N8N_GUATEMALA_BONO14_WEBHOOK_URL no está configurado.");const ae=sv();Ae("Reactivando conexión segura..."),await nv(X);const un=iv(X,ae),hn={country:"GT",country_name:"Guatemala",year:L,month:7,period_type:"bono14",report_kind:"bono14",period_label:gt.label,period_start:gt.start,period_end:gt.end,payroll_file_name:ke.name,bank_file_names:at.map(Pe=>Pe.name),requested_by_name:x,requested_by_email:_,auth_mode:"temporal_sin_login",source_app:"portal-cruce-cuentas-glm-bono14",client_request_id:ae},dt=new FormData;dt.append("metadata",JSON.stringify(hn)),Object.entries(hn).forEach(([Pe,Nt])=>{dt.append(Pe,Array.isArray(Nt)?JSON.stringify(Nt):String(Nt))}),dt.append("payroll_file",ke.rawFile,ke.name),at.forEach((Pe,Nt)=>{Pe.rawFile&&(dt.append("bank_files",Pe.rawFile,Pe.name),dt.append(`bank_file_${Nt+1}`,Pe.rawFile,Pe.name))}),Ae("Procesando Bono 14...");const dn=await fetch(un,{method:"POST",body:dt,cache:"no-store",credentials:"omit"});Ae("Generando reporte independiente de Bono 14...");const tt=(dn.headers.get("content-type")??"").includes("application/json")?await dn.json():{ok:dn.ok,message:await dn.text()};if(!dn.ok||(tt==null?void 0:tt.ok)===!1)throw new Error(typeof(tt==null?void 0:tt.message)=="string"?tt.message:"No se pudo procesar el Bono 14. Verifica los archivos e intenta nuevamente.");const kn=uv(tt);kn.reportKind="bono14",y(kn),m(!0),n(kn.message||"Bono 14 procesado correctamente.","success"),setTimeout(()=>{const Pe=document.getElementById("resultados-seccion");Pe&&Pe.scrollIntoView({behavior:"smooth",block:"start"})},150)}catch(R){m(!1),y(null),n(dv(R),"error")}finally{me(!1),Ae("")}}},In=()=>{if(p!=null&&p.reportUrl){window.open(p.reportUrl,"_blank","noopener,noreferrer");return}n("El reporte aún no tiene un enlace disponible.","info")};return g.jsxs("div",{className:"flex-1 flex flex-col min-h-screen bg-neutral-50 text-neutral-800 font-sans",children:[g.jsxs("header",{className:"bg-white border-b-4 border-[#6CC24A] flex justify-between items-center w-full px-4 sm:px-8 h-[84px] sticky top-0 z-40 shadow-sm gap-x-4",children:[g.jsxs("div",{className:"flex items-center gap-2 sm:gap-3 min-w-0",children:[g.jsx("button",{onClick:v,className:"md:hidden p-2 -ml-2 text-neutral-600 hover:text-neutral-800 hover:bg-neutral-100 transition-colors flex-shrink-0","aria-label":"Abrir menú",children:g.jsx(uw,{className:"w-6 h-6"})}),g.jsx("h1",{className:"text-xs sm:text-sm md:text-lg lg:text-2xl font-black text-[#4F758B] tracking-tight uppercase flex items-center gap-1.5 sm:gap-2 min-w-0",children:g.jsxs("span",{className:"truncate",children:["Cruce de Cuentas GLM - ",T.name]})})]}),g.jsxs("div",{className:"flex-shrink-0 flex items-center gap-2",children:[g.jsx(Uw,{country:T,operatorName:x,operatorEmail:_,section:"Cruce de Cuentas",onShowToast:n}),g.jsx("div",{className:"border border-neutral-200 bg-white px-2.5 py-2 shadow-sm","aria-label":`Bandera de ${T.name}`,children:g.jsx("img",{src:T.flag,alt:`Bandera de ${T.name}`,className:"h-5 sm:h-6 w-auto object-contain"})})]})]}),g.jsxs("main",{className:"flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 py-8 flex flex-col gap-8",children:[g.jsxs("section",{className:"bg-white border border-[#D0D0D0] p-5 shadow-sm",children:[g.jsx("div",{className:"flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4 mb-5",children:g.jsxs("div",{className:"flex items-center gap-3",children:[g.jsx("div",{className:"bg-[#4F758B]/10 p-2 rounded-full",children:g.jsx(cw,{className:"w-5 h-5 text-[#4F758B]"})}),g.jsx("div",{className:"pt-0.5",children:g.jsx("h2",{className:"text-sm font-black text-[#4F758B] uppercase tracking-wider leading-none",children:"Datos del cruce"})})]})}),g.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[g.jsxs("label",{className:"flex flex-col gap-1.5",children:[g.jsx("span",{className:"text-[10px] font-black uppercase tracking-wider text-neutral-500",children:"Año"}),g.jsx("select",{value:L,onChange:R=>{W(Number(R.target.value)),Ct()},className:"border border-[#D0D0D0] bg-white px-3 py-2.5 text-sm font-bold text-neutral-700 focus:outline-none focus:border-[#4F758B]",children:$n.map(R=>g.jsx("option",{value:R,children:R},R))})]}),g.jsxs("label",{className:"flex flex-col gap-1.5",children:[g.jsx("span",{className:"text-[10px] font-black uppercase tracking-wider text-neutral-500",children:"Mes"}),g.jsx("select",{value:Q,onChange:R=>{le(Number(R.target.value)),Ct()},className:"border border-[#D0D0D0] bg-white px-3 py-2.5 text-sm font-bold text-neutral-700 focus:outline-none focus:border-[#4F758B]",children:Lw.map(R=>g.jsx("option",{value:R.value,children:R.label},R.value))})]}),g.jsxs("label",{className:"flex flex-col gap-1.5",children:[g.jsx("span",{className:"text-[10px] font-black uppercase tracking-wider text-neutral-500",children:"Tipo de cruce"}),g.jsx("select",{value:ue,onChange:R=>{A(R.target.value),Ct()},className:"border border-[#D0D0D0] bg-white px-3 py-2.5 text-sm font-bold text-neutral-700 focus:outline-none focus:border-[#4F758B]",children:av.map(R=>g.jsx("option",{value:R.value,children:R.label},R.value))})]})]}),g.jsxs("div",{className:"mt-4 grid grid-cols-1 md:grid-cols-[1fr_auto] gap-3 items-center bg-[#4F758B]/5 border border-[#4F758B]/10 px-4 py-3",children:[g.jsxs("div",{className:"flex items-start gap-2 text-xs text-neutral-600",children:[g.jsx(m2,{className:"w-4 h-4 text-[#4F758B] mt-0.5 flex-shrink-0"}),g.jsxs("div",{children:[g.jsx("span",{className:"font-black text-[#4F758B]",children:"Período calculado:"})," ",ov(Ze.start)," al ",ov(Ze.end),g.jsx("p",{className:"text-[10px] text-neutral-500 mt-0.5",children:Vt})]})]}),g.jsx("div",{className:"text-[10px] font-bold text-neutral-500 uppercase tracking-wider",children:Ze.label})]})]}),(G||C||P||K)&&(e!==null||a.length>0||c.length>0)&&g.jsx("div",{className:"flex justify-end",style:{marginBottom:"-20px"},children:g.jsxs("button",{type:"button",onClick:Qa,className:"inline-flex items-center gap-2 border border-red-100 bg-white px-3 py-2 text-[10px] font-black text-red-600 hover:bg-red-50 transition-colors uppercase tracking-wide shadow-sm","aria-label":"Borrar todos los archivos cargados",title:"Eliminar de una vez todas las nóminas y planillas del banco cargadas",children:[g.jsx(Ta,{className:"w-4 h-4"}),"Borrar todo"]})}),g.jsxs("section",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[g.jsxs("div",{className:"bg-white border border-[#D0D0D0] p-6 flex flex-col justify-between relative shadow-sm hover:shadow-md transition-shadow",children:[g.jsx("div",{className:"absolute top-0 left-0 w-full h-1 bg-[#4F758B]"}),g.jsxs("div",{children:[g.jsxs("div",{className:"flex items-center gap-2.5 mb-4",children:[g.jsx(Ca,{className:"w-5 h-5 text-[#4F758B]"}),g.jsx("h2",{className:"text-sm font-black text-neutral-800 uppercase tracking-wider",children:"1. Carga de Nómina"})]}),g.jsx("input",{type:"file",ref:st,onChange:qi,accept:".xlsx,.xls",multiple:G,className:"hidden"}),G?a.length>0?g.jsxs("div",{className:"space-y-3",children:[g.jsxs("div",{className:"border border-[#4F758B]/20 bg-[#4F758B]/5 px-4 py-3",children:[g.jsxs("p",{className:"text-[10px] font-black uppercase tracking-wider text-[#4F758B]",children:[a.length," archivo(s) de nómina cargado(s)"]}),g.jsx("p",{className:"text-[10px] text-neutral-500 mt-1",children:k?"Incluye la quincenal y todas las planillas extraordinarias, vacaciones o XIII Mes que correspondan al período.":"Incluye todos los archivos de nómina de El Salvador que correspondan a la quincena seleccionada (General, Karla Elias, Nestlé, Motorola u otros del mismo formato)."})]}),g.jsx("div",{className:"max-h-[260px] overflow-y-auto border border-neutral-200 divide-y divide-neutral-100",children:a.map((R,X)=>g.jsxs("div",{className:"bg-white px-4 py-3 flex items-center justify-between gap-3",children:[g.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[g.jsx(Ca,{className:"w-6 h-6 text-[#6CC24A] flex-shrink-0"}),g.jsxs("div",{className:"overflow-hidden",children:[g.jsx("p",{className:"text-xs font-bold text-neutral-700 truncate max-w-[290px]",title:R.name,children:R.name}),g.jsxs("p",{className:"text-[10px] text-neutral-400 font-mono mt-0.5",children:[R.size," • Excel"]})]})]}),g.jsx("button",{onClick:()=>fi(X),className:"p-1.5 text-neutral-400 hover:text-red-500 hover:bg-neutral-100 transition-all rounded","aria-label":`Remover ${R.name}`,children:g.jsx(Ta,{className:"w-4.5 h-4.5"})})]},`${R.name}-${X}`))}),g.jsx("button",{type:"button",onClick:()=>{var R;return(R=st.current)==null?void 0:R.click()},className:"w-full border border-dashed border-[#4F758B]/40 bg-white px-4 py-2.5 text-[10px] font-black text-[#4F758B] hover:bg-[#4F758B]/5 transition-colors uppercase tracking-wide",children:"Agregar más archivos de nómina"})]}):g.jsxs("div",{onDragOver:Fn,onDrop:di,onClick:()=>{var R;return(R=st.current)==null?void 0:R.click()},className:"border-2 border-dashed border-[#D0D0D0] bg-neutral-50 hover:bg-[#4F758B]/5 hover:border-[#4F758B]/40 transition-colors flex flex-col items-center justify-center py-10 px-4 text-center cursor-pointer min-h-[190px]",children:[g.jsx(Ir,{className:"w-8 h-8 text-neutral-300 mb-2"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700",children:"Arrastre la nómina y sus suplementos"}),g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1 font-medium",children:"Puede seleccionar varios .xlsx / .xls a la vez"}),g.jsx("button",{type:"button",className:"mt-4 border border-[#D0D0D0] bg-white px-4 py-1.5 text-[10px] font-bold text-neutral-600 hover:border-[#4F758B] hover:text-[#4F758B] transition-colors shadow-sm uppercase tracking-wide",children:"Seleccionar Archivos"})]}):e?g.jsxs("div",{className:"border border-[#6CC24A]/30 bg-[#6CC24A]/5 p-5 flex items-center justify-between gap-3",children:[g.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[g.jsx(Ca,{className:"w-8 h-8 text-[#6CC24A] flex-shrink-0"}),g.jsxs("div",{className:"overflow-hidden",children:[g.jsx("p",{className:"text-xs font-bold text-neutral-700 truncate max-w-[300px]",title:e.name,children:e.name}),g.jsxs("p",{className:"text-[10px] text-neutral-400 font-mono mt-0.5",children:[e.size," • Excel"]})]})]}),g.jsx("button",{onClick:()=>{i(null),st.current&&(st.current.value=""),Ct(),n("Nómina removida.","info")},className:"p-1.5 text-neutral-400 hover:text-red-500 hover:bg-neutral-100 transition-all rounded","aria-label":"Remover nómina",children:g.jsx(Ta,{className:"w-4.5 h-4.5"})})]}):g.jsxs("div",{onDragOver:Fn,onDrop:di,onClick:()=>{var R;return(R=st.current)==null?void 0:R.click()},className:"border-2 border-dashed border-[#D0D0D0] bg-neutral-50 hover:bg-[#4F758B]/5 hover:border-[#4F758B]/40 transition-colors flex flex-col items-center justify-center py-10 px-4 text-center cursor-pointer min-h-[190px]",children:[g.jsx(Ir,{className:"w-8 h-8 text-neutral-300 mb-2"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700",children:"Arrastre y suelte archivo Excel"}),g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1 font-medium",children:"Formato .xlsx, .xls"}),g.jsx("button",{type:"button",className:"mt-4 border border-[#D0D0D0] bg-white px-4 py-1.5 text-[10px] font-bold text-neutral-600 hover:border-[#4F758B] hover:text-[#4F758B] transition-colors shadow-sm uppercase tracking-wide",children:"Seleccionar Archivo"})]})]})]}),g.jsxs("div",{className:"bg-white border border-[#D0D0D0] p-6 flex flex-col justify-between relative shadow-sm hover:shadow-md transition-shadow",children:[g.jsx("div",{className:"absolute top-0 left-0 w-full h-1 bg-[#4F758B]"}),g.jsxs("div",{children:[g.jsxs("div",{className:"flex items-center gap-2.5 mb-2",children:[g.jsx(Xl,{className:"w-5 h-5 text-[#4F758B]"}),g.jsx("h2",{className:"text-sm font-black text-neutral-800 uppercase tracking-wider",children:"2. Carga de Planillas del Banco"})]}),g.jsx("p",{className:"text-[11px] text-neutral-500 mb-4 leading-relaxed",children:"Puede subir múltiples archivos separados o un archivo consolidado del período."}),g.jsx("input",{type:"file",ref:ht,onChange:Gc,accept:K?".csv,.pdf":P?".pdf":".csv",multiple:!0,className:"hidden"}),g.jsxs("div",{onDragOver:Fn,onDrop:os,onClick:()=>{var R;return(R=ht.current)==null?void 0:R.click()},className:"border-2 border-dashed border-[#D0D0D0] bg-neutral-50 hover:bg-[#4F758B]/5 hover:border-[#4F758B]/40 transition-colors flex flex-col items-center justify-center py-8 px-4 text-center cursor-pointer min-h-[130px]",children:[g.jsx(Ir,{className:"w-7 h-7 text-neutral-300 mb-2"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700",children:`Arrastre y suelte archivo ${H}`}),g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1 font-medium",children:`Formato ${Y}`}),g.jsx("button",{type:"button",className:"mt-4 border border-[#D0D0D0] bg-white px-4 py-1.5 text-[10px] font-bold text-neutral-600 hover:border-[#4F758B] hover:text-[#4F758B] transition-colors shadow-sm uppercase tracking-wide",children:"Seleccionar Archivos"})]}),c.length>0&&g.jsxs("div",{className:"mt-4 border border-neutral-200 bg-white",children:[g.jsxs("div",{className:"p-3 border-b border-neutral-200 bg-neutral-50",children:[g.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 mb-2",children:[g.jsxs("div",{children:[g.jsxs("p",{className:"text-[11px] font-black text-neutral-700 uppercase tracking-wide",children:[c.length," ",c.length===1?"archivo cargado":"archivos cargados"]}),g.jsx("p",{className:"text-[9px] text-neutral-400 mt-0.5",children:"Busque por nombre para localizar y eliminar una planilla rápidamente."})]}),ge&&g.jsx("button",{type:"button",onClick:R=>{R.stopPropagation(),we("")},className:"self-start sm:self-auto text-[9px] font-bold uppercase tracking-wide text-[#4F758B] hover:underline",children:"Limpiar búsqueda"})]}),g.jsxs("div",{className:"relative",children:[g.jsx(Xr,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-neutral-400 pointer-events-none"}),g.jsx("input",{type:"search",value:ge,onChange:R=>we(R.target.value),onClick:R=>R.stopPropagation(),placeholder:`Buscar archivo ${H} por nombre...`,className:"w-full h-9 pl-9 pr-3 border border-[#D0D0D0] bg-white text-[11px] text-neutral-700 outline-none focus:border-[#4F758B] focus:ring-2 focus:ring-[#4F758B]/10 transition-all","aria-label":`Buscar archivos ${H} cargados`})]}),ge&&g.jsxs("p",{className:"text-[9px] text-neutral-400 mt-2",children:["Mostrando ",Cs.length," de ",c.length," archivos."]})]}),g.jsx("div",{className:"max-h-[330px] overflow-y-auto overscroll-contain p-2 space-y-2",children:Cs.length>0?Cs.map(({file:R,originalIndex:X})=>g.jsxs("div",{className:"border border-neutral-200 bg-white px-3 py-3 flex items-center justify-between gap-3 hover:border-[#4F758B]/40 hover:bg-[#4F758B]/[0.025] transition-colors",children:[g.jsxs("div",{className:"flex items-start gap-3 min-w-0 flex-1",children:[g.jsx("div",{className:"w-7 h-7 mt-0.5 border border-[#4F758B]/20 bg-[#4F758B]/5 flex items-center justify-center flex-shrink-0",children:g.jsx(Xl,{className:"w-4 h-4 text-[#4F758B]"})}),g.jsxs("div",{className:"min-w-0 flex-1",children:[g.jsx("p",{className:"text-[11px] leading-4 font-bold text-neutral-700 whitespace-normal break-words",title:R.name,children:R.name}),g.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[g.jsx("span",{className:"text-[9px] text-neutral-400 font-mono",children:R.size}),g.jsx("span",{className:"text-[8px] font-bold uppercase tracking-wide text-[#4F758B] bg-[#4F758B]/5 border border-[#4F758B]/10 px-1.5 py-0.5",children:H})]})]})]}),g.jsx("button",{type:"button",onClick:ae=>{ae.stopPropagation(),jo(X)},className:"w-8 h-8 flex items-center justify-center flex-shrink-0 text-neutral-400 hover:text-red-600 hover:bg-red-50 border border-transparent hover:border-red-100 rounded transition-colors","aria-label":`Remover ${R.name}`,title:`Eliminar ${R.name}`,children:g.jsx(Ta,{className:"w-4 h-4"})})]},`${R.name}-${X}`)):g.jsxs("div",{className:"py-8 px-4 text-center",children:[g.jsx(Xr,{className:"w-5 h-5 text-neutral-300 mx-auto mb-2"}),g.jsx("p",{className:"text-[11px] font-bold text-neutral-600",children:"No encontramos archivos con ese nombre."}),g.jsx("p",{className:"text-[9px] text-neutral-400 mt-1",children:"Pruebe con otra parte del nombre del archivo."})]})})]})]})]})]}),ci&&g.jsx("section",{className:"bg-white border border-[#D0D0D0] shadow-sm",children:g.jsxs("div",{className:"border-t-4 border-[#6CC24A] p-5 sm:p-6",children:[g.jsxs("div",{className:"flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4 mb-5",children:[g.jsxs("div",{className:"flex items-start gap-3",children:[g.jsx("div",{className:"bg-[#6CC24A]/10 p-2 rounded-full",children:g.jsx(xb,{className:"w-5 h-5 text-[#4F758B]"})}),g.jsxs("div",{children:[g.jsx("h2",{className:"text-sm font-black text-[#4F758B] uppercase tracking-wider",children:"Bono 14 · Reporte independiente"}),g.jsx("p",{className:"text-[11px] text-neutral-500 mt-1 max-w-3xl leading-relaxed",children:"Esta sección aparece únicamente para Guatemala · Julio · Quincena 15. El Bono 14 se procesa separado de la nómina quincenal y genera su propio Google Sheet e histórico."})]})]}),g.jsxs("div",{className:"text-left lg:text-right",children:[g.jsx("p",{className:"text-[9px] font-black uppercase tracking-wider text-neutral-400",children:"Período del Bono 14"}),g.jsxs("p",{className:"text-[11px] font-bold text-[#4F758B] mt-1",children:[gt.start," al ",gt.end]})]})]}),g.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-5",children:[g.jsxs("div",{className:"border border-neutral-200 p-4 bg-neutral-50/50",children:[g.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[g.jsx(Ca,{className:"w-4.5 h-4.5 text-[#4F758B]"}),g.jsx("h3",{className:"text-xs font-black uppercase tracking-wider text-neutral-700",children:"1. Excel de Bono 14"})]}),g.jsx("p",{className:"text-[10px] text-neutral-500 mb-3",children:"Archivo anual con los montos calculados de Bono 14."}),g.jsx("input",{type:"file",ref:it,onChange:No,accept:".xlsx,.xls",className:"hidden"}),ke?g.jsxs("div",{className:"border border-neutral-200 bg-white px-3 py-3 flex items-center justify-between gap-3",children:[g.jsxs("div",{className:"min-w-0",children:[g.jsx("p",{className:"text-[11px] font-bold text-neutral-700 break-words",title:ke.name,children:ke.name}),g.jsxs("p",{className:"text-[9px] text-neutral-400 font-mono mt-1",children:[ke.size," · Excel"]})]}),g.jsx("button",{type:"button",onClick:()=>{qe(null),it.current&&(it.current.value=""),Ct(),n("Excel de Bono 14 removido.","info")},className:"w-8 h-8 flex items-center justify-center text-neutral-400 hover:text-red-600 hover:bg-red-50 border border-transparent hover:border-red-100 rounded transition-colors","aria-label":"Remover Excel de Bono 14",children:g.jsx(Ta,{className:"w-4 h-4"})})]}):g.jsxs("div",{onDragOver:Fn,onDrop:Kc,onClick:()=>{var R;return(R=it.current)==null?void 0:R.click()},className:"border-2 border-dashed border-[#D0D0D0] bg-white hover:bg-[#4F758B]/5 hover:border-[#4F758B]/40 transition-colors py-8 px-4 text-center cursor-pointer",children:[g.jsx(Ir,{className:"w-7 h-7 text-neutral-300 mx-auto mb-2"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700",children:"Arrastre el Excel de Bono 14"}),g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1",children:"Formato .xlsx, .xls"}),g.jsx("button",{type:"button",className:"mt-4 border border-[#D0D0D0] bg-white px-4 py-1.5 text-[10px] font-bold text-neutral-600 hover:border-[#4F758B] hover:text-[#4F758B] transition-colors shadow-sm uppercase tracking-wide",children:"Seleccionar Archivo"})]})]}),g.jsxs("div",{className:"border border-neutral-200 p-4 bg-neutral-50/50",children:[g.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[g.jsx(Xl,{className:"w-4.5 h-4.5 text-[#4F758B]"}),g.jsx("h3",{className:"text-xs font-black uppercase tracking-wider text-neutral-700",children:"2. CSV bancarios del Bono 14"})]}),g.jsx("p",{className:"text-[10px] text-neutral-500 mb-3",children:"Puede cargar todos los envíos bancarios correspondientes al Bono 14."}),g.jsx("input",{type:"file",ref:Qt,onChange:Wa,accept:".csv",multiple:!0,className:"hidden"}),g.jsxs("div",{onDragOver:Fn,onDrop:Ro,onClick:()=>{var R;return(R=Qt.current)==null?void 0:R.click()},className:"border-2 border-dashed border-[#D0D0D0] bg-white hover:bg-[#4F758B]/5 hover:border-[#4F758B]/40 transition-colors py-6 px-4 text-center cursor-pointer",children:[g.jsx(Ir,{className:"w-6 h-6 text-neutral-300 mx-auto mb-2"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700",children:"Arrastre uno o varios CSV"}),g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1",children:"Formato .csv"}),g.jsx("button",{type:"button",className:"mt-4 border border-[#D0D0D0] bg-white px-4 py-1.5 text-[10px] font-bold text-neutral-600 hover:border-[#4F758B] hover:text-[#4F758B] transition-colors shadow-sm uppercase tracking-wide",children:"Seleccionar Archivos"})]}),at.length>0&&g.jsxs("div",{className:"mt-3 border border-neutral-200 bg-white",children:[g.jsxs("div",{className:"p-3 border-b border-neutral-200 bg-neutral-50",children:[g.jsxs("div",{className:"relative",children:[g.jsx(Xr,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-neutral-400 pointer-events-none"}),g.jsx("input",{type:"search",value:Nn,onChange:R=>as(R.target.value),onClick:R=>R.stopPropagation(),placeholder:"Buscar CSV de Bono 14...",className:"w-full h-9 pl-9 pr-3 border border-[#D0D0D0] bg-white text-[11px] text-neutral-700 outline-none focus:border-[#4F758B]"})]}),g.jsxs("p",{className:"text-[9px] text-neutral-400 mt-2",children:[at.length," archivo(s) cargado(s)."]})]}),g.jsx("div",{className:"max-h-[250px] overflow-y-auto p-2 space-y-2",children:$i.map(({file:R,originalIndex:X})=>g.jsxs("div",{className:"border border-neutral-200 px-3 py-2.5 flex items-start justify-between gap-3",children:[g.jsxs("div",{className:"min-w-0",children:[g.jsx("p",{className:"text-[10px] leading-4 font-bold text-neutral-700 break-words",children:R.name}),g.jsx("p",{className:"text-[9px] text-neutral-400 font-mono mt-0.5",children:R.size})]}),g.jsx("button",{type:"button",onClick:ae=>{ae.stopPropagation(),er(X)},className:"w-8 h-8 flex items-center justify-center flex-shrink-0 text-neutral-400 hover:text-red-600 hover:bg-red-50 rounded transition-colors","aria-label":`Remover ${R.name}`,children:g.jsx(Ta,{className:"w-4 h-4"})})]},`bonus14-${R.name}-${X}`))})]})]})]}),g.jsxs("div",{className:"mt-5 flex flex-col items-center gap-2",children:[g.jsxs("button",{type:"button",onClick:Co,disabled:se||!(ke!=null&&ke.rawFile)||at.length===0,className:"inline-flex items-center justify-center gap-2 bg-[#4F758B] hover:bg-[#3d6378] text-white px-7 py-3 text-xs font-black uppercase tracking-wider transition-colors disabled:opacity-45 disabled:cursor-not-allowed min-w-[280px]",children:[se?g.jsx(Ha,{className:"w-4 h-4 animate-spin"}):g.jsx(xb,{className:"w-4 h-4"}),"Generar reporte Bono 14"]}),g.jsxs("p",{className:"text-[9px] text-neutral-400 text-center",children:["Se guardará como un reporte separado: GT · ",L," · Bono 14."]})]})]})}),g.jsx("section",{className:"flex flex-col items-center gap-3",children:g.jsx("button",{onClick:ko,disabled:se,className:"w-full sm:w-auto min-w-[280px] bg-[#4F758B] hover:bg-[#41677b] disabled:bg-neutral-300 disabled:cursor-not-allowed text-white px-8 py-4 font-black text-sm uppercase tracking-wider shadow-md flex items-center justify-center gap-3 transition-all duration-150 active:scale-[0.99] border-l-4 border-[#6CC24A]",children:se?g.jsxs(g.Fragment,{children:[g.jsx(Ha,{className:"w-5 h-5 animate-spin"}),g.jsx("span",{children:ye||"Procesando cruce de cuentas..."})]}):g.jsxs(g.Fragment,{children:[g.jsx(G2,{className:"w-5 h-5"}),g.jsx("span",{children:"Ejecutar Cruce de Cuentas"})]})})}),g.jsx(zi,{children:d&&p&&g.jsxs(Tn.section,{id:"resultados-seccion",initial:{opacity:0,y:20},animate:{opacity:1,y:0},exit:{opacity:0,y:10},className:"flex flex-col gap-5 scroll-mt-28",children:[g.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-4",children:[g.jsxs("div",{className:"bg-white border border-emerald-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-emerald-700",children:[g.jsx(Ec,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:"Coincidencias"})]}),g.jsx("p",{className:"text-3xl font-black text-emerald-800 mt-2",children:p.summary.matches})]}),g.jsxs("div",{className:"bg-white border border-red-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-[#ba1a1a]",children:[g.jsx(Ac,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:"Discrepancias"})]}),g.jsx("p",{className:"text-3xl font-black text-[#ba1a1a] mt-2",children:p.summary.discrepancies})]}),g.jsxs("div",{className:"bg-white border border-amber-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-amber-800",children:[g.jsx(vb,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:jt?"Banco sin Bono 14":"Banco sin nómina"})]}),g.jsx("p",{className:"text-3xl font-black text-amber-800 mt-2",children:p.summary.bankWithoutPayroll})]}),g.jsxs("div",{className:"bg-white border border-orange-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-orange-800",children:[g.jsx(vb,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:"Banco sin Bamboo"})]}),g.jsx("p",{className:"text-3xl font-black text-orange-800 mt-2",children:p.summary.bankWithoutBamboo})]}),g.jsxs("div",{className:"bg-white border border-violet-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-violet-800",children:[g.jsx(Xl,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:"Diferencias nombre banco"})]}),g.jsx("p",{className:"text-3xl font-black text-violet-800 mt-2",children:p.summary.nameDifferences})]}),g.jsxs("div",{className:"bg-white border border-blue-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-blue-800",children:[g.jsx(Ca,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:jt?"Bono 14 sin cuenta":"Nómina sin cuenta"})]}),g.jsx("p",{className:"text-3xl font-black text-blue-800 mt-2",children:p.summary.payrollWithoutAccount})]})]}),g.jsxs("div",{className:"bg-white border border-[#D0D0D0] shadow-sm overflow-hidden",children:[g.jsxs("div",{className:"p-5 border-b border-neutral-200 flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4",children:[g.jsxs("div",{children:[g.jsx("h2",{className:"text-lg font-black text-[#4F758B] uppercase tracking-tight",children:jt?"Resultados del Bono 14":"Resultados del Cruce"}),g.jsx("p",{className:"text-[11px] text-neutral-500 mt-1",children:qn})]}),g.jsx("div",{className:"flex flex-col sm:flex-row gap-2",children:g.jsxs("button",{onClick:In,disabled:!p.reportUrl,className:"inline-flex items-center justify-center gap-2 border border-[#4F758B] text-[#4F758B] hover:bg-[#4F758B] hover:text-white px-4 py-2 text-xs font-bold transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:[g.jsx(A2,{className:"w-4 h-4"}),"Abrir Google Sheet"]})})]}),g.jsxs("div",{className:"p-4 border-b border-neutral-200 bg-neutral-50 flex flex-col lg:flex-row gap-3 lg:items-center lg:justify-between",children:[g.jsxs("div",{className:"relative w-full lg:max-w-sm",children:[g.jsx(Xr,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400"}),g.jsx("input",{type:"text",value:ne,onChange:R=>{de(R.target.value),J(1)},placeholder:"Buscar empleado, Employee Number o cuenta...",className:"w-full pl-9 pr-3 py-2 border border-[#D0D0D0] text-xs font-medium focus:outline-none focus:border-[#4F758B]"})]}),g.jsx("div",{className:"flex flex-wrap gap-2",children:[["todos","Todos"],["discrepancias","Discrepancias"],["coincidencias","Coincidencias"],["banco_sin_nomina",jt?"Banco sin Bono 14":"Banco sin nómina"],["banco_sin_bamboo","Banco sin Bamboo"],["diferencia_nombre_banco","Diferencias nombre banco"],["nomina_sin_cuenta",jt?"Bono 14 sin cuenta":"Nómina sin cuenta"]].map(([R,X])=>g.jsx("button",{onClick:()=>{Be(R),J(1)},className:`px-3 py-1.5 text-[10px] uppercase tracking-wider font-black border transition-colors ${Ne===R?"bg-[#4F758B] text-white border-[#4F758B]":"bg-white text-neutral-500 border-neutral-300 hover:border-[#4F758B] hover:text-[#4F758B]"}`,children:X},R))})]}),g.jsx("div",{className:"overflow-x-hidden",children:g.jsxs("table",{className:"w-full table-fixed text-left border-collapse",children:[g.jsxs("colgroup",{children:[g.jsx("col",{style:{width:"10%"}}),g.jsx("col",{style:{width:"8%"}}),g.jsx("col",{style:{width:"10%"}}),g.jsx("col",{style:{width:"9%"}}),g.jsx("col",{style:{width:"9%"}}),g.jsx("col",{style:{width:"9%"}}),g.jsx("col",{style:{width:"8%"}}),g.jsx("col",{style:{width:"9%"}}),g.jsx("col",{style:{width:"17%"}}),g.jsx("col",{style:{width:"11%"}})]}),g.jsx("thead",{children:g.jsxs("tr",{className:"bg-[#4F758B] text-white text-xs font-bold uppercase tracking-wider",children:[g.jsx("th",{className:"py-3 px-2 xl:px-3",children:"Empleado"}),g.jsx("th",{className:"py-3 px-2 xl:px-3",children:"Employee Number"}),g.jsx("th",{className:"py-3 px-2 xl:px-3",children:"Cuenta"}),g.jsx("th",{className:"py-3 px-2 xl:px-3 text-right",children:jt?"Monto Bono 14":"Monto Nómina"}),g.jsx("th",{className:"py-3 px-2 xl:px-3 text-right",children:"Monto Banco"}),g.jsx("th",{className:"py-3 px-2 xl:px-3 text-right",children:"Diferencia"}),g.jsx("th",{className:"py-3 px-2 xl:px-3 text-center",children:"Estado"}),g.jsx("th",{className:"py-3 px-2 xl:px-3",children:"Categoría"}),g.jsx("th",{className:"py-3 px-2 xl:px-3",children:"Observación"}),g.jsx("th",{className:"py-3 px-2 xl:px-3 text-center",children:"Acciones"})]})}),g.jsx("tbody",{className:"divide-y divide-neutral-200 text-xs",children:cn.length>0?cn.map(R=>g.jsxs("tr",{className:"hover:bg-neutral-50 transition-colors",children:[g.jsx("td",{className:"py-3 px-2 xl:px-3 font-bold text-neutral-800 break-words",children:R.employee}),g.jsx("td",{className:"py-3 px-2 xl:px-3 font-mono text-neutral-600 break-all",children:R.employeeNumber||"—"}),g.jsx("td",{className:"py-3 px-2 xl:px-3 font-mono text-neutral-500 break-all",children:R.account??"—"}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-right font-mono text-neutral-700 whitespace-nowrap",children:Dd(R.amountPayroll,T,R.currency)}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-right font-mono text-neutral-700 whitespace-nowrap",children:Dd(R.amountBank,T,R.currency)}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-right font-mono text-neutral-700 whitespace-nowrap",children:Dd(R.difference,T,R.currency)}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-center",children:g.jsx("span",{className:`inline-block max-w-full px-2 py-1 text-[9px] font-black uppercase tracking-wider border leading-tight ${AC(R.status)}`,children:R.status})}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-neutral-600 capitalize break-words",children:RC(R.category??R.source,(p==null?void 0:p.reportKind)??"nomina")}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-neutral-600 break-words",children:R.observation}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-center",children:Ba(R,"banco_sin_bamboo")?ze.has(R.id)?g.jsx("span",{className:"inline-flex items-center px-2.5 py-1 border border-emerald-200 bg-emerald-50 text-emerald-800 text-[9px] font-black uppercase tracking-wider",children:"Reportado a RRHH"}):g.jsx("button",{type:"button",onClick:()=>Ce(R),className:"inline-flex max-w-full items-center justify-center px-2.5 py-2 border border-[#4F758B] text-[#4F758B] hover:bg-[#4F758B] hover:text-white text-[9px] font-black uppercase tracking-wider transition-colors whitespace-nowrap",children:"Reportar a RRHH"}):g.jsx("span",{className:"text-neutral-300",children:"—"})})]},R.id)):g.jsx("tr",{children:g.jsx("td",{colSpan:10,className:"py-12 text-center text-neutral-400 font-medium",children:"No hay resultados para el filtro seleccionado."})})})]})}),g.jsxs("div",{className:"p-4 border-t border-neutral-200 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 text-xs text-neutral-500",children:[g.jsxs("span",{children:["Mostrando ",cn.length," de ",ui.length," resultado(s)."]}),g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx("button",{onClick:()=>J(R=>Math.max(1,R-1)),disabled:q===1,className:"px-3 py-1.5 border border-neutral-300 bg-white disabled:opacity-40 disabled:cursor-not-allowed hover:border-[#4F758B] font-bold",children:"Anterior"}),g.jsxs("span",{className:"font-bold text-neutral-700",children:["Página ",q," de ",yt]}),g.jsx("button",{onClick:()=>J(R=>Math.min(yt,R+1)),disabled:q===yt,className:"px-3 py-1.5 border border-neutral-300 bg-white disabled:opacity-40 disabled:cursor-not-allowed hover:border-[#4F758B] font-bold",children:"Siguiente"})]})]})]})]})})]}),ee&&p&&g.jsx(Bw,{row:ee,country:T,periodRange:jt?gt:Ze,operatorName:x,operatorEmail:_,executionId:p.executionId,reportUrl:p.reportUrl,onClose:()=>Ce(null),onSuccess:R=>Re(X=>{const ae=new Set(X);return ae.add(R),ae}),onShowToast:n})]})}const ac=10;function zC(n){return n==="TT"?"":n==="PA"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-pa-historicos":n==="SV"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-sv-historicos":n==="HN"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-hn-historicos":n==="PR"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-pr-historicos":n==="RD"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-rd-historicos":"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-gt-historicos"}function PC(n){return n==="TT"?"":n==="PA"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-pa-marcar-resuelto":n==="SV"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-sv-marcar-resuelto":n==="HN"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-hn-marcar-resuelto":n==="PR"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-pr-marcar-resuelto":n==="RD"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-rd-marcar-resuelto":"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-gt-marcar-resuelto"}function rn(n){const e=Number(n);return Number.isFinite(e)?e:0}function VC(n,e){if(!n)return"";const i=new Date(String(n));return Number.isNaN(i.getTime())?String(n).slice(0,10):i.toLocaleDateString(e,{year:"numeric",month:"2-digit",day:"2-digit"})}function vf(n,e){if(!n)return"";const i=new Date(String(n));return Number.isNaN(i.getTime())?String(n):i.toLocaleString(e,{dateStyle:"short",timeStyle:"short"})}function HC(n){return String(n??"").toLowerCase().includes("resuelto")?"Resuelto":"Pendiente revisión"}function yv(n,e){const i=n,a=!Array.isArray(i)&&i?i:{};return(Array.isArray(i)?i:Array.isArray(a.reports)?a.reports:[]).map((c,u)=>{const d=c,m=rn(d.discrepancias??d.discrepancies),p=rn(d.bancoSinNomina??d.banco_sin_nomina??d.bankWithoutPayroll),y=rn(d.bancoSinBamboo??d.banco_sin_bamboo??d.bankWithoutBamboo),v=rn(d.nominaSinCuenta??d.nomina_sin_cuenta??d.payrollWithoutAccount),x=d.metadata&&typeof d.metadata=="object"&&!Array.isArray(d.metadata)?d.metadata:{},_=d.summary&&typeof d.summary=="object"&&!Array.isArray(d.summary)?d.summary:{},S=rn(d.diferenciasNombreBanco??d.diferencias_nombre_banco??d.nameDifferences??x.diferencias_nombre_banco??_.diferenciasNombreBanco);rn(d.posiblesCuentasMalDigitadas??d.posibles_cuentas_mal_digitadas??d.possibleWrongAccounts??x.posibles_cuentas_mal_digitadas??_.posiblesCuentasMalDigitadas);const T=m+p+y+v+S,j=String(d.country??d.pais??d.country_code??e.code).toUpperCase(),k=j==="RD"?rn(d.pendientes??d.total_pending??d.totalPending??x.pendientes_cruce_principal??_.pendientes):T,M=Array.isArray(d.archivosBanco)?d.archivosBanco.map(String):Array.isArray(d.bank_file_names)?d.bank_file_names.map(String):[],C=d.updated_at??d.fechaEjecucion??d.ejecutado_en??d.created_at;return{id:String(d.id??`reporte-${u+1}`),country:j==="TT"?"TT":j==="PA"?"PA":j==="SV"?"SV":j==="HN"?"HN":j==="PR"?"PR":j==="RD"?"RD":"GT",date:VC(d.fecha??d.period_end??C,e.locale),executionDate:vf(C,e.locale),period:String(d.periodo??d.period_label??d.period??"Período no especificado"),periodStart:d.period_start?String(d.period_start):void 0,periodEnd:d.period_end?String(d.period_end):void 0,payrollFile:String(d.archivoNomina??d.payroll_file_name??d.payrollFile??""),bankFiles:M,matches:rn(d.coincidencias??d.matches),discrepancies:m,bankWithoutPayroll:p,bankWithoutBamboo:y,payrollWithoutAccount:v,nameDifferences:S,totalPending:k,totalPayroll:rn(d.totalNomina??d.total_nomina),totalBank:rn(d.totalBanco??d.total_banco),totalDifference:rn(d.diferenciaTotal??d.diferencia_total),status:HC(d.estado??d.status??d.estadoLabel),reportUrl:d.reportUrl||d.report_url?String(d.reportUrl??d.report_url):void 0,spreadsheetId:d.spreadsheetId||d.spreadsheet_id?String(d.spreadsheetId??d.spreadsheet_id):void 0,executedBy:d.ejecutadoPorNombre||d.ejecutado_por_nombre?String(d.ejecutadoPorNombre??d.ejecutado_por_nombre):void 0,executedByEmail:d.ejecutadoPorEmail||d.ejecutado_por_email?String(d.ejecutadoPorEmail??d.ejecutado_por_email):void 0,resolvedBy:d.resueltoPorNombre||d.resuelto_por_nombre?String(d.resueltoPorNombre??d.resuelto_por_nombre):void 0,resolvedByEmail:d.resueltoPorEmail||d.resuelto_por_email?String(d.resueltoPorEmail??d.resuelto_por_email):void 0,resolvedAt:vf(d.resueltoEn??d.resuelto_en,e.locale),resolutionComment:d.comentarioResolucion||d.comentario_resolucion?String(d.comentarioResolucion??d.comentario_resolucion):void 0,_sortTime:new Date(String(C??d.period_end??"")).getTime()||0}}).filter(c=>c.country===e.code).sort((c,u)=>u._sortTime-c._sortTime).map(({_sortTime:c,...u})=>u)}function xf(n){return String(n??"").toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^a-z0-9 ]/g," ").replace(/\s+/g," ").trim()}function wf(n){return String(n??"").replace(/\.0$/g,"").replace(/\D/g,"").trim()}function bv(n,e){for(const i of e){const a=n[i];if(typeof a=="number"&&Number.isFinite(a))return a;if(typeof a=="string"&&a.trim()){const l=Number(a.replace(/[A-Za-z$Q,\s]/g,"").trim());if(Number.isFinite(l))return l}}return null}function $C(n){return Array.isArray(n)?n.map((e,i)=>{const a=e??{},l=String(a.employee??a.employee_name??a.bank_name_file??a.bank_account_holder??"Sin nombre"),c=bv(a,["bankAmount","bank_amount","amount","monto_banco"]),u=a.best_bamboo_candidate&&typeof a.best_bamboo_candidate=="object"?a.best_bamboo_candidate:null;return{id:String(a.id??`historical-bamboo-${xf(l)}-${wf(a.account??a.bank_account)}-${i+1}`),employee:l,employeeNumber:"",account:String(a.account??a.bank_account??a.bankAccount??""),amountPayroll:0,amountBank:c,difference:c===null?null:0-c,status:"Pendiente revisión",category:"banco_sin_bamboo",source:"banco_sin_bamboo",observation:String(a.observation??a.observacion??"Pago bancario sin empleado identificado de forma confiable en BambooHR."),bankNameFile:String(a.bank_name_file??a.bankNameFile??""),bankAccountHolder:String(a.bank_account_holder??a.bankAccountHolder??""),bestBambooCandidate:u?{employeeNumber:String(u.employee_number??u.employeeNumber??""),employeeName:String(u.employee_name??u.employeeName??""),score:bv(u,["score"])}:null,ambiguousBambooMatch:!!a.ambiguous_bamboo_match}}):[]}function qC(n){return Array.isArray(n)?n.map(e=>{const i=e??{};return{id:String(i.id??""),sourceName:String(i.nombre_origen_principal??i.source_name??""),sourceNames:Array.isArray(i.nombres_origen)?i.nombres_origen.map(String):[],bankAccount:String(i.cuenta_bancaria??i.bank_account??""),status:String(i.estado??""),emailSent:i.correo_enviado===!0}}):[]}function FC(n,e){const i=n.status.toLowerCase();if(!(n.emailSent||i==="notificado_rrhh"||i==="corregido_bamboo"))return!1;const l=wf(n.bankAccount),c=wf(e.account);if(l&&c&&l!==c)return!1;const u=new Set([n.sourceName,...n.sourceNames].map(xf).filter(Boolean));return[e.employee,e.bankNameFile,e.bankAccountHolder].map(xf).filter(Boolean).some(m=>u.has(m))}function IC(n){return n==="Resuelto"?"bg-blue-50 text-blue-800 border-blue-200":"bg-amber-50 text-amber-800 border-amber-200"}function GC(n){return n==="Resuelto"?"RESUELTO":"PENDIENTE REVISIÓN"}function KC({onShowToast:n,onOpenSidebar:e,operatorName:i,operatorEmail:a,country:l}){const[c,u]=D.useState(""),[d,m]=D.useState("todos"),[p,y]=D.useState([]),[v,x]=D.useState(1),[_,S]=D.useState(!1),[T,j]=D.useState(!1),[k,M]=D.useState(""),[C,P]=D.useState(null),[K,G]=D.useState(""),[H,Y]=D.useState(null),[Z,se]=D.useState([]),[me,ye]=D.useState(new Set),[Ae,Ne]=D.useState(!1),[Be,L]=D.useState(""),[W,Q]=D.useState(null),[le,ue]=D.useState(0),[A,q]=D.useState(0),J=D.useRef(0),ne=D.useRef(null),de=Math.max(1,Math.ceil(A/ac)),ge=p;D.useEffect(()=>{x(1)},[c,d,l.code]),D.useEffect(()=>{v>de&&x(de)},[v,de]);const we=async()=>{var Re;const ee=++J.current;(Re=ne.current)==null||Re.abort();const Ce=new AbortController;ne.current=Ce;const ze=()=>J.current===ee&&!Ce.signal.aborted;S(!0),M("");try{if(es){const gt=d==="pendiente"?"pendiente_revision":d==="resuelto"?"resuelto":null,{data:jt,error:qn}=await es.rpc("cruce_cuentas_get_historicos",{p_country:l.code,p_page:v,p_page_size:ac,p_search:c.trim()||null,p_status:gt});if(!ze())return;if(!qn&&jt){const Rn=Array.isArray(jt)?jt[0]:jt,Cs=yv(Rn,l),$i=rn(Rn==null?void 0:Rn.total),ui=rn((Rn==null?void 0:Rn.filtered_total)??$i);y(Cs),ue($i),q(ui);return}}if(!ze())return;const rt=zC(l.code);if(!rt)throw new Error(`No está configurado el origen histórico de ${l.name}.`);const st=new URL(rt);st.searchParams.set("country",l.code);const ht=await fetch(st.toString(),{method:"GET",signal:Ce.signal}),it=await ht.json().catch(()=>null);if(!ze())return;if(!ht.ok||(it==null?void 0:it.ok)===!1)throw new Error("No se pudieron cargar los reportes históricos.");const Qt=yv(it,l),$n=c.trim().toLowerCase(),Ze=Qt.filter(gt=>{const jt=d==="todos"||d==="pendiente"&>.status==="Pendiente revisión"||d==="resuelto"&>.status==="Resuelto",qn=!$n||gt.period.toLowerCase().includes($n)||gt.payrollFile.toLowerCase().includes($n)||gt.id.toLowerCase().includes($n)||(gt.resolvedBy??"").toLowerCase().includes($n)||(gt.executedBy??"").toLowerCase().includes($n);return jt&&qn});if(!ze())return;const ci=(v-1)*ac;y(Ze.slice(ci,ci+ac)),ue(Qt.length),q(Ze.length)}catch(rt){if(!ze()||rt instanceof DOMException&&rt.name==="AbortError")return;y([]),ue(0),q(0),M(rt instanceof Error?rt.message:"No se pudieron cargar los reportes históricos. Intenta nuevamente."),n("No se pudieron cargar los reportes históricos.","error")}finally{ze()&&(S(!1),ne.current===Ce&&(ne.current=null))}};D.useEffect(()=>{const ee=window.setTimeout(()=>{we()},c.trim()?300:0);return()=>{var Ce;window.clearTimeout(ee),J.current+=1,(Ce=ne.current)==null||Ce.abort(),ne.current=null}},[l.code,v,c,d]);const ke=()=>{Q(null),Y(null),se([]),ye(new Set),L("")},qe=async ee=>{if(ee.bankWithoutBamboo<=0){n("Este reporte no tiene casos de Banco sin Bamboo.","info");return}if(!es){n("Supabase no está configurado en esta aplicación.","error");return}Y(ee),Q(null),se([]),ye(new Set),L(""),Ne(!0);try{const{data:Ce,error:ze}=await es.rpc("cruce_cuentas_get_banco_sin_bamboo_reporte",{p_report_id:ee.id,p_country:l.code});if(ze)throw ze;const Re=Array.isArray(Ce)?Ce[0]:Ce;if(!Re||Re.ok===!1)throw new Error(String((Re==null?void 0:Re.message)||"No se pudieron recuperar los casos de Banco sin Bamboo."));const rt=$C(Re.cases),st=qC(Re.corrections),ht=new Set(rt.filter(it=>st.some(Qt=>FC(Qt,it))).map(it=>it.id));se(rt),ye(ht),rt.length===0&&L("Este reporte fue creado antes de que se guardara el detalle de Banco sin Bamboo. Los reportes nuevos conservarán los casos para revisarlos desde Históricos.")}catch(Ce){const ze=Ce instanceof Error?Ce.message:"No se pudieron recuperar los casos de Banco sin Bamboo.";L(ze),n(ze,"error")}finally{Ne(!1)}},at={label:(H==null?void 0:H.period)||"Período no especificado",start:(H==null?void 0:H.periodStart)||"",end:(H==null?void 0:H.periodEnd)||""},jn=ee=>{if(ee.reportUrl){window.open(ee.reportUrl,"_blank","noopener,noreferrer");return}n("Este reporte aún no tiene un Google Sheet disponible.","info")},Nn=ee=>{if(ee.status==="Resuelto"){n("Este reporte ya fue marcado como resuelto.","info");return}P(ee),G("")},as=async()=>{if(!C)return;const ee=K.trim();if(ee.length<10){n("Debes escribir un comentario de resolución más descriptivo.","error");return}const Ce=PC(l.code);if(!Ce){n(`La resolución de reportes para ${l.name} estará disponible próximamente.`,"info");return}j(!0);try{const ze=await fetch(Ce,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({reportId:C.id,comentarioResolucion:ee,resueltoPorNombre:i,resueltoPorEmail:a,country:l.code,countryName:l.name})}),Re=await ze.json().catch(()=>null);if(!ze.ok||(Re==null?void 0:Re.ok)===!1){const ht=Array.isArray(Re==null?void 0:Re.errors)?Re.errors.join(` +`):(Re==null?void 0:Re.message)||"No se pudo marcar el reporte como resuelto.";throw new Error(ht)}const rt=Re.report??{},st=vf(rt.resueltoEn??new Date().toISOString(),l.locale);y(ht=>ht.map(it=>it.id===C.id?{...it,status:"Resuelto",resolvedBy:String(rt.resueltoPorNombre??i),resolvedByEmail:String(rt.resueltoPorEmail??a),resolvedAt:st,resolutionComment:String(rt.comentarioResolucion??ee)}:it)),P(null),G(""),n("Reporte marcado como resuelto correctamente.","success")}catch(ze){const Re=ze instanceof Error?ze.message:"No se pudo marcar el reporte como resuelto.";n(Re,"error")}finally{j(!1)}};return g.jsxs("div",{className:"flex-1 flex flex-col min-h-screen bg-neutral-50 text-neutral-800 font-sans",children:[g.jsxs("header",{className:"bg-white border-b-4 border-[#6CC24A] flex justify-between items-center w-full px-4 sm:px-8 h-[84px] sticky top-0 z-40 shadow-sm gap-x-4",children:[g.jsxs("div",{className:"flex items-center gap-2 sm:gap-3 min-w-0",children:[g.jsx("button",{onClick:e,className:"md:hidden p-2 -ml-2 text-neutral-600 hover:text-neutral-800 hover:bg-neutral-100 transition-colors flex-shrink-0","aria-label":"Abrir menú",children:g.jsx(uw,{className:"w-6 h-6"})}),g.jsx("h1",{className:"text-xs sm:text-sm md:text-lg lg:text-2xl font-black text-[#4F758B] tracking-tight uppercase flex items-center gap-1.5 sm:gap-2 min-w-0",children:g.jsxs("span",{className:"truncate",children:["Reportes Históricos - ",l.name]})})]}),g.jsxs("div",{className:"flex items-center gap-2 sm:gap-3 flex-shrink-0",children:[g.jsx(Uw,{country:l,operatorName:i,operatorEmail:a,section:"Reportes Históricos",onShowToast:n}),g.jsx("div",{className:"hidden sm:flex items-center border border-neutral-200 bg-white px-2.5 py-2 shadow-sm","aria-label":`Bandera de ${l.name}`,children:g.jsx("img",{src:l.flag,alt:`Bandera de ${l.name}`,className:"h-5 sm:h-6 w-auto object-contain"})}),g.jsxs("button",{onClick:we,disabled:_,className:"hidden sm:inline-flex items-center gap-2 border border-[#4F758B]/20 text-[#4F758B] px-3 py-2 text-xs font-bold hover:border-[#4F758B]/50 disabled:opacity-50",children:[g.jsx(J2,{className:`w-4 h-4 ${_?"animate-spin":""}`}),"Actualizar"]})]})]}),g.jsxs("main",{className:"flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 py-8 flex flex-col gap-6",children:[g.jsxs("div",{className:"bg-white border border-[#D0D0D0] p-4 flex flex-col lg:flex-row items-center justify-between gap-4 shadow-sm",children:[g.jsxs("div",{className:"relative w-full lg:max-w-md",children:[g.jsx(Xr,{className:"absolute left-3.5 top-1/2 transform -translate-y-1/2 text-neutral-400 w-4 h-4"}),g.jsx("input",{type:"text",placeholder:"Buscar por período, reporte, archivo o resolutor...",value:c,onChange:ee=>u(ee.target.value),className:"w-full pl-10 pr-4 py-2 border border-[#D0D0D0] text-xs font-medium placeholder-neutral-400 focus:outline-none focus:border-[#4F758B] transition-colors"})]}),g.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center gap-3 w-full lg:w-auto",children:[g.jsx("div",{className:"flex flex-wrap gap-2",children:[["todos","Todos"],["pendiente","Pendiente revisión"],["resuelto","Resuelto"]].map(([ee,Ce])=>g.jsx("button",{onClick:()=>m(ee),className:`px-3 py-1.5 text-[10px] uppercase tracking-wider font-black border transition-colors ${d===ee?"bg-[#4F758B] text-white border-[#4F758B]":"bg-white text-neutral-500 border-neutral-300 hover:border-[#4F758B] hover:text-[#4F758B]"}`,children:Ce},ee))}),g.jsxs("div",{className:"flex items-center gap-2 text-xs font-bold text-neutral-500",children:[g.jsx(O2,{className:"w-4 h-4 text-neutral-400"}),g.jsxs("span",{children:["Mostrando: ",A," de ",le," reportes"]})]})]})]}),k&&g.jsxs("div",{className:"border border-red-200 bg-red-50 text-[#ba1a1a] px-4 py-3 text-xs font-bold flex items-center gap-2",children:[g.jsx(Ac,{className:"w-4 h-4"}),k]}),g.jsxs("div",{className:"bg-white border border-[#D0D0D0] shadow-sm overflow-hidden",children:[g.jsx("div",{className:"overflow-x-auto lg:overflow-x-hidden",children:g.jsxs("table",{className:"w-full text-left border-collapse min-w-[960px] lg:min-w-0 lg:table-fixed",children:[g.jsxs("colgroup",{children:[g.jsx("col",{className:"lg:w-[9%]"}),g.jsx("col",{className:"lg:w-[8%]"}),g.jsx("col",{className:"lg:w-[21%]"}),g.jsx("col",{className:"lg:w-[9%]"}),g.jsx("col",{className:"lg:w-[9%]"}),g.jsx("col",{className:"lg:w-[9%]"}),g.jsx("col",{className:"lg:w-[9%]"}),g.jsx("col",{className:"lg:w-[10%]"}),g.jsx("col",{className:"lg:w-[16%]"})]}),g.jsx("thead",{children:g.jsxs("tr",{className:"bg-[#4F758B] text-white text-xs font-bold uppercase tracking-wider",children:[g.jsx("th",{className:"py-3 px-2 xl:px-3",children:"Fecha"}),g.jsx("th",{className:"py-3 px-2 xl:px-3",children:"Período"}),g.jsx("th",{className:"py-3 px-2 xl:px-3",children:"Archivo de Nómina / Bono 14"}),g.jsx("th",{className:"py-3 px-2 xl:px-3 text-center",children:"Coincidencias"}),g.jsx("th",{className:"py-3 px-2 xl:px-3 text-center",children:"Banco sin Bamboo"}),g.jsx("th",{className:"py-3 px-2 xl:px-3 text-center",children:"Pendientes"}),g.jsx("th",{className:"py-3 px-2 xl:px-3 text-center",children:"Estado"}),g.jsx("th",{className:"py-3 px-2 xl:px-3",children:"Resuelto por"}),g.jsx("th",{className:"py-3 px-2 xl:px-3 text-center",children:"Acciones"})]})}),g.jsx("tbody",{className:"divide-y divide-neutral-200 text-xs",children:_?g.jsx("tr",{children:g.jsx("td",{colSpan:9,className:"py-12 text-center text-neutral-400 font-medium",children:g.jsxs("div",{className:"inline-flex items-center gap-2",children:[g.jsx(Ha,{className:"w-4 h-4 animate-spin"}),"Cargando reportes históricos..."]})})}):ge.length>0?ge.map(ee=>g.jsxs(Tn.tr,{initial:{opacity:0},animate:{opacity:1},className:"hover:bg-neutral-50/70 transition-colors",children:[g.jsx("td",{className:"py-3 px-2 xl:px-3 font-medium text-neutral-700",children:g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx(g2,{className:"w-4 h-4 text-neutral-400"}),g.jsxs("div",{children:[g.jsx("span",{children:ee.date}),ee.executionDate&&g.jsx("p",{className:"text-[9px] text-neutral-400 mt-0.5",children:ee.executionDate})]})]})}),g.jsx("td",{className:"py-3 px-2 xl:px-3 font-bold text-[#4F758B]",children:ee.period}),g.jsx("td",{className:"py-3 px-2 xl:px-3 font-mono text-neutral-500 min-w-0",title:ee.payrollFile,children:g.jsxs("div",{className:"flex items-center gap-1.5",children:[g.jsx(Ca,{className:"w-4 h-4 text-neutral-400 flex-shrink-0"}),g.jsx("span",{className:"truncate min-w-0",children:ee.payrollFile||"No especificado"})]})}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-center font-black text-emerald-800",children:ee.matches}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-center",children:ee.bankWithoutBamboo>0?g.jsxs("button",{type:"button",onClick:()=>void qe(ee),className:"inline-flex items-center gap-1.5 min-w-8 px-2.5 py-1 text-[10px] font-black border bg-orange-50 text-orange-800 border-orange-200 hover:bg-orange-100 hover:border-orange-300 transition-colors",title:"Revisar casos y reportar correcciones a RRHH",children:[g.jsx("span",{children:ee.bankWithoutBamboo}),g.jsx("span",{className:"hidden 2xl:inline",children:"Revisar"})]}):g.jsx("span",{className:"inline-block min-w-8 px-2.5 py-1 text-[10px] font-black border bg-neutral-50 text-neutral-400 border-neutral-200",children:"0"})}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-center",children:g.jsx("span",{className:`inline-block px-2.5 py-1 text-[10px] font-bold border ${ee.totalPending>0?"bg-red-50 text-[#ba1a1a] border-red-200":"bg-emerald-50 text-emerald-800 border-emerald-200"}`,children:ee.totalPending===0?"Sin pendientes":`${ee.totalPending} pendiente${ee.totalPending>1?"s":""}`})}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-center",children:g.jsx("span",{className:`inline-block px-2.5 py-1 text-[9px] uppercase font-black tracking-wider border ${IC(ee.status)}`,children:GC(ee.status)})}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-neutral-600 max-w-[220px]",children:ee.resolvedBy?g.jsxs("div",{title:ee.resolutionComment||"",children:[g.jsx("p",{className:"font-bold text-neutral-700 truncate",children:ee.resolvedBy}),g.jsx("p",{className:"text-[10px] text-neutral-400",children:ee.resolvedAt})]}):g.jsx("span",{className:"text-neutral-400",children:"Pendiente"})}),g.jsx("td",{className:"py-3 px-2 xl:px-3 text-center",children:g.jsxs("div",{className:"flex justify-center items-stretch gap-1.5 min-w-0",children:[g.jsxs("button",{onClick:()=>jn(ee),className:"inline-flex items-center gap-1.5 text-[#4F758B] hover:text-[#3d6378] font-bold text-xs border border-[#4F758B]/20 hover:border-[#4F758B]/50 px-2.5 py-1.5 bg-white hover:bg-neutral-50 transition-colors",children:[g.jsx(N2,{className:"w-3.5 h-3.5"}),g.jsx("span",{children:"Ver"})]}),g.jsxs("button",{onClick:()=>Nn(ee),disabled:ee.status==="Resuelto",className:"inline-flex items-center gap-1.5 text-emerald-700 hover:text-emerald-800 font-bold text-xs border border-emerald-200 hover:border-emerald-400 px-2.5 py-1.5 bg-emerald-50 hover:bg-emerald-100 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:[g.jsx(Ec,{className:"w-3.5 h-3.5"}),g.jsx("span",{className:"leading-tight",children:ee.status==="Resuelto"?"Resuelto":"Marcar resuelto"})]})]})})]},ee.id)):g.jsx("tr",{children:g.jsx("td",{colSpan:9,className:"py-12 text-center text-neutral-400 font-medium",children:"No se encontraron reportes históricos."})})})]})}),g.jsxs("div",{className:"p-4 border-t border-neutral-200 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 text-xs text-neutral-500",children:[g.jsxs("span",{children:["Mostrando ",ge.length," de ",A," reporte(s)."]}),g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx("button",{onClick:()=>x(ee=>Math.max(1,ee-1)),disabled:v===1,className:"px-3 py-1.5 border border-neutral-300 bg-white disabled:opacity-40 disabled:cursor-not-allowed hover:border-[#4F758B] font-bold",children:"Anterior"}),g.jsxs("span",{className:"font-bold text-neutral-700",children:["Página ",v," de ",de]}),g.jsx("button",{onClick:()=>x(ee=>Math.min(de,ee+1)),disabled:v===de,className:"px-3 py-1.5 border border-neutral-300 bg-white disabled:opacity-40 disabled:cursor-not-allowed hover:border-[#4F758B] font-bold",children:"Siguiente"})]})]})]})]}),g.jsx(zi,{children:H&&g.jsx(Tn.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:"fixed inset-0 z-[80] flex items-center justify-center bg-black/45 px-4 py-6",children:g.jsxs(Tn.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},exit:{opacity:0,y:12},className:"w-full max-w-5xl bg-white border border-[#D0D0D0] shadow-2xl max-h-[92vh] flex flex-col",children:[g.jsx("div",{className:"h-1.5 bg-[#6CC24A] flex-shrink-0"}),g.jsxs("div",{className:"border-b border-neutral-200 px-5 sm:px-6 py-4 flex items-start justify-between gap-4 flex-shrink-0",children:[g.jsxs("div",{children:[g.jsx("p",{className:"text-[10px] uppercase tracking-[0.18em] font-black text-[#6B8FA3]",children:"Histórico · Banco sin BambooHR"}),g.jsx("h2",{className:"text-lg sm:text-xl font-black text-[#4F758B] mt-1",children:H.period}),g.jsxs("p",{className:"text-xs text-neutral-500 mt-1",children:[l.name," · ",H.bankWithoutBamboo," caso",H.bankWithoutBamboo===1?"":"s"," guardado",H.bankWithoutBamboo===1?"":"s"," en este reporte"]})]}),g.jsx("button",{type:"button",onClick:ke,className:"p-2 text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100","aria-label":"Cerrar revisión de Banco sin Bamboo",children:g.jsx(Ga,{className:"w-5 h-5"})})]}),g.jsxs("div",{className:"px-5 sm:px-6 py-4 overflow-y-auto",children:[g.jsxs("div",{className:"border border-[#D6E8F4] bg-[#F7FBFD] px-4 py-3 text-xs text-neutral-600 leading-relaxed mb-4",children:["Aquí puedes volver días después al reporte y enviar a RRHH únicamente los falsos positivos que ya verificaste manualmente. Los casos previamente enviados se muestran como ",g.jsx("strong",{children:"Reportado a RRHH"}),"."]}),Ae?g.jsxs("div",{className:"py-14 text-center text-neutral-500 text-sm",children:[g.jsx(Ha,{className:"w-5 h-5 animate-spin mx-auto mb-2 text-[#4F758B]"}),"Recuperando casos del reporte..."]}):Be?g.jsxs("div",{className:"border border-amber-200 bg-amber-50 text-amber-800 px-4 py-3 text-xs font-medium flex items-start gap-2",children:[g.jsx(Ac,{className:"w-4 h-4 mt-0.5 flex-shrink-0"}),g.jsx("span",{children:Be})]}):Z.length>0?g.jsx("div",{className:"overflow-x-auto border border-neutral-200",children:g.jsxs("table",{className:"w-full text-left border-collapse min-w-[760px]",children:[g.jsx("thead",{children:g.jsxs("tr",{className:"bg-[#4F758B] text-white text-[10px] font-black uppercase tracking-wider",children:[g.jsx("th",{className:"px-3 py-3",children:"Nombre detectado"}),g.jsx("th",{className:"px-3 py-3",children:"Cuenta"}),g.jsx("th",{className:"px-3 py-3 text-right",children:"Monto banco"}),g.jsx("th",{className:"px-3 py-3",children:"Candidato BambooHR"}),g.jsx("th",{className:"px-3 py-3 text-center",children:"Acción"})]})}),g.jsx("tbody",{className:"divide-y divide-neutral-200 text-xs",children:Z.map(ee=>{var Re;const Ce=me.has(ee.id),ze=ee.amountBank;return g.jsxs("tr",{className:"hover:bg-neutral-50",children:[g.jsxs("td",{className:"px-3 py-3",children:[g.jsx("p",{className:"font-black text-neutral-800",children:ee.employee}),(ee.bankNameFile||ee.bankAccountHolder)&&g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1",children:[ee.bankNameFile,ee.bankAccountHolder].filter(Boolean).join(" · ")})]}),g.jsx("td",{className:"px-3 py-3 font-mono font-bold text-neutral-600",children:ee.account||"—"}),g.jsx("td",{className:"px-3 py-3 text-right font-black text-neutral-700",children:ze===null?"—":new Intl.NumberFormat(l.locale,{style:"currency",currency:l.currency,maximumFractionDigits:2}).format(ze)}),g.jsx("td",{className:"px-3 py-3 text-neutral-600 max-w-[260px]",children:(Re=ee.bestBambooCandidate)!=null&&Re.employeeName?g.jsxs("div",{children:[g.jsx("p",{className:"font-bold text-[#4F758B]",children:ee.bestBambooCandidate.employeeName}),ee.bestBambooCandidate.employeeNumber&&g.jsxs("p",{className:"text-[10px] text-neutral-400 mt-0.5",children:["Employee Number ",ee.bestBambooCandidate.employeeNumber]})]}):g.jsx("span",{className:"text-neutral-400",children:"Sin candidato confiable"})}),g.jsx("td",{className:"px-3 py-3 text-center",children:Ce?g.jsxs("span",{className:"inline-flex items-center gap-1.5 px-3 py-1.5 border border-emerald-200 bg-emerald-50 text-emerald-800 text-[10px] font-black uppercase tracking-wider",children:[g.jsx(Ec,{className:"w-3.5 h-3.5"}),"Reportado a RRHH"]}):g.jsx("button",{type:"button",onClick:()=>Q(ee),className:"inline-flex items-center gap-1.5 px-3 py-1.5 bg-[#6CC24A] hover:bg-[#5aaa3f] text-white text-[10px] font-black uppercase tracking-wider transition-colors",children:"Reportar a RRHH"})})]},ee.id)})})]})}):g.jsx("div",{className:"py-12 text-center text-neutral-400 text-sm",children:"No hay casos guardados en este reporte."})]}),g.jsxs("div",{className:"border-t border-neutral-200 px-5 sm:px-6 py-4 flex items-center justify-between gap-3 flex-shrink-0",children:[g.jsxs("span",{className:"text-[10px] text-neutral-400",children:["ID del reporte: ",H.id]}),g.jsx("button",{type:"button",onClick:ke,className:"border border-neutral-300 bg-white px-4 py-2 text-xs font-bold text-neutral-600 hover:bg-neutral-50",children:"Cerrar"})]})]})})}),W&&H&&g.jsx(Bw,{row:W,country:l,periodRange:at,operatorName:i,operatorEmail:a,executionId:H.id,reportUrl:H.reportUrl,onClose:()=>Q(null),onSuccess:ee=>{ye(Ce=>{const ze=new Set(Ce);return ze.add(ee),ze})},onShowToast:n}),g.jsx(zi,{children:C&&g.jsx(Tn.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:"fixed inset-0 z-[80] flex items-center justify-center bg-black/45 px-4",children:g.jsxs(Tn.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},exit:{opacity:0,y:12},className:"w-full max-w-lg bg-white border border-[#D0D0D0] shadow-xl",children:[g.jsxs("div",{className:"border-b border-neutral-200 px-5 py-4 flex items-center justify-between",children:[g.jsxs("div",{children:[g.jsx("h2",{className:"text-base font-black text-[#4F758B] uppercase tracking-tight",children:"Marcar reporte como resuelto"}),g.jsx("p",{className:"text-xs text-neutral-500 mt-1",children:C.period})]}),g.jsx("button",{onClick:()=>P(null),disabled:T,className:"p-2 text-neutral-400 hover:text-neutral-700 disabled:opacity-50","aria-label":"Cerrar",children:g.jsx(Ga,{className:"w-4 h-4"})})]}),g.jsxs("div",{className:"p-5 space-y-4",children:[g.jsx("div",{className:"bg-amber-50 border border-amber-200 text-amber-800 p-3 text-xs leading-relaxed",children:"Antes de resolver, confirma que las diferencias fueron revisadas y explica cómo se cerró el caso."}),g.jsxs("label",{className:"block",children:[g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black text-neutral-500",children:"Comentario de resolución"}),g.jsx("textarea",{value:K,onChange:ee=>G(ee.target.value),placeholder:"Ejemplo: Se corrigió la cuenta bancaria en nómina y se validó contra el banco.",className:"mt-2 w-full min-h-[130px] border border-[#D0D0D0] px-3 py-2 text-sm focus:outline-none focus:border-[#4F758B]"})]})]}),g.jsxs("div",{className:"border-t border-neutral-200 px-5 py-4 flex justify-end gap-3",children:[g.jsx("button",{onClick:()=>P(null),disabled:T,className:"border border-neutral-300 bg-white px-4 py-2 text-xs font-bold text-neutral-600 hover:bg-neutral-50 disabled:opacity-50",children:"Cancelar"}),g.jsxs("button",{onClick:as,disabled:T,className:"bg-[#4F758B] hover:bg-[#41677b] text-white px-4 py-2 text-xs font-black uppercase tracking-wider disabled:opacity-50 inline-flex items-center gap-2",children:[T&&g.jsx(Ha,{className:"w-4 h-4 animate-spin"}),"Confirmar resolución"]})]})]})})})]})}function vv({message:n,type:e,onClose:i}){D.useEffect(()=>{const c=setTimeout(()=>{i()},2e3);return()=>clearTimeout(c)},[i]);const a={success:"bg-[#6CC24A] text-white border-l-4 border-emerald-700",error:"bg-[#ba1a1a] text-white border-l-4 border-red-800",info:"bg-[#4F758B] text-white border-l-4 border-slate-700"},l={success:Ec,error:x2,info:cw}[e];return g.jsx("div",{className:"fixed bottom-6 right-6 z-50 max-w-sm w-full",children:g.jsxs(Tn.div,{initial:{opacity:0,y:30,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:20,scale:.95},className:`flex items-center gap-3 p-4 shadow-lg rounded-md border border-neutral-200/10 ${a[e]}`,children:[g.jsx("span",{className:"flex-shrink-0",children:g.jsx(l,{className:"w-5 h-5"})}),g.jsx("div",{className:"flex-1 font-medium text-sm leading-tight pr-2",children:n}),g.jsx("button",{onClick:i,className:"flex-shrink-0 hover:bg-white/20 p-1 rounded transition-colors text-white",children:g.jsx(Ga,{className:"w-4 h-4"})})]})})}const YC="https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png";function XC({onSelect:n}){return g.jsxs("div",{className:"min-h-screen bg-[#F5F5F5] flex flex-col font-sans",children:[g.jsx("div",{className:"h-1.5 bg-[#6CC24A]"}),g.jsx("main",{className:"flex-1 flex items-center justify-center px-4 py-10",children:g.jsxs(Tn.section,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},className:"w-full max-w-3xl bg-white border border-[#D0D0D0] shadow-xl p-6 sm:p-9",children:[g.jsx("img",{src:YC,alt:"GomezLee Marketing",className:"h-14 object-contain mb-7"}),g.jsxs("div",{className:"flex items-start gap-3 mb-7",children:[g.jsx("div",{className:"bg-[#4F758B]/10 p-2.5 rounded-full",children:g.jsx(lw,{className:"w-5 h-5 text-[#4F758B]"})}),g.jsxs("div",{children:[g.jsx("h1",{className:"text-xl sm:text-2xl font-black text-[#4F758B] uppercase tracking-tight",children:"Selecciona el país"}),g.jsx("p",{className:"text-sm text-neutral-500 mt-1",children:"El portal cargará las reglas, la moneda y los reportes correspondientes."})]})]}),g.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",children:uo.map(e=>g.jsxs("button",{type:"button",disabled:!e.enabled,onClick:()=>e.enabled&&n(e.code),className:`text-left border p-5 transition-all min-h-[150px] flex flex-col justify-between ${e.enabled?"border-[#4F758B]/30 hover:border-[#4F758B] hover:shadow-md bg-white":"border-neutral-200 bg-neutral-50 cursor-not-allowed opacity-70"}`,children:[g.jsxs("div",{className:"flex items-start justify-between gap-3",children:[g.jsx("img",{src:e.flag,alt:"",className:"w-12 h-8 sm:w-16 sm:h-10 object-cover shadow-sm border border-neutral-200","aria-hidden":"true"}),e.enabled?g.jsx(h2,{className:"w-5 h-5 text-[#6CC24A]"}):g.jsx(P2,{className:"w-4 h-4 text-neutral-400"})]}),g.jsxs("div",{children:[g.jsx("p",{className:"font-black text-[#4F758B] uppercase tracking-wide",children:e.name}),g.jsx("p",{className:"text-xs text-neutral-500 mt-1",children:e.enabled?`Moneda ${e.currency}`:"Próximamente"})]})]},e.code))})]})})]})}const JC="glm_cruce_cuentas_tab_state",QC=1,ss="drafts",xv="glm_cruce_cuentas_tab_session_id",Pw=1,ZC=10080*60*1e3;let Ra=null,qa=Promise.resolve(),wv=null;function _v(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}-${Math.random().toString(36).slice(2)}`}function tm(){try{const n=window.sessionStorage.getItem(xv);if(n)return n;const e=_v();return window.sessionStorage.setItem(xv,e),e}catch{return wv??(wv=_v()),wv}}function nm(){return Ra||(Ra=new Promise((n,e)=>{if(typeof indexedDB>"u"){e(new Error("IndexedDB no está disponible en este navegador."));return}const i=indexedDB.open(JC,QC);i.onupgradeneeded=()=>{const a=i.result;a.objectStoreNames.contains(ss)||a.createObjectStore(ss,{keyPath:"sessionId"})},i.onsuccess=()=>n(i.result),i.onerror=()=>e(i.error??new Error("No se pudo abrir IndexedDB.")),i.onblocked=()=>e(new Error("La base local está bloqueada por otra pestaña."))}),Ra.catch(()=>{Ra=null}),Ra)}function WC(n){return new Promise((e,i)=>{n.onsuccess=()=>e(n.result),n.onerror=()=>i(n.error??new Error("Falló una operación local."))})}function Ic(n){return new Promise((e,i)=>{n.oncomplete=()=>e(),n.onerror=()=>i(n.error??new Error("Falló la transacción local.")),n.onabort=()=>i(n.error??new Error("La transacción local fue cancelada."))})}function eO(n){if(!n||typeof n!="object")return!1;const e=n;return e.version===Pw&&typeof e.sessionId=="string"&&typeof e.updatedAt=="number"&&(e.currentView==="cruce"||e.currentView==="historial")&&Array.isArray(e.uploadedBankFiles)&&typeof e.isCruceExecuted=="boolean"}async function tO(n,e){const i=Date.now()-ZC,a=n.transaction(ss,"readwrite"),l=Ic(a),u=a.objectStore(ss).openCursor();await new Promise((d,m)=>{u.onsuccess=()=>{const p=u.result;if(!p){d();return}const y=p.value;y.sessionId!==e&&typeof y.updatedAt=="number"&&y.updatedAtm(u.error??new Error("No se pudieron limpiar borradores antiguos."))}),await l}async function nO(){const n=tm();try{const e=await nm(),i=e.transaction(ss,"readonly"),a=Ic(i),l=await WC(i.objectStore(ss).get(n));return await a,tO(e,n).catch(()=>{}),eO(l)?l:null}catch{return null}}function sO(n){const e=tm(),i={...n,version:Pw,sessionId:e,updatedAt:Date.now()};return qa=qa.catch(()=>{}).then(async()=>{const l=(await nm()).transaction(ss,"readwrite"),c=Ic(l);l.objectStore(ss).put(i),await c}).catch(()=>{}),qa}function Sv(){const n=tm();return qa=qa.catch(()=>{}).then(async()=>{const i=(await nm()).transaction(ss,"readwrite"),a=Ic(i);i.objectStore(ss).delete(n),await a}).catch(()=>{}),qa}const Md=!1,_f="glm_cruce_selected_country",Bd={name:"Usuario GLM",email:"usuario@gomezleemarketing.com"};function iO(){try{const n=window.localStorage.getItem(_f),e=uo.find(i=>i.code===n&&i.enabled);return(e==null?void 0:e.code)??null}catch{return null}}function aO(){const[n,e]=D.useState("cruce"),[i,a]=D.useState(!1),[l,c]=D.useState(null),[u,d]=D.useState([]),[m,p]=D.useState([]),[y,v]=D.useState(!1),[x,_]=D.useState(null),[S,T]=D.useState(0),[j,k]=D.useState(()=>iO()),[M,C]=D.useState(Bd),[P,K]=D.useState(Md),[G,H]=D.useState(!1),[Y,Z]=D.useState(null);D.useRef(0);const se=D.useMemo(()=>Md,[]),me=j?wb(j):null,ye=(le,ue)=>{Z({message:le,type:ue})};D.useEffect(()=>{},[se]),D.useEffect(()=>{},[se]),D.useEffect(()=>{let le=!0;return(async()=>{const A=await nO();le&&(A&&(!j||A.countryCode===j?(A.countryCode&&k(A.countryCode),e(A.currentView),c(A.uploadedPayroll),d(Array.isArray(A.uploadedPayrollFiles)?A.uploadedPayrollFiles:[]),p(A.uploadedBankFiles),v(A.isCruceExecuted),_(A.cruceResponse)):await Sv()),le&&H(!0))})(),()=>{le=!1}},[]),D.useEffect(()=>{G&&sO({countryCode:j,currentView:n,uploadedPayroll:l,uploadedPayrollFiles:u,uploadedBankFiles:m,isCruceExecuted:y,cruceResponse:x})},[G,j,n,l,u,m,y,x]);const Ae=()=>{c(null),d([]),p([]),v(!1),_(null),T(le=>le+1)},Ne=async()=>{await Sv(),es&&await es.auth.signOut(),C(Bd),k(null),window.localStorage.removeItem(_f),Ae(),e("cruce"),ye("Sesión cerrada correctamente.","success")},Be=()=>{Ae(),e("cruce"),ye("Nuevo cruce iniciado.","success")},L=le=>{const ue=wb(le);if(!ue.enabled){ye(`${ue.name} estará disponible próximamente.`,"info");return}j&&j!==le&&Ae(),k(le),window.localStorage.setItem(_f,le),e("cruce"),a(!1)},W=()=>{k(null),a(!1)};if(P)return g.jsx("div",{className:"min-h-screen bg-[#F5F5F5] flex items-center justify-center text-[#4F758B] font-black uppercase tracking-wider",children:"Validando acceso..."});if(!me)return g.jsxs(g.Fragment,{children:[g.jsx(XC,{onSelect:L}),g.jsx(zi,{children:Y&&g.jsx(vv,{message:Y.message,type:Y.type,onClose:()=>Z(null)})})]});const Q=M??Bd;return g.jsxs("div",{className:"min-h-screen bg-[#F5F5F5] selection:bg-[#6CC24A] selection:text-white antialiased font-sans flex flex-col",children:[g.jsxs(Tn.div,{initial:{opacity:0},animate:{opacity:1},className:"min-h-screen flex w-full relative overflow-x-hidden",children:[g.jsx(zi,{children:i&&g.jsx(Tn.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},onClick:()=>a(!1),className:"fixed inset-0 bg-black/45 z-45 md:hidden"},"backdrop")}),g.jsx(iN,{currentView:n,onViewChange:le=>{e(le),a(!1)},onNewCruce:()=>{Be(),a(!1)},isSidebarOpen:i,onCloseSidebar:()=>a(!1),user:Q,isAuthEnabled:Md,onLogout:Ne,country:me,onCountryChange:L,onChooseAnotherCountry:W}),g.jsx("div",{className:"pl-0 md:pl-64 flex-1 flex flex-col w-full min-h-screen transition-all duration-300",children:g.jsx(zi,{mode:"wait",children:n==="cruce"?g.jsx(Tn.div,{initial:{opacity:0,x:10},animate:{opacity:1,x:0},exit:{opacity:0,x:-10},transition:{duration:.2},className:"flex-1 flex flex-col",children:g.jsx(LC,{onShowToast:ye,uploadedPayroll:l,setUploadedPayroll:c,uploadedPayrollFiles:u,setUploadedPayrollFiles:d,uploadedBankFiles:m,setUploadedBankFiles:p,isCruceExecuted:y,setIsCruceExecuted:v,response:x,setResponse:_,onOpenSidebar:()=>a(!0),operatorName:Q.name,operatorEmail:Q.email,resetToken:S,country:me})},`view-cruce-${me.code}`):g.jsx(Tn.div,{initial:{opacity:0,x:10},animate:{opacity:1,x:0},exit:{opacity:0,x:-10},transition:{duration:.2},className:"flex-1 flex flex-col",children:g.jsx(KC,{onShowToast:ye,onOpenSidebar:()=>a(!0),operatorName:Q.name,operatorEmail:Q.email,country:me})},`view-history-${me.code}`)})})]},`interface-${me.code}`),g.jsx(zi,{children:Y&&g.jsx(vv,{message:Y.message,type:Y.type,onClose:()=>Z(null)})})]})}window.addEventListener("pageshow",n=>{n.persisted&&window.location.reload()});i1.createRoot(document.getElementById("root")).render(g.jsx(D.StrictMode,{children:g.jsx(aO,{})})); diff --git a/dist/assets/index-DKvwoX2P.css b/dist/assets/index-DKvwoX2P.css new file mode 100644 index 0000000..2824bdb --- /dev/null +++ b/dist/assets/index-DKvwoX2P.css @@ -0,0 +1 @@ +@import"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&display=swap";/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:"Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-mono:"JetBrains Mono", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-800:oklch(44.4% .177 26.899);--color-orange-50:oklch(98% .016 73.684);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-300:oklch(83.7% .128 66.29);--color-orange-800:oklch(47% .157 37.304);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-800:oklch(47.3% .137 46.201);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-700:oklch(50.8% .118 165.612);--color-emerald-800:oklch(43.2% .095 166.913);--color-blue-50:oklch(97% .014 254.604);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-800:oklch(42.4% .199 265.638);--color-violet-200:oklch(89.4% .057 293.283);--color-violet-800:oklch(43.2% .232 292.759);--color-slate-700:oklch(37.2% .044 257.287);--color-neutral-50:oklch(98.5% 0 0);--color-neutral-100:oklch(97% 0 0);--color-neutral-200:oklch(92.2% 0 0);--color-neutral-300:oklch(87% 0 0);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-500:oklch(55.6% 0 0);--color-neutral-600:oklch(43.9% 0 0);--color-neutral-700:oklch(37.1% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-3xl:48rem;--container-5xl:64rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-black:900;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-md:.375rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-gris-fondo:#f5f5f5}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.top-0{top:0}.top-1\/2{top:50%}.top-\[84px\]{top:84px}.top-full{top:100%}.right-0{right:0}.right-6{right:calc(var(--spacing) * 6)}.bottom-0{bottom:0}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-0{left:0}.left-3{left:calc(var(--spacing) * 3)}.left-3\.5{left:calc(var(--spacing) * 3.5)}.z-10{z-index:10}.z-40{z-index:40}.z-45{z-index:45}.z-50{z-index:50}.z-\[80\]{z-index:80}.z-\[90\]{z-index:90}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-7{margin-bottom:calc(var(--spacing) * 7)}.-ml-2{margin-left:calc(var(--spacing) * -2)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-4\.5{height:calc(var(--spacing) * 4.5)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-14{height:calc(var(--spacing) * 14)}.h-\[80px\]{height:80px}.h-\[84px\]{height:84px}.h-screen{height:100vh}.max-h-\[92vh\]{max-height:92vh}.max-h-\[250px\]{max-height:250px}.max-h-\[260px\]{max-height:260px}.max-h-\[330px\]{max-height:330px}.min-h-\[130px\]{min-height:130px}.min-h-\[150px\]{min-height:150px}.min-h-\[190px\]{min-height:190px}.min-h-screen{min-height:100vh}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-4\.5{width:calc(var(--spacing) * 4.5)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-12{width:calc(var(--spacing) * 12)}.w-64{width:calc(var(--spacing) * 64)}.w-auto{width:auto}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[220px\]{max-width:220px}.max-w-\[260px\]{max-width:260px}.max-w-\[290px\]{max-width:290px}.max-w-\[300px\]{max-width:300px}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:0}.min-w-8{min-width:calc(var(--spacing) * 8)}.min-w-\[280px\]{min-width:280px}.min-w-\[760px\]{min-width:760px}.min-w-\[960px\]{min-width:960px}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.table-fixed{table-layout:fixed}.border-collapse{border-collapse:collapse}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0{--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.scroll-mt-28{scroll-margin-top:calc(var(--spacing) * 28)}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-neutral-100>:not(:last-child)){border-color:var(--color-neutral-100)}:where(.divide-neutral-200>:not(:last-child)){border-color:var(--color-neutral-200)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-4{border-top-style:var(--tw-border-style);border-top-width:4px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-4{border-bottom-style:var(--tw-border-style);border-bottom-width:4px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[\#4F758B\]{border-color:#4f758b}.border-\[\#4F758B\]\/10{border-color:#4f758b1a}.border-\[\#4F758B\]\/20{border-color:#4f758b33}.border-\[\#4F758B\]\/25{border-color:#4f758b40}.border-\[\#4F758B\]\/30{border-color:#4f758b4d}.border-\[\#4F758B\]\/40{border-color:#4f758b66}.border-\[\#6CC24A\]{border-color:#6cc24a}.border-\[\#6CC24A\]\/30{border-color:#6cc24a4d}.border-\[\#D0D0D0\]{border-color:#d0d0d0}.border-\[\#D6E8F4\]{border-color:#d6e8f4}.border-amber-200{border-color:var(--color-amber-200)}.border-blue-200{border-color:var(--color-blue-200)}.border-emerald-200{border-color:var(--color-emerald-200)}.border-emerald-700{border-color:var(--color-emerald-700)}.border-neutral-200{border-color:var(--color-neutral-200)}.border-neutral-200\/10{border-color:#e5e5e51a}@supports (color:color-mix(in lab,red,red)){.border-neutral-200\/10{border-color:color-mix(in oklab,var(--color-neutral-200) 10%,transparent)}}.border-neutral-300{border-color:var(--color-neutral-300)}.border-orange-200{border-color:var(--color-orange-200)}.border-red-100{border-color:var(--color-red-100)}.border-red-200{border-color:var(--color-red-200)}.border-red-800{border-color:var(--color-red-800)}.border-slate-700{border-color:var(--color-slate-700)}.border-transparent{border-color:#0000}.border-violet-200{border-color:var(--color-violet-200)}.border-white\/40{border-color:#fff6}@supports (color:color-mix(in lab,red,red)){.border-white\/40{border-color:color-mix(in oklab,var(--color-white) 40%,transparent)}}.border-t-white{border-top-color:var(--color-white)}.bg-\[\#4F758B\]{background-color:#4f758b}.bg-\[\#4F758B\]\/5{background-color:#4f758b0d}.bg-\[\#4F758B\]\/10{background-color:#4f758b1a}.bg-\[\#6CC24A\]{background-color:#6cc24a}.bg-\[\#6CC24A\]\/5{background-color:#6cc24a0d}.bg-\[\#6CC24A\]\/10{background-color:#6cc24a1a}.bg-\[\#D0D0D0\]{background-color:#d0d0d0}.bg-\[\#F5F5F5\]{background-color:#f5f5f5}.bg-\[\#F7FBFD\]{background-color:#f7fbfd}.bg-\[\#ba1a1a\]{background-color:#ba1a1a}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black\/45{background-color:#00000073}@supports (color:color-mix(in lab,red,red)){.bg-black\/45{background-color:color-mix(in oklab,var(--color-black) 45%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-neutral-50{background-color:var(--color-neutral-50)}.bg-neutral-50\/50{background-color:#fafafa80}@supports (color:color-mix(in lab,red,red)){.bg-neutral-50\/50{background-color:color-mix(in oklab,var(--color-neutral-50) 50%,transparent)}}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-orange-50{background-color:var(--color-orange-50)}.bg-red-50{background-color:var(--color-red-50)}.bg-white{background-color:var(--color-white)}.fill-current{fill:currentColor}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-14{padding-block:calc(var(--spacing) * 14)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-5{padding-top:calc(var(--spacing) * 5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.pl-0{padding-left:0}.pl-9{padding-left:calc(var(--spacing) * 9)}.pl-10{padding-left:calc(var(--spacing) * 10)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.18em\]{--tw-tracking:.18em;letter-spacing:.18em}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.text-\[\#4F758B\]{color:#4f758b}.text-\[\#6B8FA3\]{color:#6b8fa3}.text-\[\#6CC24A\]{color:#6cc24a}.text-\[\#ba1a1a\]{color:#ba1a1a}.text-amber-800{color:var(--color-amber-800)}.text-blue-800{color:var(--color-blue-800)}.text-emerald-700{color:var(--color-emerald-700)}.text-emerald-800{color:var(--color-emerald-800)}.text-neutral-300{color:var(--color-neutral-300)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-neutral-600{color:var(--color-neutral-600)}.text-neutral-700{color:var(--color-neutral-700)}.text-neutral-800{color:var(--color-neutral-800)}.text-orange-800{color:var(--color-orange-800)}.text-red-600{color:var(--color-red-600)}.text-violet-800{color:var(--color-violet-800)}.text-white{color:var(--color-white)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.placeholder-neutral-400::placeholder{color:var(--color-neutral-400)}.accent-\[\#6CC24A\]{accent-color:#6cc24a}.opacity-25{opacity:.25}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.selection\:bg-\[\#6CC24A\] ::selection{background-color:#6cc24a}.selection\:bg-\[\#6CC24A\]::selection{background-color:#6cc24a}.selection\:bg-transparent ::selection{background-color:#0000}.selection\:bg-transparent::selection{background-color:#0000}.selection\:text-white ::selection{color:var(--color-white)}.selection\:text-white::selection{color:var(--color-white)}@media(hover:hover){.hover\:border-\[\#4F758B\]:hover{border-color:#4f758b}.hover\:border-\[\#4F758B\]\/40:hover{border-color:#4f758b66}.hover\:border-\[\#4F758B\]\/50:hover{border-color:#4f758b80}.hover\:border-\[\#4F758B\]\/55:hover{border-color:#4f758b8c}.hover\:border-emerald-400:hover{border-color:var(--color-emerald-400)}.hover\:border-orange-300:hover{border-color:var(--color-orange-300)}.hover\:border-red-100:hover{border-color:var(--color-red-100)}.hover\:bg-\[\#3F6174\]:hover{background-color:#3f6174}.hover\:bg-\[\#3d6378\]:hover{background-color:#3d6378}.hover\:bg-\[\#4F758B\]:hover{background-color:#4f758b}.hover\:bg-\[\#4F758B\]\/5:hover{background-color:#4f758b0d}.hover\:bg-\[\#4F758B\]\/\[0\.025\]:hover{background-color:#4f758b06}.hover\:bg-\[\#5aaa3f\]:hover{background-color:#5aaa3f}.hover\:bg-\[\#5bb03c\]:hover{background-color:#5bb03c}.hover\:bg-\[\#41677b\]:hover{background-color:#41677b}.hover\:bg-emerald-100:hover{background-color:var(--color-emerald-100)}.hover\:bg-neutral-50:hover{background-color:var(--color-neutral-50)}.hover\:bg-neutral-50\/70:hover{background-color:#fafafab3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-neutral-50\/70:hover{background-color:color-mix(in oklab,var(--color-neutral-50) 70%,transparent)}}.hover\:bg-neutral-100:hover{background-color:var(--color-neutral-100)}.hover\:bg-neutral-200:hover{background-color:var(--color-neutral-200)}.hover\:bg-orange-100:hover{background-color:var(--color-orange-100)}.hover\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\:bg-white\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/20:hover{background-color:color-mix(in oklab,var(--color-white) 20%,transparent)}}.hover\:text-\[\#3d6378\]:hover{color:#3d6378}.hover\:text-\[\#4F758B\]:hover{color:#4f758b}.hover\:text-emerald-800:hover{color:var(--color-emerald-800)}.hover\:text-neutral-700:hover{color:var(--color-neutral-700)}.hover\:text-neutral-800:hover{color:var(--color-neutral-800)}.hover\:text-red-500:hover{color:var(--color-red-500)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\:border-\[\#4F758B\]:focus{border-color:#4f758b}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-\[\#4F758B\]\/10:focus{--tw-ring-color:oklab(54.2682% -.0318721 -.0447881/.1)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-98:active{--tw-scale-x:98%;--tw-scale-y:98%;--tw-scale-z:98%;scale:var(--tw-scale-x) var(--tw-scale-y)}.active\:scale-\[0\.99\]:active{scale:.99}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:border-neutral-300:disabled{border-color:var(--color-neutral-300)}.disabled\:bg-neutral-50:disabled{background-color:var(--color-neutral-50)}.disabled\:bg-neutral-300:disabled{background-color:var(--color-neutral-300)}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-45:disabled{opacity:.45}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:40rem){.sm\:col-span-2{grid-column:span 2/span 2}.sm\:flex{display:flex}.sm\:inline{display:inline}.sm\:inline-flex{display:inline-flex}.sm\:h-6{height:calc(var(--spacing) * 6)}.sm\:h-10{height:calc(var(--spacing) * 10)}.sm\:w-16{width:calc(var(--spacing) * 16)}.sm\:w-auto{width:auto}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}.sm\:justify-end{justify-content:flex-end}.sm\:gap-2{gap:calc(var(--spacing) * 2)}.sm\:gap-3{gap:calc(var(--spacing) * 3)}.sm\:self-auto{align-self:auto}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:p-9{padding:calc(var(--spacing) * 9)}.sm\:px-3{padding-inline:calc(var(--spacing) * 3)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:px-8{padding-inline:calc(var(--spacing) * 8)}.sm\:text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.sm\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}}@media(min-width:48rem){.md\:block{display:block}.md\:hidden{display:none}.md\:translate-x-0{--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-\[1fr_auto\]{grid-template-columns:1fr auto}.md\:justify-center{justify-content:center}.md\:pl-64{padding-left:calc(var(--spacing) * 64)}.md\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}}@media(min-width:64rem){.lg\:w-\[8\%\]{width:8%}.lg\:w-\[9\%\]{width:9%}.lg\:w-\[10\%\]{width:10%}.lg\:w-\[16\%\]{width:16%}.lg\:w-\[21\%\]{width:21%}.lg\:w-auto{width:auto}.lg\:max-w-md{max-width:var(--container-md)}.lg\:max-w-sm{max-width:var(--container-sm)}.lg\:min-w-0{min-width:0}.lg\:table-fixed{table-layout:fixed}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:items-start{align-items:flex-start}.lg\:justify-between{justify-content:space-between}.lg\:overflow-x-hidden{overflow-x:hidden}.lg\:text-right{text-align:right}.lg\:text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}}@media(min-width:80rem){.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.xl\:px-3{padding-inline:calc(var(--spacing) * 3)}}@media(min-width:96rem){.\32xl\:inline{display:inline}}}body{font-family:var(--font-sans);background-color:var(--color-gris-fondo)}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}} diff --git a/dist/assets/index-saVPcx_I.js b/dist/assets/index-saVPcx_I.js deleted file mode 100644 index d201809..0000000 --- a/dist/assets/index-saVPcx_I.js +++ /dev/null @@ -1,270 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))a(l);new MutationObserver(l=>{for(const c of l)if(c.type==="childList")for(const u of c.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&a(u)}).observe(document,{childList:!0,subtree:!0});function i(l){const c={};return l.integrity&&(c.integrity=l.integrity),l.referrerPolicy&&(c.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?c.credentials="include":l.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function a(l){if(l.ep)return;l.ep=!0;const c=i(l);fetch(l.href,c)}})();var sd={exports:{}},qr={};/** - * @license React - * react-jsx-runtime.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Ky;function WS(){if(Ky)return qr;Ky=1;var n=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function i(a,l,c){var u=null;if(c!==void 0&&(u=""+c),l.key!==void 0&&(u=""+l.key),"key"in l){c={};for(var d in l)d!=="key"&&(c[d]=l[d])}else c=l;return l=c.ref,{$$typeof:n,type:a,key:u,ref:l!==void 0?l:null,props:c}}return qr.Fragment=e,qr.jsx=i,qr.jsxs=i,qr}var Yy;function e1(){return Yy||(Yy=1,sd.exports=WS()),sd.exports}var g=e1(),id={exports:{}},be={};/** - * @license React - * react.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Xy;function t1(){if(Xy)return be;Xy=1;var n=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),l=Symbol.for("react.profiler"),c=Symbol.for("react.consumer"),u=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),m=Symbol.for("react.suspense"),p=Symbol.for("react.memo"),y=Symbol.for("react.lazy"),v=Symbol.for("react.activity"),x=Symbol.iterator;function _(E){return E===null||typeof E!="object"?null:(E=x&&E[x]||E["@@iterator"],typeof E=="function"?E:null)}var S={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},T=Object.assign,k={};function R(E,H,W){this.props=E,this.context=H,this.refs=k,this.updater=W||S}R.prototype.isReactComponent={},R.prototype.setState=function(E,H){if(typeof E!="object"&&typeof E!="function"&&E!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,E,H,"setState")},R.prototype.forceUpdate=function(E){this.updater.enqueueForceUpdate(this,E,"forceUpdate")};function M(){}M.prototype=R.prototype;function N(E,H,W){this.props=E,this.context=H,this.refs=k,this.updater=W||S}var P=N.prototype=new M;P.constructor=N,T(P,R.prototype),P.isPureReactComponent=!0;var G=Array.isArray;function X(){}var q={H:null,A:null,T:null,S:null},Y=Object.prototype.hasOwnProperty;function se(E,H,W){var Q=W.ref;return{$$typeof:n,type:E,key:H,ref:Q!==void 0?Q:null,props:W}}function J(E,H){return se(E.type,H,E.props)}function he(E){return typeof E=="object"&&E!==null&&E.$$typeof===n}function fe(E){var H={"=":"=0",":":"=2"};return"$"+E.replace(/[=:]/g,function(W){return H[W]})}var Ae=/\/+/g;function ve(E,H){return typeof E=="object"&&E!==null&&E.key!=null?fe(""+E.key):H.toString(36)}function Ce(E){switch(E.status){case"fulfilled":return E.value;case"rejected":throw E.reason;default:switch(typeof E.status=="string"?E.then(X,X):(E.status="pending",E.then(function(H){E.status==="pending"&&(E.status="fulfilled",E.value=H)},function(H){E.status==="pending"&&(E.status="rejected",E.reason=H)})),E.status){case"fulfilled":return E.value;case"rejected":throw E.reason}}throw E}function L(E,H,W,Q,oe){var re=typeof E;(re==="undefined"||re==="boolean")&&(E=null);var _e=!1;if(E===null)_e=!0;else switch(re){case"bigint":case"string":case"number":_e=!0;break;case"object":switch(E.$$typeof){case n:case e:_e=!0;break;case y:return _e=E._init,L(_e(E._payload),H,W,Q,oe)}}if(_e)return oe=oe(E),_e=Q===""?"."+ve(E,0):Q,G(oe)?(W="",_e!=null&&(W=_e.replace(Ae,"$&/")+"/"),L(oe,H,W,"",function(en){return en})):oe!=null&&(he(oe)&&(oe=J(oe,W+(oe.key==null||E&&E.key===oe.key?"":(""+oe.key).replace(Ae,"$&/")+"/")+_e)),H.push(oe)),1;_e=0;var ke=Q===""?".":Q+":";if(G(E))for(var He=0;He>>1,ie=L[pe];if(0>>1;pel(W,Z))Ql(oe,W)?(L[pe]=oe,L[Q]=Z,pe=Q):(L[pe]=W,L[H]=Z,pe=H);else if(Ql(oe,Z))L[pe]=oe,L[Q]=Z,pe=Q;else break e}}return K}function l(L,K){var Z=L.sortIndex-K.sortIndex;return Z!==0?Z:L.id-K.id}if(n.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var c=performance;n.unstable_now=function(){return c.now()}}else{var u=Date,d=u.now();n.unstable_now=function(){return u.now()-d}}var m=[],p=[],y=1,v=null,x=3,_=!1,S=!1,T=!1,k=!1,R=typeof setTimeout=="function"?setTimeout:null,M=typeof clearTimeout=="function"?clearTimeout:null,N=typeof setImmediate<"u"?setImmediate:null;function P(L){for(var K=i(p);K!==null;){if(K.callback===null)a(p);else if(K.startTime<=L)a(p),K.sortIndex=K.expirationTime,e(m,K);else break;K=i(p)}}function G(L){if(T=!1,P(L),!S)if(i(m)!==null)S=!0,X||(X=!0,fe());else{var K=i(p);K!==null&&Ce(G,K.startTime-L)}}var X=!1,q=-1,Y=5,se=-1;function J(){return k?!0:!(n.unstable_now()-seL&&J());){var pe=v.callback;if(typeof pe=="function"){v.callback=null,x=v.priorityLevel;var ie=pe(v.expirationTime<=L);if(L=n.unstable_now(),typeof ie=="function"){v.callback=ie,P(L),K=!0;break t}v===i(m)&&a(m),P(L)}else a(m);v=i(m)}if(v!==null)K=!0;else{var E=i(p);E!==null&&Ce(G,E.startTime-L),K=!1}}break e}finally{v=null,x=Z,_=!1}K=void 0}}finally{K?fe():X=!1}}}var fe;if(typeof N=="function")fe=function(){N(he)};else if(typeof MessageChannel<"u"){var Ae=new MessageChannel,ve=Ae.port2;Ae.port1.onmessage=he,fe=function(){ve.postMessage(null)}}else fe=function(){R(he,0)};function Ce(L,K){q=R(function(){L(n.unstable_now())},K)}n.unstable_IdlePriority=5,n.unstable_ImmediatePriority=1,n.unstable_LowPriority=4,n.unstable_NormalPriority=3,n.unstable_Profiling=null,n.unstable_UserBlockingPriority=2,n.unstable_cancelCallback=function(L){L.callback=null},n.unstable_forceFrameRate=function(L){0>L||125pe?(L.sortIndex=Z,e(p,L),i(m)===null&&L===i(p)&&(T?(M(q),q=-1):T=!0,Ce(G,Z-pe))):(L.sortIndex=ie,e(m,L),S||_||(S=!0,X||(X=!0,fe()))),L},n.unstable_shouldYield=J,n.unstable_wrapCallback=function(L){var K=x;return function(){var Z=x;x=K;try{return L.apply(this,arguments)}finally{x=Z}}}})(od)),od}var Zy;function s1(){return Zy||(Zy=1,rd.exports=n1()),rd.exports}var ld={exports:{}},Pt={};/** - * @license React - * react-dom.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Wy;function i1(){if(Wy)return Pt;Wy=1;var n=Tf();function e(m){var p="https://react.dev/errors/"+m;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}return n(),ld.exports=i1(),ld.exports}/** - * @license React - * react-dom-client.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var t0;function r1(){if(t0)return Fr;t0=1;var n=s1(),e=Tf(),i=a1();function a(t){var s="https://react.dev/errors/"+t;if(1ie||(t.current=pe[ie],pe[ie]=null,ie--)}function W(t,s){ie++,pe[ie]=t.current,t.current=s}var Q=E(null),oe=E(null),re=E(null),_e=E(null);function ke(t,s){switch(W(re,s),W(oe,t),W(Q,null),s.nodeType){case 9:case 11:t=(t=s.documentElement)&&(t=t.namespaceURI)?gy(t):0;break;default:if(t=s.tagName,s=s.namespaceURI)s=gy(s),t=yy(s,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}H(Q),W(Q,t)}function He(){H(Q),H(oe),H(re)}function en(t){t.memoizedState!==null&&W(_e,t);var s=Q.current,r=yy(s,t.type);s!==r&&(W(oe,t),W(Q,r))}function jn(t){oe.current===t&&(H(Q),H(oe)),_e.current===t&&(H(_e),Pr._currentValue=Z)}var Rs,is;function te(t){if(Rs===void 0)try{throw Error()}catch(r){var s=r.stack.trim().match(/\n( *(at )?)/);Rs=s&&s[1]||"",is=-1)":-1h||A[o]!==U[h]){var $=` -`+A[o].replace(" at new "," at ");return t.displayName&&$.includes("")&&($=$.replace("",t.displayName)),$}while(1<=o&&0<=h);break}}}finally{Be=!1,Error.prepareStackTrace=r}return(r=t?t.displayName||t.name:"")?te(r):""}function xe(t,s){switch(t.tag){case 26:case 27:case 5:return te(t.type);case 16:return te("Lazy");case 13:return t.child!==s&&s!==null?te("Suspense Fallback"):te("Suspense");case 19:return te("SuspenseList");case 0:case 15:return Ue(t.type,!1);case 11:return Ue(t.type.render,!1);case 1:return Ue(t.type,!0);case 31:return te("Activity");default:return""}}function $e(t){try{var s="",r=null;do s+=xe(t,r),r=t,t=t.return;while(t);return s}catch(o){return` -Error generating stack: `+o.message+` -`+o.stack}}var kt=Object.prototype.hasOwnProperty,xt=n.unstable_scheduleCallback,Et=n.unstable_cancelCallback,Ht=n.unstable_shouldYield,Nn=n.unstable_requestPaint,We=n.unstable_now,tn=n.unstable_getCurrentPriorityLevel,Gt=n.unstable_ImmediatePriority,kn=n.unstable_UserBlockingPriority,fn=n.unstable_NormalPriority,Rn=n.unstable_LowPriority,Cs=n.unstable_IdlePriority,Os=n.log,qn=n.unstable_setDisableYieldValue,as=null,$t=null;function et(t){if(typeof Os=="function"&&qn(t),$t&&typeof $t.setStrictMode=="function")try{$t.setStrictMode(as,t)}catch{}}var Lt=Math.clz32?Math.clz32:ui,ko=Math.log,Ro=Math.LN2;function ui(t){return t>>>=0,t===0?32:31-(ko(t)/Ro|0)|0}var hi=256,Hi=262144,$i=4194304;function rs(t){var s=t&42;if(s!==0)return s;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function qi(t,s,r){var o=t.pendingLanes;if(o===0)return 0;var h=0,f=t.suspendedLanes,b=t.pingedLanes;t=t.warmLanes;var w=o&134217727;return w!==0?(o=w&~f,o!==0?h=rs(o):(b&=w,b!==0?h=rs(b):r||(r=w&~t,r!==0&&(h=rs(r))))):(w=o&~f,w!==0?h=rs(w):b!==0?h=rs(b):r||(r=o&~t,r!==0&&(h=rs(r)))),h===0?0:s!==0&&s!==h&&(s&f)===0&&(f=h&-h,r=s&-s,f>=r||f===32&&(r&4194048)!==0)?s:h}function di(t,s){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&s)===0}function Xc(t,s){switch(t){case 1:case 2:case 4:case 8:case 64:return s+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return s+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Za(){var t=$i;return $i<<=1,($i&62914560)===0&&($i=4194304),t}function Wa(t){for(var s=[],r=0;31>r;r++)s.push(t);return s}function fi(t,s){t.pendingLanes|=s,s!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function Co(t,s,r,o,h,f){var b=t.pendingLanes;t.pendingLanes=r,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=r,t.entangledLanes&=r,t.errorRecoveryDisabledLanes&=r,t.shellSuspendCounter=0;var w=t.entanglements,A=t.expirationTimes,U=t.hiddenUpdates;for(r=b&~r;0"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var Kw=/[\n"\\]/g;function pn(t){return t.replace(Kw,function(s){return"\\"+s.charCodeAt(0).toString(16)+" "})}function Qc(t,s,r,o,h,f,b,w){t.name="",b!=null&&typeof b!="function"&&typeof b!="symbol"&&typeof b!="boolean"?t.type=b:t.removeAttribute("type"),s!=null?b==="number"?(s===0&&t.value===""||t.value!=s)&&(t.value=""+mn(s)):t.value!==""+mn(s)&&(t.value=""+mn(s)):b!=="submit"&&b!=="reset"||t.removeAttribute("value"),s!=null?Zc(t,b,mn(s)):r!=null?Zc(t,b,mn(r)):o!=null&&t.removeAttribute("value"),h==null&&f!=null&&(t.defaultChecked=!!f),h!=null&&(t.checked=h&&typeof h!="function"&&typeof h!="symbol"),w!=null&&typeof w!="function"&&typeof w!="symbol"&&typeof w!="boolean"?t.name=""+mn(w):t.removeAttribute("name")}function um(t,s,r,o,h,f,b,w){if(f!=null&&typeof f!="function"&&typeof f!="symbol"&&typeof f!="boolean"&&(t.type=f),s!=null||r!=null){if(!(f!=="submit"&&f!=="reset"||s!=null)){Jc(t);return}r=r!=null?""+mn(r):"",s=s!=null?""+mn(s):r,w||s===t.value||(t.value=s),t.defaultValue=s}o=o??h,o=typeof o!="function"&&typeof o!="symbol"&&!!o,t.checked=w?t.checked:!!o,t.defaultChecked=!!o,b!=null&&typeof b!="function"&&typeof b!="symbol"&&typeof b!="boolean"&&(t.name=b),Jc(t)}function Zc(t,s,r){s==="number"&&zo(t.ownerDocument)===t||t.defaultValue===""+r||(t.defaultValue=""+r)}function Gi(t,s,r,o){if(t=t.options,s){s={};for(var h=0;h"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),su=!1;if(cs)try{var sr={};Object.defineProperty(sr,"passive",{get:function(){su=!0}}),window.addEventListener("test",sr,sr),window.removeEventListener("test",sr,sr)}catch{su=!1}var Ds=null,iu=null,Vo=null;function ym(){if(Vo)return Vo;var t,s=iu,r=s.length,o,h="value"in Ds?Ds.value:Ds.textContent,f=h.length;for(t=0;t=rr),Sm=" ",Tm=!1;function Em(t,s){switch(t){case"keyup":return w_.indexOf(s.keyCode)!==-1;case"keydown":return s.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Am(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var Ji=!1;function S_(t,s){switch(t){case"compositionend":return Am(s);case"keypress":return s.which!==32?null:(Tm=!0,Sm);case"textInput":return t=s.data,t===Sm&&Tm?null:t;default:return null}}function T_(t,s){if(Ji)return t==="compositionend"||!cu&&Em(t,s)?(t=ym(),Vo=iu=Ds=null,Ji=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(s.ctrlKey||s.altKey||s.metaKey)||s.ctrlKey&&s.altKey){if(s.char&&1=s)return{node:r,offset:s-t};t=o}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=Mm(r)}}function Um(t,s){return t&&s?t===s?!0:t&&t.nodeType===3?!1:s&&s.nodeType===3?Um(t,s.parentNode):"contains"in t?t.contains(s):t.compareDocumentPosition?!!(t.compareDocumentPosition(s)&16):!1:!1}function Lm(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var s=zo(t.document);s instanceof t.HTMLIFrameElement;){try{var r=typeof s.contentWindow.location.href=="string"}catch{r=!1}if(r)t=s.contentWindow;else break;s=zo(t.document)}return s}function du(t){var s=t&&t.nodeName&&t.nodeName.toLowerCase();return s&&(s==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||s==="textarea"||t.contentEditable==="true")}var O_=cs&&"documentMode"in document&&11>=document.documentMode,Qi=null,fu=null,ur=null,mu=!1;function zm(t,s,r){var o=r.window===r?r.document:r.nodeType===9?r:r.ownerDocument;mu||Qi==null||Qi!==zo(o)||(o=Qi,"selectionStart"in o&&du(o)?o={start:o.selectionStart,end:o.selectionEnd}:(o=(o.ownerDocument&&o.ownerDocument.defaultView||window).getSelection(),o={anchorNode:o.anchorNode,anchorOffset:o.anchorOffset,focusNode:o.focusNode,focusOffset:o.focusOffset}),ur&&cr(ur,o)||(ur=o,o=Dl(fu,"onSelect"),0>=b,h-=b,In=1<<32-Lt(s)+h|r<Se?(Ne=de,de=null):Ne=de.sibling;var De=z(O,de,B[Se],F);if(De===null){de===null&&(de=Ne);break}t&&de&&De.alternate===null&&s(O,de),j=f(De,j,Se),Oe===null?me=De:Oe.sibling=De,Oe=De,de=Ne}if(Se===B.length)return r(O,de),Re&&hs(O,Se),me;if(de===null){for(;SeSe?(Ne=de,de=null):Ne=de.sibling;var ti=z(O,de,De.value,F);if(ti===null){de===null&&(de=Ne);break}t&&de&&ti.alternate===null&&s(O,de),j=f(ti,j,Se),Oe===null?me=ti:Oe.sibling=ti,Oe=ti,de=Ne}if(De.done)return r(O,de),Re&&hs(O,Se),me;if(de===null){for(;!De.done;Se++,De=B.next())De=I(O,De.value,F),De!==null&&(j=f(De,j,Se),Oe===null?me=De:Oe.sibling=De,Oe=De);return Re&&hs(O,Se),me}for(de=o(de);!De.done;Se++,De=B.next())De=V(de,O,Se,De.value,F),De!==null&&(t&&De.alternate!==null&&de.delete(De.key===null?Se:De.key),j=f(De,j,Se),Oe===null?me=De:Oe.sibling=De,Oe=De);return t&&de.forEach(function(ZS){return s(O,ZS)}),Re&&hs(O,Se),me}function Ie(O,j,B,F){if(typeof B=="object"&&B!==null&&B.type===T&&B.key===null&&(B=B.props.children),typeof B=="object"&&B!==null){switch(B.$$typeof){case _:e:{for(var me=B.key;j!==null;){if(j.key===me){if(me=B.type,me===T){if(j.tag===7){r(O,j.sibling),F=h(j,B.props.children),F.return=O,O=F;break e}}else if(j.elementType===me||typeof me=="object"&&me!==null&&me.$$typeof===Y&&Ti(me)===j.type){r(O,j.sibling),F=h(j,B.props),gr(F,B),F.return=O,O=F;break e}r(O,j);break}else s(O,j);j=j.sibling}B.type===T?(F=vi(B.props.children,O.mode,F,B.key),F.return=O,O=F):(F=Jo(B.type,B.key,B.props,null,O.mode,F),gr(F,B),F.return=O,O=F)}return b(O);case S:e:{for(me=B.key;j!==null;){if(j.key===me)if(j.tag===4&&j.stateNode.containerInfo===B.containerInfo&&j.stateNode.implementation===B.implementation){r(O,j.sibling),F=h(j,B.children||[]),F.return=O,O=F;break e}else{r(O,j);break}else s(O,j);j=j.sibling}F=wu(B,O.mode,F),F.return=O,O=F}return b(O);case Y:return B=Ti(B),Ie(O,j,B,F)}if(Ce(B))return le(O,j,B,F);if(fe(B)){if(me=fe(B),typeof me!="function")throw Error(a(150));return B=me.call(B),ye(O,j,B,F)}if(typeof B.then=="function")return Ie(O,j,sl(B),F);if(B.$$typeof===N)return Ie(O,j,Wo(O,B),F);il(O,B)}return typeof B=="string"&&B!==""||typeof B=="number"||typeof B=="bigint"?(B=""+B,j!==null&&j.tag===6?(r(O,j.sibling),F=h(j,B),F.return=O,O=F):(r(O,j),F=xu(B,O.mode,F),F.return=O,O=F),b(O)):r(O,j)}return function(O,j,B,F){try{pr=0;var me=Ie(O,j,B,F);return la=null,me}catch(de){if(de===oa||de===tl)throw de;var Oe=sn(29,de,null,O.mode);return Oe.lanes=F,Oe.return=O,Oe}finally{}}}var Ai=op(!0),lp=op(!1),zs=!1;function Du(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Mu(t,s){t=t.updateQueue,s.updateQueue===t&&(s.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function Ps(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function Vs(t,s,r){var o=t.updateQueue;if(o===null)return null;if(o=o.shared,(ze&2)!==0){var h=o.pending;return h===null?s.next=s:(s.next=h.next,h.next=s),o.pending=s,s=Xo(t),Im(t,null,r),s}return Yo(t,o,s,r),Xo(t)}function yr(t,s,r){if(s=s.updateQueue,s!==null&&(s=s.shared,(r&4194048)!==0)){var o=s.lanes;o&=t.pendingLanes,r|=o,s.lanes=r,Do(t,r)}}function Bu(t,s){var r=t.updateQueue,o=t.alternate;if(o!==null&&(o=o.updateQueue,r===o)){var h=null,f=null;if(r=r.firstBaseUpdate,r!==null){do{var b={lane:r.lane,tag:r.tag,payload:r.payload,callback:null,next:null};f===null?h=f=b:f=f.next=b,r=r.next}while(r!==null);f===null?h=f=s:f=f.next=s}else h=f=s;r={baseState:o.baseState,firstBaseUpdate:h,lastBaseUpdate:f,shared:o.shared,callbacks:o.callbacks},t.updateQueue=r;return}t=r.lastBaseUpdate,t===null?r.firstBaseUpdate=s:t.next=s,r.lastBaseUpdate=s}var Uu=!1;function br(){if(Uu){var t=ra;if(t!==null)throw t}}function vr(t,s,r,o){Uu=!1;var h=t.updateQueue;zs=!1;var f=h.firstBaseUpdate,b=h.lastBaseUpdate,w=h.shared.pending;if(w!==null){h.shared.pending=null;var A=w,U=A.next;A.next=null,b===null?f=U:b.next=U,b=A;var $=t.alternate;$!==null&&($=$.updateQueue,w=$.lastBaseUpdate,w!==b&&(w===null?$.firstBaseUpdate=U:w.next=U,$.lastBaseUpdate=A))}if(f!==null){var I=h.baseState;b=0,$=U=A=null,w=f;do{var z=w.lane&-536870913,V=z!==w.lane;if(V?(je&z)===z:(o&z)===z){z!==0&&z===aa&&(Uu=!0),$!==null&&($=$.next={lane:0,tag:w.tag,payload:w.payload,callback:null,next:null});e:{var le=t,ye=w;z=s;var Ie=r;switch(ye.tag){case 1:if(le=ye.payload,typeof le=="function"){I=le.call(Ie,I,z);break e}I=le;break e;case 3:le.flags=le.flags&-65537|128;case 0:if(le=ye.payload,z=typeof le=="function"?le.call(Ie,I,z):le,z==null)break e;I=v({},I,z);break e;case 2:zs=!0}}z=w.callback,z!==null&&(t.flags|=64,V&&(t.flags|=8192),V=h.callbacks,V===null?h.callbacks=[z]:V.push(z))}else V={lane:z,tag:w.tag,payload:w.payload,callback:w.callback,next:null},$===null?(U=$=V,A=I):$=$.next=V,b|=z;if(w=w.next,w===null){if(w=h.shared.pending,w===null)break;V=w,w=V.next,V.next=null,h.lastBaseUpdate=V,h.shared.pending=null}}while(!0);$===null&&(A=I),h.baseState=A,h.firstBaseUpdate=U,h.lastBaseUpdate=$,f===null&&(h.shared.lanes=0),Is|=b,t.lanes=b,t.memoizedState=I}}function cp(t,s){if(typeof t!="function")throw Error(a(191,t));t.call(s)}function up(t,s){var r=t.callbacks;if(r!==null)for(t.callbacks=null,t=0;tf?f:8;var b=L.T,w={};L.T=w,th(t,!1,s,r);try{var A=h(),U=L.S;if(U!==null&&U(w,A),A!==null&&typeof A=="object"&&typeof A.then=="function"){var $=H_(A,o);_r(t,s,$,cn(t))}else _r(t,s,o,cn(t))}catch(I){_r(t,s,{then:function(){},status:"rejected",reason:I},cn())}finally{K.p=f,b!==null&&w.types!==null&&(b.types=w.types),L.T=b}}function K_(){}function Wu(t,s,r,o){if(t.tag!==5)throw Error(a(476));var h=$p(t).queue;Hp(t,h,s,Z,r===null?K_:function(){return qp(t),r(o)})}function $p(t){var s=t.memoizedState;if(s!==null)return s;s={memoizedState:Z,baseState:Z,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ps,lastRenderedState:Z},next:null};var r={};return s.next={memoizedState:r,baseState:r,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ps,lastRenderedState:r},next:null},t.memoizedState=s,t=t.alternate,t!==null&&(t.memoizedState=s),s}function qp(t){var s=$p(t);s.next===null&&(s=t.alternate.memoizedState),_r(t,s.next.queue,{},cn())}function eh(){return Ot(Pr)}function Fp(){return dt().memoizedState}function Ip(){return dt().memoizedState}function Y_(t){for(var s=t.return;s!==null;){switch(s.tag){case 24:case 3:var r=cn();t=Ps(r);var o=Vs(s,t,r);o!==null&&(Zt(o,s,r),yr(o,s,r)),s={cache:ku()},t.payload=s;return}s=s.return}}function X_(t,s,r){var o=cn();r={lane:o,revertLane:0,gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},ml(t)?Kp(s,r):(r=bu(t,s,r,o),r!==null&&(Zt(r,t,o),Yp(r,s,o)))}function Gp(t,s,r){var o=cn();_r(t,s,r,o)}function _r(t,s,r,o){var h={lane:o,revertLane:0,gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null};if(ml(t))Kp(s,h);else{var f=t.alternate;if(t.lanes===0&&(f===null||f.lanes===0)&&(f=s.lastRenderedReducer,f!==null))try{var b=s.lastRenderedState,w=f(b,r);if(h.hasEagerState=!0,h.eagerState=w,nn(w,b))return Yo(t,s,h,0),Ke===null&&Ko(),!1}catch{}finally{}if(r=bu(t,s,h,o),r!==null)return Zt(r,t,o),Yp(r,s,o),!0}return!1}function th(t,s,r,o){if(o={lane:2,revertLane:Dh(),gesture:null,action:o,hasEagerState:!1,eagerState:null,next:null},ml(t)){if(s)throw Error(a(479))}else s=bu(t,r,o,2),s!==null&&Zt(s,t,2)}function ml(t){var s=t.alternate;return t===we||s!==null&&s===we}function Kp(t,s){ua=ol=!0;var r=t.pending;r===null?s.next=s:(s.next=r.next,r.next=s),t.pending=s}function Yp(t,s,r){if((r&4194048)!==0){var o=s.lanes;o&=t.pendingLanes,r|=o,s.lanes=r,Do(t,r)}}var Sr={readContext:Ot,use:ul,useCallback:rt,useContext:rt,useEffect:rt,useImperativeHandle:rt,useLayoutEffect:rt,useInsertionEffect:rt,useMemo:rt,useReducer:rt,useRef:rt,useState:rt,useDebugValue:rt,useDeferredValue:rt,useTransition:rt,useSyncExternalStore:rt,useId:rt,useHostTransitionStatus:rt,useFormState:rt,useActionState:rt,useOptimistic:rt,useMemoCache:rt,useCacheRefresh:rt};Sr.useEffectEvent=rt;var Xp={readContext:Ot,use:ul,useCallback:function(t,s){return qt().memoizedState=[t,s===void 0?null:s],t},useContext:Ot,useEffect:Op,useImperativeHandle:function(t,s,r){r=r!=null?r.concat([t]):null,dl(4194308,4,Up.bind(null,s,t),r)},useLayoutEffect:function(t,s){return dl(4194308,4,t,s)},useInsertionEffect:function(t,s){dl(4,2,t,s)},useMemo:function(t,s){var r=qt();s=s===void 0?null:s;var o=t();if(ji){et(!0);try{t()}finally{et(!1)}}return r.memoizedState=[o,s],o},useReducer:function(t,s,r){var o=qt();if(r!==void 0){var h=r(s);if(ji){et(!0);try{r(s)}finally{et(!1)}}}else h=s;return o.memoizedState=o.baseState=h,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:h},o.queue=t,t=t.dispatch=X_.bind(null,we,t),[o.memoizedState,t]},useRef:function(t){var s=qt();return t={current:t},s.memoizedState=t},useState:function(t){t=Yu(t);var s=t.queue,r=Gp.bind(null,we,s);return s.dispatch=r,[t.memoizedState,r]},useDebugValue:Qu,useDeferredValue:function(t,s){var r=qt();return Zu(r,t,s)},useTransition:function(){var t=Yu(!1);return t=Hp.bind(null,we,t.queue,!0,!1),qt().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,s,r){var o=we,h=qt();if(Re){if(r===void 0)throw Error(a(407));r=r()}else{if(r=s(),Ke===null)throw Error(a(349));(je&127)!==0||gp(o,s,r)}h.memoizedState=r;var f={value:r,getSnapshot:s};return h.queue=f,Op(bp.bind(null,o,f,t),[t]),o.flags|=2048,da(9,{destroy:void 0},yp.bind(null,o,f,r,s),null),r},useId:function(){var t=qt(),s=Ke.identifierPrefix;if(Re){var r=Gn,o=In;r=(o&~(1<<32-Lt(o)-1)).toString(32)+r,s="_"+s+"R_"+r,r=ll++,0<\/script>",f=f.removeChild(f.firstChild);break;case"select":f=typeof o.is=="string"?b.createElement("select",{is:o.is}):b.createElement("select"),o.multiple?f.multiple=!0:o.size&&(f.size=o.size);break;default:f=typeof o.is=="string"?b.createElement(h,{is:o.is}):b.createElement(h)}}f[ae]=s,f[nt]=o;e:for(b=s.child;b!==null;){if(b.tag===5||b.tag===6)f.appendChild(b.stateNode);else if(b.tag!==4&&b.tag!==27&&b.child!==null){b.child.return=b,b=b.child;continue}if(b===s)break e;for(;b.sibling===null;){if(b.return===null||b.return===s)break e;b=b.return}b.sibling.return=b.return,b=b.sibling}s.stateNode=f;e:switch(Mt(f,h,o),h){case"button":case"input":case"select":case"textarea":o=!!o.autoFocus;break e;case"img":o=!0;break e;default:o=!1}o&&ys(s)}}return Ze(s),ph(s,s.type,t===null?null:t.memoizedProps,s.pendingProps,r),null;case 6:if(t&&s.stateNode!=null)t.memoizedProps!==o&&ys(s);else{if(typeof o!="string"&&s.stateNode===null)throw Error(a(166));if(t=re.current,sa(s)){if(t=s.stateNode,r=s.memoizedProps,o=null,h=Ct,h!==null)switch(h.tag){case 27:case 5:o=h.memoizedProps}t[ae]=s,t=!!(t.nodeValue===r||o!==null&&o.suppressHydrationWarning===!0||my(t.nodeValue,r)),t||Us(s,!0)}else t=Ml(t).createTextNode(o),t[ae]=s,s.stateNode=t}return Ze(s),null;case 31:if(r=s.memoizedState,t===null||t.memoizedState!==null){if(o=sa(s),r!==null){if(t===null){if(!o)throw Error(a(318));if(t=s.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(a(557));t[ae]=s}else xi(),(s.flags&128)===0&&(s.memoizedState=null),s.flags|=4;Ze(s),t=!1}else r=Eu(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=r),t=!0;if(!t)return s.flags&256?(rn(s),s):(rn(s),null);if((s.flags&128)!==0)throw Error(a(558))}return Ze(s),null;case 13:if(o=s.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(h=sa(s),o!==null&&o.dehydrated!==null){if(t===null){if(!h)throw Error(a(318));if(h=s.memoizedState,h=h!==null?h.dehydrated:null,!h)throw Error(a(317));h[ae]=s}else xi(),(s.flags&128)===0&&(s.memoizedState=null),s.flags|=4;Ze(s),h=!1}else h=Eu(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=h),h=!0;if(!h)return s.flags&256?(rn(s),s):(rn(s),null)}return rn(s),(s.flags&128)!==0?(s.lanes=r,s):(r=o!==null,t=t!==null&&t.memoizedState!==null,r&&(o=s.child,h=null,o.alternate!==null&&o.alternate.memoizedState!==null&&o.alternate.memoizedState.cachePool!==null&&(h=o.alternate.memoizedState.cachePool.pool),f=null,o.memoizedState!==null&&o.memoizedState.cachePool!==null&&(f=o.memoizedState.cachePool.pool),f!==h&&(o.flags|=2048)),r!==t&&r&&(s.child.flags|=8192),vl(s,s.updateQueue),Ze(s),null);case 4:return He(),t===null&&Lh(s.stateNode.containerInfo),Ze(s),null;case 10:return fs(s.type),Ze(s),null;case 19:if(H(ht),o=s.memoizedState,o===null)return Ze(s),null;if(h=(s.flags&128)!==0,f=o.rendering,f===null)if(h)Er(o,!1);else{if(ot!==0||t!==null&&(t.flags&128)!==0)for(t=s.child;t!==null;){if(f=rl(t),f!==null){for(s.flags|=128,Er(o,!1),t=f.updateQueue,s.updateQueue=t,vl(s,t),s.subtreeFlags=0,t=r,r=s.child;r!==null;)Gm(r,t),r=r.sibling;return W(ht,ht.current&1|2),Re&&hs(s,o.treeForkCount),s.child}t=t.sibling}o.tail!==null&&We()>Tl&&(s.flags|=128,h=!0,Er(o,!1),s.lanes=4194304)}else{if(!h)if(t=rl(f),t!==null){if(s.flags|=128,h=!0,t=t.updateQueue,s.updateQueue=t,vl(s,t),Er(o,!0),o.tail===null&&o.tailMode==="hidden"&&!f.alternate&&!Re)return Ze(s),null}else 2*We()-o.renderingStartTime>Tl&&r!==536870912&&(s.flags|=128,h=!0,Er(o,!1),s.lanes=4194304);o.isBackwards?(f.sibling=s.child,s.child=f):(t=o.last,t!==null?t.sibling=f:s.child=f,o.last=f)}return o.tail!==null?(t=o.tail,o.rendering=t,o.tail=t.sibling,o.renderingStartTime=We(),t.sibling=null,r=ht.current,W(ht,h?r&1|2:r&1),Re&&hs(s,o.treeForkCount),t):(Ze(s),null);case 22:case 23:return rn(s),zu(),o=s.memoizedState!==null,t!==null?t.memoizedState!==null!==o&&(s.flags|=8192):o&&(s.flags|=8192),o?(r&536870912)!==0&&(s.flags&128)===0&&(Ze(s),s.subtreeFlags&6&&(s.flags|=8192)):Ze(s),r=s.updateQueue,r!==null&&vl(s,r.retryQueue),r=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),o=null,s.memoizedState!==null&&s.memoizedState.cachePool!==null&&(o=s.memoizedState.cachePool.pool),o!==r&&(s.flags|=2048),t!==null&&H(Si),null;case 24:return r=null,t!==null&&(r=t.memoizedState.cache),s.memoizedState.cache!==r&&(s.flags|=2048),fs(mt),Ze(s),null;case 25:return null;case 30:return null}throw Error(a(156,s.tag))}function eS(t,s){switch(Su(s),s.tag){case 1:return t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 3:return fs(mt),He(),t=s.flags,(t&65536)!==0&&(t&128)===0?(s.flags=t&-65537|128,s):null;case 26:case 27:case 5:return jn(s),null;case 31:if(s.memoizedState!==null){if(rn(s),s.alternate===null)throw Error(a(340));xi()}return t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 13:if(rn(s),t=s.memoizedState,t!==null&&t.dehydrated!==null){if(s.alternate===null)throw Error(a(340));xi()}return t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 19:return H(ht),null;case 4:return He(),null;case 10:return fs(s.type),null;case 22:case 23:return rn(s),zu(),t!==null&&H(Si),t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 24:return fs(mt),null;case 25:return null;default:return null}}function vg(t,s){switch(Su(s),s.tag){case 3:fs(mt),He();break;case 26:case 27:case 5:jn(s);break;case 4:He();break;case 31:s.memoizedState!==null&&rn(s);break;case 13:rn(s);break;case 19:H(ht);break;case 10:fs(s.type);break;case 22:case 23:rn(s),zu(),t!==null&&H(Si);break;case 24:fs(mt)}}function Ar(t,s){try{var r=s.updateQueue,o=r!==null?r.lastEffect:null;if(o!==null){var h=o.next;r=h;do{if((r.tag&t)===t){o=void 0;var f=r.create,b=r.inst;o=f(),b.destroy=o}r=r.next}while(r!==h)}}catch(w){Ve(s,s.return,w)}}function qs(t,s,r){try{var o=s.updateQueue,h=o!==null?o.lastEffect:null;if(h!==null){var f=h.next;o=f;do{if((o.tag&t)===t){var b=o.inst,w=b.destroy;if(w!==void 0){b.destroy=void 0,h=s;var A=r,U=w;try{U()}catch($){Ve(h,A,$)}}}o=o.next}while(o!==f)}}catch($){Ve(s,s.return,$)}}function xg(t){var s=t.updateQueue;if(s!==null){var r=t.stateNode;try{up(s,r)}catch(o){Ve(t,t.return,o)}}}function wg(t,s,r){r.props=Ni(t.type,t.memoizedProps),r.state=t.memoizedState;try{r.componentWillUnmount()}catch(o){Ve(t,s,o)}}function jr(t,s){try{var r=t.ref;if(r!==null){switch(t.tag){case 26:case 27:case 5:var o=t.stateNode;break;case 30:o=t.stateNode;break;default:o=t.stateNode}typeof r=="function"?t.refCleanup=r(o):r.current=o}}catch(h){Ve(t,s,h)}}function Kn(t,s){var r=t.ref,o=t.refCleanup;if(r!==null)if(typeof o=="function")try{o()}catch(h){Ve(t,s,h)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof r=="function")try{r(null)}catch(h){Ve(t,s,h)}else r.current=null}function _g(t){var s=t.type,r=t.memoizedProps,o=t.stateNode;try{e:switch(s){case"button":case"input":case"select":case"textarea":r.autoFocus&&o.focus();break e;case"img":r.src?o.src=r.src:r.srcSet&&(o.srcset=r.srcSet)}}catch(h){Ve(t,t.return,h)}}function gh(t,s,r){try{var o=t.stateNode;_S(o,t.type,r,s),o[nt]=s}catch(h){Ve(t,t.return,h)}}function Sg(t){return t.tag===5||t.tag===3||t.tag===26||t.tag===27&&Js(t.type)||t.tag===4}function yh(t){e:for(;;){for(;t.sibling===null;){if(t.return===null||Sg(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.tag===27&&Js(t.type)||t.flags&2||t.child===null||t.tag===4)continue e;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function bh(t,s,r){var o=t.tag;if(o===5||o===6)t=t.stateNode,s?(r.nodeType===9?r.body:r.nodeName==="HTML"?r.ownerDocument.body:r).insertBefore(t,s):(s=r.nodeType===9?r.body:r.nodeName==="HTML"?r.ownerDocument.body:r,s.appendChild(t),r=r._reactRootContainer,r!=null||s.onclick!==null||(s.onclick=ls));else if(o!==4&&(o===27&&Js(t.type)&&(r=t.stateNode,s=null),t=t.child,t!==null))for(bh(t,s,r),t=t.sibling;t!==null;)bh(t,s,r),t=t.sibling}function xl(t,s,r){var o=t.tag;if(o===5||o===6)t=t.stateNode,s?r.insertBefore(t,s):r.appendChild(t);else if(o!==4&&(o===27&&Js(t.type)&&(r=t.stateNode),t=t.child,t!==null))for(xl(t,s,r),t=t.sibling;t!==null;)xl(t,s,r),t=t.sibling}function Tg(t){var s=t.stateNode,r=t.memoizedProps;try{for(var o=t.type,h=s.attributes;h.length;)s.removeAttributeNode(h[0]);Mt(s,o,r),s[ae]=t,s[nt]=r}catch(f){Ve(t,t.return,f)}}var bs=!1,yt=!1,vh=!1,Eg=typeof WeakSet=="function"?WeakSet:Set,jt=null;function tS(t,s){if(t=t.containerInfo,Vh=Hl,t=Lm(t),du(t)){if("selectionStart"in t)var r={start:t.selectionStart,end:t.selectionEnd};else e:{r=(r=t.ownerDocument)&&r.defaultView||window;var o=r.getSelection&&r.getSelection();if(o&&o.rangeCount!==0){r=o.anchorNode;var h=o.anchorOffset,f=o.focusNode;o=o.focusOffset;try{r.nodeType,f.nodeType}catch{r=null;break e}var b=0,w=-1,A=-1,U=0,$=0,I=t,z=null;t:for(;;){for(var V;I!==r||h!==0&&I.nodeType!==3||(w=b+h),I!==f||o!==0&&I.nodeType!==3||(A=b+o),I.nodeType===3&&(b+=I.nodeValue.length),(V=I.firstChild)!==null;)z=I,I=V;for(;;){if(I===t)break t;if(z===r&&++U===h&&(w=b),z===f&&++$===o&&(A=b),(V=I.nextSibling)!==null)break;I=z,z=I.parentNode}I=V}r=w===-1||A===-1?null:{start:w,end:A}}else r=null}r=r||{start:0,end:0}}else r=null;for(Hh={focusedElem:t,selectionRange:r},Hl=!1,jt=s;jt!==null;)if(s=jt,t=s.child,(s.subtreeFlags&1028)!==0&&t!==null)t.return=s,jt=t;else for(;jt!==null;){switch(s=jt,f=s.alternate,t=s.flags,s.tag){case 0:if((t&4)!==0&&(t=s.updateQueue,t=t!==null?t.events:null,t!==null))for(r=0;r title"))),Mt(f,o,r),f[ae]=t,At(f),o=f;break e;case"link":var b=Cy("link","href",h).get(o+(r.href||""));if(b){for(var w=0;wIe&&(b=Ie,Ie=ye,ye=b);var O=Bm(w,ye),j=Bm(w,Ie);if(O&&j&&(V.rangeCount!==1||V.anchorNode!==O.node||V.anchorOffset!==O.offset||V.focusNode!==j.node||V.focusOffset!==j.offset)){var B=I.createRange();B.setStart(O.node,O.offset),V.removeAllRanges(),ye>Ie?(V.addRange(B),V.extend(j.node,j.offset)):(B.setEnd(j.node,j.offset),V.addRange(B))}}}}for(I=[],V=w;V=V.parentNode;)V.nodeType===1&&I.push({element:V,left:V.scrollLeft,top:V.scrollTop});for(typeof w.focus=="function"&&w.focus(),w=0;wr?32:r,L.T=null,r=Ah,Ah=null;var f=Ks,b=Ss;if(_t=0,ya=Ks=null,Ss=0,(ze&6)!==0)throw Error(a(331));var w=ze;if(ze|=4,Ug(f.current),Dg(f,f.current,b,r),ze=w,Dr(0,!1),$t&&typeof $t.onPostCommitFiberRoot=="function")try{$t.onPostCommitFiberRoot(as,f)}catch{}return!0}finally{K.p=h,L.T=o,ey(t,s)}}function ny(t,s,r){s=yn(r,s),s=ah(t.stateNode,s,2),t=Vs(t,s,2),t!==null&&(fi(t,2),Yn(t))}function Ve(t,s,r){if(t.tag===3)ny(t,t,r);else for(;s!==null;){if(s.tag===3){ny(s,t,r);break}else if(s.tag===1){var o=s.stateNode;if(typeof s.type.getDerivedStateFromError=="function"||typeof o.componentDidCatch=="function"&&(Gs===null||!Gs.has(o))){t=yn(r,t),r=sg(2),o=Vs(s,r,2),o!==null&&(ig(r,o,s,t),fi(o,2),Yn(o));break}}s=s.return}}function Rh(t,s,r){var o=t.pingCache;if(o===null){o=t.pingCache=new iS;var h=new Set;o.set(s,h)}else h=o.get(s),h===void 0&&(h=new Set,o.set(s,h));h.has(r)||(_h=!0,h.add(r),t=cS.bind(null,t,s,r),s.then(t,t))}function cS(t,s,r){var o=t.pingCache;o!==null&&o.delete(s),t.pingedLanes|=t.suspendedLanes&r,t.warmLanes&=~r,Ke===t&&(je&r)===r&&(ot===4||ot===3&&(je&62914560)===je&&300>We()-Sl?(ze&2)===0&&ba(t,0):Sh|=r,ga===je&&(ga=0)),Yn(t)}function sy(t,s){s===0&&(s=Za()),t=bi(t,s),t!==null&&(fi(t,s),Yn(t))}function uS(t){var s=t.memoizedState,r=0;s!==null&&(r=s.retryLane),sy(t,r)}function hS(t,s){var r=0;switch(t.tag){case 31:case 13:var o=t.stateNode,h=t.memoizedState;h!==null&&(r=h.retryLane);break;case 19:o=t.stateNode;break;case 22:o=t.stateNode._retryCache;break;default:throw Error(a(314))}o!==null&&o.delete(s),sy(t,r)}function dS(t,s){return xt(t,s)}var Rl=null,xa=null,Ch=!1,Cl=!1,Oh=!1,Xs=0;function Yn(t){t!==xa&&t.next===null&&(xa===null?Rl=xa=t:xa=xa.next=t),Cl=!0,Ch||(Ch=!0,mS())}function Dr(t,s){if(!Oh&&Cl){Oh=!0;do for(var r=!1,o=Rl;o!==null;){if(t!==0){var h=o.pendingLanes;if(h===0)var f=0;else{var b=o.suspendedLanes,w=o.pingedLanes;f=(1<<31-Lt(42|t)+1)-1,f&=h&~(b&~w),f=f&201326741?f&201326741|1:f?f|2:0}f!==0&&(r=!0,oy(o,f))}else f=je,f=qi(o,o===Ke?f:0,o.cancelPendingCommit!==null||o.timeoutHandle!==-1),(f&3)===0||di(o,f)||(r=!0,oy(o,f));o=o.next}while(r);Oh=!1}}function fS(){iy()}function iy(){Cl=Ch=!1;var t=0;Xs!==0&&TS()&&(t=Xs);for(var s=We(),r=null,o=Rl;o!==null;){var h=o.next,f=ay(o,s);f===0?(o.next=null,r===null?Rl=h:r.next=h,h===null&&(xa=r)):(r=o,(t!==0||(f&3)!==0)&&(Cl=!0)),o=h}_t!==0&&_t!==5||Dr(t),Xs!==0&&(Xs=0)}function ay(t,s){for(var r=t.suspendedLanes,o=t.pingedLanes,h=t.expirationTimes,f=t.pendingLanes&-62914561;0w)break;var $=A.transferSize,I=A.initiatorType;$&&py(I)&&(A=A.responseEnd,b+=$*(A"u"?null:document;function jy(t,s,r){var o=wa;if(o&&typeof s=="string"&&s){var h=pn(s);h='link[rel="'+t+'"][href="'+h+'"]',typeof r=="string"&&(h+='[crossorigin="'+r+'"]'),Ay.has(h)||(Ay.add(h),t={rel:t,crossOrigin:r,href:s},o.querySelector(h)===null&&(s=o.createElement("link"),Mt(s,"link",t),At(s),o.head.appendChild(s)))}}function DS(t){Ts.D(t),jy("dns-prefetch",t,null)}function MS(t,s){Ts.C(t,s),jy("preconnect",t,s)}function BS(t,s,r){Ts.L(t,s,r);var o=wa;if(o&&t&&s){var h='link[rel="preload"][as="'+pn(s)+'"]';s==="image"&&r&&r.imageSrcSet?(h+='[imagesrcset="'+pn(r.imageSrcSet)+'"]',typeof r.imageSizes=="string"&&(h+='[imagesizes="'+pn(r.imageSizes)+'"]')):h+='[href="'+pn(t)+'"]';var f=h;switch(s){case"style":f=_a(t);break;case"script":f=Sa(t)}Sn.has(f)||(t=v({rel:"preload",href:s==="image"&&r&&r.imageSrcSet?void 0:t,as:s},r),Sn.set(f,t),o.querySelector(h)!==null||s==="style"&&o.querySelector(Lr(f))||s==="script"&&o.querySelector(zr(f))||(s=o.createElement("link"),Mt(s,"link",t),At(s),o.head.appendChild(s)))}}function US(t,s){Ts.m(t,s);var r=wa;if(r&&t){var o=s&&typeof s.as=="string"?s.as:"script",h='link[rel="modulepreload"][as="'+pn(o)+'"][href="'+pn(t)+'"]',f=h;switch(o){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":f=Sa(t)}if(!Sn.has(f)&&(t=v({rel:"modulepreload",href:t},s),Sn.set(f,t),r.querySelector(h)===null)){switch(o){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(r.querySelector(zr(f)))return}o=r.createElement("link"),Mt(o,"link",t),At(o),r.head.appendChild(o)}}}function LS(t,s,r){Ts.S(t,s,r);var o=wa;if(o&&t){var h=Fi(o).hoistableStyles,f=_a(t);s=s||"default";var b=h.get(f);if(!b){var w={loading:0,preload:null};if(b=o.querySelector(Lr(f)))w.loading=5;else{t=v({rel:"stylesheet",href:t,"data-precedence":s},r),(r=Sn.get(f))&&Yh(t,r);var A=b=o.createElement("link");At(A),Mt(A,"link",t),A._p=new Promise(function(U,$){A.onload=U,A.onerror=$}),A.addEventListener("load",function(){w.loading|=1}),A.addEventListener("error",function(){w.loading|=2}),w.loading|=4,Ul(b,s,o)}b={type:"stylesheet",instance:b,count:1,state:w},h.set(f,b)}}}function zS(t,s){Ts.X(t,s);var r=wa;if(r&&t){var o=Fi(r).hoistableScripts,h=Sa(t),f=o.get(h);f||(f=r.querySelector(zr(h)),f||(t=v({src:t,async:!0},s),(s=Sn.get(h))&&Xh(t,s),f=r.createElement("script"),At(f),Mt(f,"link",t),r.head.appendChild(f)),f={type:"script",instance:f,count:1,state:null},o.set(h,f))}}function PS(t,s){Ts.M(t,s);var r=wa;if(r&&t){var o=Fi(r).hoistableScripts,h=Sa(t),f=o.get(h);f||(f=r.querySelector(zr(h)),f||(t=v({src:t,async:!0,type:"module"},s),(s=Sn.get(h))&&Xh(t,s),f=r.createElement("script"),At(f),Mt(f,"link",t),r.head.appendChild(f)),f={type:"script",instance:f,count:1,state:null},o.set(h,f))}}function Ny(t,s,r,o){var h=(h=re.current)?Bl(h):null;if(!h)throw Error(a(446));switch(t){case"meta":case"title":return null;case"style":return typeof r.precedence=="string"&&typeof r.href=="string"?(s=_a(r.href),r=Fi(h).hoistableStyles,o=r.get(s),o||(o={type:"style",instance:null,count:0,state:null},r.set(s,o)),o):{type:"void",instance:null,count:0,state:null};case"link":if(r.rel==="stylesheet"&&typeof r.href=="string"&&typeof r.precedence=="string"){t=_a(r.href);var f=Fi(h).hoistableStyles,b=f.get(t);if(b||(h=h.ownerDocument||h,b={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},f.set(t,b),(f=h.querySelector(Lr(t)))&&!f._p&&(b.instance=f,b.state.loading=5),Sn.has(t)||(r={rel:"preload",as:"style",href:r.href,crossOrigin:r.crossOrigin,integrity:r.integrity,media:r.media,hrefLang:r.hrefLang,referrerPolicy:r.referrerPolicy},Sn.set(t,r),f||VS(h,t,r,b.state))),s&&o===null)throw Error(a(528,""));return b}if(s&&o!==null)throw Error(a(529,""));return null;case"script":return s=r.async,r=r.src,typeof r=="string"&&s&&typeof s!="function"&&typeof s!="symbol"?(s=Sa(r),r=Fi(h).hoistableScripts,o=r.get(s),o||(o={type:"script",instance:null,count:0,state:null},r.set(s,o)),o):{type:"void",instance:null,count:0,state:null};default:throw Error(a(444,t))}}function _a(t){return'href="'+pn(t)+'"'}function Lr(t){return'link[rel="stylesheet"]['+t+"]"}function ky(t){return v({},t,{"data-precedence":t.precedence,precedence:null})}function VS(t,s,r,o){t.querySelector('link[rel="preload"][as="style"]['+s+"]")?o.loading=1:(s=t.createElement("link"),o.preload=s,s.addEventListener("load",function(){return o.loading|=1}),s.addEventListener("error",function(){return o.loading|=2}),Mt(s,"link",r),At(s),t.head.appendChild(s))}function Sa(t){return'[src="'+pn(t)+'"]'}function zr(t){return"script[async]"+t}function Ry(t,s,r){if(s.count++,s.instance===null)switch(s.type){case"style":var o=t.querySelector('style[data-href~="'+pn(r.href)+'"]');if(o)return s.instance=o,At(o),o;var h=v({},r,{"data-href":r.href,"data-precedence":r.precedence,href:null,precedence:null});return o=(t.ownerDocument||t).createElement("style"),At(o),Mt(o,"style",h),Ul(o,r.precedence,t),s.instance=o;case"stylesheet":h=_a(r.href);var f=t.querySelector(Lr(h));if(f)return s.state.loading|=4,s.instance=f,At(f),f;o=ky(r),(h=Sn.get(h))&&Yh(o,h),f=(t.ownerDocument||t).createElement("link"),At(f);var b=f;return b._p=new Promise(function(w,A){b.onload=w,b.onerror=A}),Mt(f,"link",o),s.state.loading|=4,Ul(f,r.precedence,t),s.instance=f;case"script":return f=Sa(r.src),(h=t.querySelector(zr(f)))?(s.instance=h,At(h),h):(o=r,(h=Sn.get(f))&&(o=v({},r),Xh(o,h)),t=t.ownerDocument||t,h=t.createElement("script"),At(h),Mt(h,"link",o),t.head.appendChild(h),s.instance=h);case"void":return null;default:throw Error(a(443,s.type))}else s.type==="stylesheet"&&(s.state.loading&4)===0&&(o=s.instance,s.state.loading|=4,Ul(o,r.precedence,t));return s.instance}function Ul(t,s,r){for(var o=r.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),h=o.length?o[o.length-1]:null,f=h,b=0;b title"):null)}function HS(t,s,r){if(r===1||s.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof s.precedence!="string"||typeof s.href!="string"||s.href==="")break;return!0;case"link":if(typeof s.rel!="string"||typeof s.href!="string"||s.href===""||s.onLoad||s.onError)break;switch(s.rel){case"stylesheet":return t=s.disabled,typeof s.precedence=="string"&&t==null;default:return!0}case"script":if(s.async&&typeof s.async!="function"&&typeof s.async!="symbol"&&!s.onLoad&&!s.onError&&s.src&&typeof s.src=="string")return!0}return!1}function Dy(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function $S(t,s,r,o){if(r.type==="stylesheet"&&(typeof o.media!="string"||matchMedia(o.media).matches!==!1)&&(r.state.loading&4)===0){if(r.instance===null){var h=_a(o.href),f=s.querySelector(Lr(h));if(f){s=f._p,s!==null&&typeof s=="object"&&typeof s.then=="function"&&(t.count++,t=zl.bind(t),s.then(t,t)),r.state.loading|=4,r.instance=f,At(f);return}f=s.ownerDocument||s,o=ky(o),(h=Sn.get(h))&&Yh(o,h),f=f.createElement("link"),At(f);var b=f;b._p=new Promise(function(w,A){b.onload=w,b.onerror=A}),Mt(f,"link",o),r.instance=f}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(r,s),(s=r.state.preload)&&(r.state.loading&3)===0&&(t.count++,r=zl.bind(t),s.addEventListener("load",r),s.addEventListener("error",r))}}var Jh=0;function qS(t,s){return t.stylesheets&&t.count===0&&Vl(t,t.stylesheets),0Jh?50:800)+s);return t.unsuspend=r,function(){t.unsuspend=null,clearTimeout(o),clearTimeout(h)}}:null}function zl(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Vl(this,this.stylesheets);else if(this.unsuspend){var t=this.unsuspend;this.unsuspend=null,t()}}}var Pl=null;function Vl(t,s){t.stylesheets=null,t.unsuspend!==null&&(t.count++,Pl=new Map,s.forEach(FS,t),Pl=null,zl.call(t))}function FS(t,s){if(!(s.state.loading&4)){var r=Pl.get(t);if(r)var o=r.get(null);else{r=new Map,Pl.set(t,r);for(var h=t.querySelectorAll("link[data-precedence],style[data-precedence]"),f=0;f"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}return n(),ad.exports=r1(),ad.exports}var l1=o1();const Ef=D.createContext({});function Af(n){const e=D.useRef(null);return e.current===null&&(e.current=n()),e.current}const c1=typeof window<"u",jf=c1?D.useLayoutEffect:D.useEffect,Pc=D.createContext(null);function Nf(n,e){n.indexOf(e)===-1&&n.push(e)}function vc(n,e){const i=n.indexOf(e);i>-1&&n.splice(i,1)}const ts=(n,e,i)=>i>e?e:i{};const oi={},Av=n=>/^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(n),jv=n=>typeof n=="object"&&n!==null,Nv=n=>/^0[^.\s]+$/u.test(n);function kv(n){let e;return()=>(e===void 0&&(e=n()),e)}const An=n=>n,To=(...n)=>n.reduce((e,i)=>a=>i(e(a))),lo=(n,e,i)=>{const a=e-n;return a?(i-n)/a:1};class Rf{constructor(){this.subscriptions=[]}add(e){return Nf(this.subscriptions,e),()=>vc(this.subscriptions,e)}notify(e,i,a){const l=this.subscriptions.length;if(l)if(l===1)this.subscriptions[0](e,i,a);else for(let c=0;cn*1e3,En=n=>n/1e3,Rv=(n,e)=>e?n*(1e3/e):0,Cv=(n,e,i)=>(((1-3*i+3*e)*n+(3*i-6*e))*n+3*e)*n,u1=1e-7,h1=12;function d1(n,e,i,a,l){let c,u,d=0;do u=e+(i-e)/2,c=Cv(u,a,l)-n,c>0?i=u:e=u;while(Math.abs(c)>u1&&++dd1(c,0,1,n,i);return c=>c===0||c===1?c:Cv(l(c),e,a)}const Ov=n=>e=>e<=.5?n(2*e)/2:(2-n(2*(1-e)))/2,Dv=n=>e=>1-n(1-e),Mv=Eo(.33,1.53,.69,.99),Cf=Dv(Mv),Bv=Ov(Cf),Uv=n=>n>=1?1:(n*=2)<1?.5*Cf(n):.5*(2-Math.pow(2,-10*(n-1))),Of=n=>1-Math.sin(Math.acos(n)),Lv=Dv(Of),zv=Ov(Of),f1=Eo(.42,0,1,1),m1=Eo(0,0,.58,1),Pv=Eo(.42,0,.58,1),p1=n=>Array.isArray(n)&&typeof n[0]!="number",Vv=n=>Array.isArray(n)&&typeof n[0]=="number",g1={linear:An,easeIn:f1,easeInOut:Pv,easeOut:m1,circIn:Of,circInOut:zv,circOut:Lv,backIn:Cf,backInOut:Bv,backOut:Mv,anticipate:Uv},y1=n=>typeof n=="string",s0=n=>{if(Vv(n)){kf(n.length===4);const[e,i,a,l]=n;return Eo(e,i,a,l)}else if(y1(n))return g1[n];return n},Yl=["setup","read","resolveKeyframes","preUpdate","update","preRender","render","postRender"];function b1(n){let e=new Set,i=new Set,a=!1,l=!1;const c=new WeakSet;let u={delta:0,timestamp:0,isProcessing:!1};function d(p){c.has(p)&&(m.schedule(p),n()),p(u)}const m={schedule:(p,y=!1,v=!1)=>{const _=v&&a?e:i;return y&&c.add(p),_.add(p),p},cancel:p=>{i.delete(p),c.delete(p)},process:p=>{if(u=p,a){l=!0;return}a=!0;const y=e;e=i,i=y,e.forEach(d),e.clear(),a=!1,l&&(l=!1,m.process(p))}};return m}const v1=40;function Hv(n,e){let i=!1,a=!0;const l={delta:0,timestamp:0,isProcessing:!1},c=()=>i=!0,u=Yl.reduce((N,P)=>(N[P]=b1(c),N),{}),{setup:d,read:m,resolveKeyframes:p,preUpdate:y,update:v,preRender:x,render:_,postRender:S}=u,T=()=>{const N=oi.useManualTiming,P=N?l.timestamp:performance.now();i=!1,N||(l.delta=a?1e3/60:Math.max(Math.min(P-l.timestamp,v1),1)),l.timestamp=P,l.isProcessing=!0,d.process(l),m.process(l),p.process(l),y.process(l),v.process(l),x.process(l),_.process(l),S.process(l),l.isProcessing=!1,i&&e&&(a=!1,n(T))},k=()=>{i=!0,a=!0,l.isProcessing||n(T)};return{schedule:Yl.reduce((N,P)=>{const G=u[P];return N[P]=(X,q=!1,Y=!1)=>(i||k(),G.schedule(X,q,Y)),N},{}),cancel:N=>{for(let P=0;P(uc===void 0&&Ft.set(Bt.isProcessing||oi.useManualTiming?Bt.timestamp:performance.now()),uc),set:n=>{uc=n,queueMicrotask(x1)}},$v=n=>e=>typeof e=="string"&&e.startsWith(n),qv=$v("--"),w1=$v("var(--"),Df=n=>w1(n)?_1.test(n.split("/*")[0].trim()):!1,_1=/var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;function i0(n){return typeof n!="string"?!1:n.split("/*")[0].includes("var(--")}const Ya={test:n=>typeof n=="number",parse:parseFloat,transform:n=>n},co={...Ya,transform:n=>ts(0,1,n)},Xl={...Ya,default:1},eo=n=>Math.round(n*1e5)/1e5,Mf=/-?(?:\d+(?:\.\d+)?|\.\d+)/gu;function S1(n){return n==null}const T1=/^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu,Bf=(n,e)=>i=>!!(typeof i=="string"&&T1.test(i)&&i.startsWith(n)||e&&!S1(i)&&Object.prototype.hasOwnProperty.call(i,e)),Fv=(n,e,i)=>a=>{if(typeof a!="string")return a;const[l,c,u,d]=a.match(Mf);return{[n]:parseFloat(l),[e]:parseFloat(c),[i]:parseFloat(u),alpha:d!==void 0?parseFloat(d):1}},E1=n=>ts(0,255,n),ud={...Ya,transform:n=>Math.round(E1(n))},Ui={test:Bf("rgb","red"),parse:Fv("red","green","blue"),transform:({red:n,green:e,blue:i,alpha:a=1})=>"rgba("+ud.transform(n)+", "+ud.transform(e)+", "+ud.transform(i)+", "+eo(co.transform(a))+")"};function A1(n){let e="",i="",a="",l="";return n.length>5?(e=n.substring(1,3),i=n.substring(3,5),a=n.substring(5,7),l=n.substring(7,9)):(e=n.substring(1,2),i=n.substring(2,3),a=n.substring(3,4),l=n.substring(4,5),e+=e,i+=i,a+=a,l+=l),{red:parseInt(e,16),green:parseInt(i,16),blue:parseInt(a,16),alpha:l?parseInt(l,16)/255:1}}const Ld={test:Bf("#"),parse:A1,transform:Ui.transform},Ao=n=>({test:e=>typeof e=="string"&&e.endsWith(n)&&e.split(" ").length===1,parse:parseFloat,transform:e=>`${e}${n}`}),As=Ao("deg"),es=Ao("%"),ce=Ao("px"),j1=Ao("vh"),N1=Ao("vw"),a0={...es,parse:n=>es.parse(n)/100,transform:n=>es.transform(n*100)},La={test:Bf("hsl","hue"),parse:Fv("hue","saturation","lightness"),transform:({hue:n,saturation:e,lightness:i,alpha:a=1})=>"hsla("+Math.round(n)+", "+es.transform(eo(e))+", "+es.transform(eo(i))+", "+eo(co.transform(a))+")"},vt={test:n=>Ui.test(n)||Ld.test(n)||La.test(n),parse:n=>Ui.test(n)?Ui.parse(n):La.test(n)?La.parse(n):Ld.parse(n),transform:n=>typeof n=="string"?n:n.hasOwnProperty("red")?Ui.transform(n):La.transform(n),getAnimatableNone:n=>{const e=vt.parse(n);return e.alpha=0,vt.transform(e)}},k1=/(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;function R1(n){var e,i;return isNaN(n)&&typeof n=="string"&&(((e=n.match(Mf))==null?void 0:e.length)||0)+(((i=n.match(k1))==null?void 0:i.length)||0)>0}const Iv="number",Gv="color",C1="var",O1="var(",r0="${}",D1=/var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;function Ia(n){const e=n.toString(),i=[],a={color:[],number:[],var:[]},l=[];let c=0;const d=e.replace(D1,m=>(vt.test(m)?(a.color.push(c),l.push(Gv),i.push(vt.parse(m))):m.startsWith(O1)?(a.var.push(c),l.push(C1),i.push(m)):(a.number.push(c),l.push(Iv),i.push(parseFloat(m))),++c,r0)).split(r0);return{values:i,split:d,indexes:a,types:l}}function M1(n){return Ia(n).values}function Kv({split:n,types:e}){const i=n.length;return a=>{let l="";for(let c=0;ctypeof n=="number"?0:vt.test(n)?vt.getAnimatableNone(n):n,L1=(n,e)=>typeof n=="number"?e!=null&&e.trim().endsWith("/")?n:0:U1(n);function z1(n){const e=Ia(n);return Kv(e)(e.values.map((a,l)=>L1(a,e.split[l])))}const $n={test:R1,parse:M1,createTransformer:B1,getAnimatableNone:z1};function hd(n,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?n+(e-n)*6*i:i<1/2?e:i<2/3?n+(e-n)*(2/3-i)*6:n}function P1({hue:n,saturation:e,lightness:i,alpha:a}){n/=360,e/=100,i/=100;let l=0,c=0,u=0;if(!e)l=c=u=i;else{const d=i<.5?i*(1+e):i+e-i*e,m=2*i-d;l=hd(m,d,n+1/3),c=hd(m,d,n),u=hd(m,d,n-1/3)}return{red:Math.round(l*255),green:Math.round(c*255),blue:Math.round(u*255),alpha:a}}function xc(n,e){return i=>i>0?e:n}const Ye=(n,e,i)=>n+(e-n)*i,dd=(n,e,i)=>{const a=n*n,l=i*(e*e-a)+a;return l<0?0:Math.sqrt(l)},V1=[Ld,Ui,La],H1=n=>V1.find(e=>e.test(n));function o0(n){const e=H1(n);if(!e)return!1;let i=e.parse(n);return e===La&&(i=P1(i)),i}const l0=(n,e)=>{const i=o0(n),a=o0(e);if(!i||!a)return xc(n,e);const l={...i};return c=>(l.red=dd(i.red,a.red,c),l.green=dd(i.green,a.green,c),l.blue=dd(i.blue,a.blue,c),l.alpha=Ye(i.alpha,a.alpha,c),Ui.transform(l))},zd=new Set(["none","hidden"]);function $1(n,e){return zd.has(n)?i=>i<=0?n:e:i=>i>=1?e:n}function q1(n,e){return i=>Ye(n,e,i)}function Uf(n){return typeof n=="number"?q1:typeof n=="string"?Df(n)?xc:vt.test(n)?l0:G1:Array.isArray(n)?Yv:typeof n=="object"?vt.test(n)?l0:F1:xc}function Yv(n,e){const i=[...n],a=i.length,l=n.map((c,u)=>Uf(c)(c,e[u]));return c=>{for(let u=0;u{for(const c in a)i[c]=a[c](l);return i}}function I1(n,e){const i=[],a={color:0,var:0,number:0};for(let l=0;l{const i=$n.createTransformer(e),a=Ia(n),l=Ia(e);return a.indexes.var.length===l.indexes.var.length&&a.indexes.color.length===l.indexes.color.length&&a.indexes.number.length>=l.indexes.number.length?zd.has(n)&&!l.values.length||zd.has(e)&&!a.values.length?$1(n,e):To(Yv(I1(a,l),l.values),i):xc(n,e)};function Xv(n,e,i){return typeof n=="number"&&typeof e=="number"&&typeof i=="number"?Ye(n,e,i):Uf(n)(n,e)}const K1=n=>{const e=({timestamp:i})=>n(i);return{start:(i=!0)=>Xe.update(e,i),stop:()=>li(e),now:()=>Bt.isProcessing?Bt.timestamp:Ft.now()}},Jv=(n,e,i=10)=>{let a="";const l=Math.max(Math.round(e/i),2);for(let c=0;c=wc?1/0:e}function Y1(n,e=100,i){const a=i({...n,keyframes:[0,e]}),l=Math.min(Lf(a),wc);return{type:"keyframes",ease:c=>a.next(l*c).value/e,duration:En(l)}}const ct={stiffness:100,damping:10,mass:1,velocity:0,duration:800,bounce:.3,visualDuration:.3,restSpeed:{granular:.01,default:2},restDelta:{granular:.005,default:.5},minDuration:.01,maxDuration:10,minDamping:.05,maxDamping:1};function Pd(n,e){return n*Math.sqrt(1-e*e)}const X1=12;function J1(n,e,i){let a=i;for(let l=1;l{const y=p*u,v=y*n,x=y-i,_=Pd(p,u),S=Math.exp(-v);return fd-x/_*S},c=p=>{const v=p*u*n,x=v*i+i,_=Math.pow(u,2)*Math.pow(p,2)*n,S=Math.exp(-v),T=Pd(Math.pow(p,2),u);return(-l(p)+fd>0?-1:1)*((x-_)*S)/T}):(l=p=>{const y=Math.exp(-p*n),v=(p-i)*n+1;return-fd+y*v},c=p=>{const y=Math.exp(-p*n),v=(i-p)*(n*n);return y*v});const d=5/n,m=J1(l,c,d);if(n=dn(n),isNaN(m))return{stiffness:ct.stiffness,damping:ct.damping,duration:n};{const p=Math.pow(m,2)*a;return{stiffness:p,damping:u*2*Math.sqrt(a*p),duration:n}}}const Z1=["duration","bounce"],W1=["stiffness","damping","mass"];function c0(n,e){return e.some(i=>n[i]!==void 0)}function eT(n){let e={velocity:ct.velocity,stiffness:ct.stiffness,damping:ct.damping,mass:ct.mass,isResolvedFromDuration:!1,...n};if(!c0(n,W1)&&c0(n,Z1))if(e.velocity=0,n.visualDuration){const i=n.visualDuration,a=2*Math.PI/(i*1.2),l=a*a,c=2*ts(.05,1,1-(n.bounce||0))*Math.sqrt(l);e={...e,mass:ct.mass,stiffness:l,damping:c}}else{const i=Q1({...n,velocity:0});e={...e,...i,mass:ct.mass},e.isResolvedFromDuration=!0}return e}function _c(n=ct.visualDuration,e=ct.bounce){const i=typeof n!="object"?{visualDuration:n,keyframes:[0,1],bounce:e}:n;let{restSpeed:a,restDelta:l}=i;const c=i.keyframes[0],u=i.keyframes[i.keyframes.length-1],d={done:!1,value:c},{stiffness:m,damping:p,mass:y,duration:v,velocity:x,isResolvedFromDuration:_}=eT({...i,velocity:-En(i.velocity||0)}),S=x||0,T=p/(2*Math.sqrt(m*y)),k=u-c,R=En(Math.sqrt(m/y)),M=Math.abs(k)<5;a||(a=M?ct.restSpeed.granular:ct.restSpeed.default),l||(l=M?ct.restDelta.granular:ct.restDelta.default);let N,P,G,X,q,Y;if(T<1)G=Pd(R,T),X=(S+T*R*k)/G,N=J=>{const he=Math.exp(-T*R*J);return u-he*(X*Math.sin(G*J)+k*Math.cos(G*J))},q=T*R*X+k*G,Y=T*R*k-X*G,P=J=>Math.exp(-T*R*J)*(q*Math.sin(G*J)+Y*Math.cos(G*J));else if(T===1){N=he=>u-Math.exp(-R*he)*(k+(S+R*k)*he);const J=S+R*k;P=he=>Math.exp(-R*he)*(R*J*he-S)}else{const J=R*Math.sqrt(T*T-1);N=ve=>{const Ce=Math.exp(-T*R*ve),L=Math.min(J*ve,300);return u-Ce*((S+T*R*k)*Math.sinh(L)+J*k*Math.cosh(L))/J};const he=(S+T*R*k)/J,fe=T*R*he-k*J,Ae=T*R*k-he*J;P=ve=>{const Ce=Math.exp(-T*R*ve),L=Math.min(J*ve,300);return Ce*(fe*Math.sinh(L)+Ae*Math.cosh(L))}}const se={calculatedDuration:_&&v||null,velocity:J=>dn(P(J)),next:J=>{if(!_&&T<1){const fe=Math.exp(-T*R*J),Ae=Math.sin(G*J),ve=Math.cos(G*J),Ce=u-fe*(X*Ae+k*ve),L=dn(fe*(q*Ae+Y*ve));return d.done=Math.abs(L)<=a&&Math.abs(u-Ce)<=l,d.value=d.done?u:Ce,d}const he=N(J);if(_)d.done=J>=v;else{const fe=dn(P(J));d.done=Math.abs(fe)<=a&&Math.abs(u-he)<=l}return d.value=d.done?u:he,d},toString:()=>{const J=Math.min(Lf(se),wc),he=Jv(fe=>se.next(J*fe).value,J,30);return J+"ms "+he},toTransition:()=>{}};return se}_c.applyToOptions=n=>{const e=Y1(n,100,_c);return n.ease=e.ease,n.duration=dn(e.duration),n.type="keyframes",n};const tT=5;function Qv(n,e,i){const a=Math.max(e-tT,0);return Rv(i-n(a),e-a)}function Vd({keyframes:n,velocity:e=0,power:i=.8,timeConstant:a=325,bounceDamping:l=10,bounceStiffness:c=500,modifyTarget:u,min:d,max:m,restDelta:p=.5,restSpeed:y}){const v=n[0],x={done:!1,value:v},_=Y=>d!==void 0&&Ym,S=Y=>d===void 0?m:m===void 0||Math.abs(d-Y)-T*Math.exp(-Y/a),N=Y=>R+M(Y),P=Y=>{const se=M(Y),J=N(Y);x.done=Math.abs(se)<=p,x.value=x.done?R:J};let G,X;const q=Y=>{_(x.value)&&(G=Y,X=_c({keyframes:[x.value,S(x.value)],velocity:Qv(N,Y,x.value),damping:l,stiffness:c,restDelta:p,restSpeed:y}))};return q(0),{calculatedDuration:null,next:Y=>{let se=!1;return!X&&G===void 0&&(se=!0,P(Y),q(Y)),G!==void 0&&Y>=G?X.next(Y-G):(!se&&P(Y),x)}}}function nT(n,e,i){const a=[],l=i||oi.mix||Xv,c=n.length-1;for(let u=0;ue[0];if(c===2&&e[0]===e[1])return()=>e[1];const u=n[0]===n[1];n[0]>n[c-1]&&(n=[...n].reverse(),e=[...e].reverse());const d=nT(e,a,l),m=d.length,p=y=>{if(u&&y1)for(;vp(ts(n[0],n[c-1],y)):p}function iT(n,e){const i=n[n.length-1];for(let a=1;a<=e;a++){const l=lo(0,e,a);n.push(Ye(i,1,l))}}function aT(n){const e=[0];return iT(e,n.length-1),e}function rT(n,e){return n.map(i=>i*e)}function oT(n,e){return n.map(()=>e||Pv).splice(0,n.length-1)}function to({duration:n=300,keyframes:e,times:i,ease:a="easeInOut"}){const l=p1(a)?a.map(s0):s0(a),c={done:!1,value:e[0]},u=rT(i&&i.length===e.length?i:aT(e),n),d=sT(u,e,{ease:Array.isArray(l)?l:oT(e,l)});return{calculatedDuration:n,next:m=>(c.value=d(m),c.done=m>=n,c)}}const lT=n=>n!==null;function Vc(n,{repeat:e,repeatType:i="loop"},a,l=1){const c=n.filter(lT),d=l<0||e&&i!=="loop"&&e%2===1?0:c.length-1;return!d||a===void 0?c[d]:a}const cT={decay:Vd,inertia:Vd,tween:to,keyframes:to,spring:_c};function Zv(n){typeof n.type=="string"&&(n.type=cT[n.type])}class zf{constructor(){this.updateFinished()}get finished(){return this._finished}updateFinished(){this._finished=new Promise(e=>{this.resolve=e})}notifyFinished(){this.resolve()}then(e,i){return this.finished.then(e,i)}}const uT=n=>n/100;class Sc extends zf{constructor(e){super(),this.state="idle",this.startTime=null,this.isStopped=!1,this.currentTime=0,this.holdTime=null,this.playbackSpeed=1,this.delayState={done:!1,value:void 0},this.stop=()=>{var a,l;const{motionValue:i}=this.options;i&&i.updatedAt!==Ft.now()&&this.tick(Ft.now()),this.isStopped=!0,this.state!=="idle"&&(this.teardown(),(l=(a=this.options).onStop)==null||l.call(a))},this.options=e,this.initAnimation(),this.play(),e.autoplay===!1&&this.pause()}initAnimation(){const{options:e}=this;Zv(e);const{type:i=to,repeat:a=0,repeatDelay:l=0,repeatType:c,velocity:u=0}=e;let{keyframes:d}=e;const m=i||to;m!==to&&typeof d[0]!="number"&&(this.mixKeyframes=To(uT,Xv(d[0],d[1])),d=[0,100]);const p=m({...e,keyframes:d});c==="mirror"&&(this.mirroredGenerator=m({...e,keyframes:[...d].reverse(),velocity:-u})),p.calculatedDuration===null&&(p.calculatedDuration=Lf(p));const{calculatedDuration:y}=p;this.calculatedDuration=y,this.resolvedDuration=y+l,this.totalDuration=this.resolvedDuration*(a+1)-l,this.generator=p}updateTime(e){const i=Math.round(e-this.startTime)*this.playbackSpeed;this.holdTime!==null?this.currentTime=this.holdTime:this.currentTime=i}tick(e,i=!1){const{generator:a,totalDuration:l,mixKeyframes:c,mirroredGenerator:u,resolvedDuration:d,calculatedDuration:m}=this;if(this.startTime===null)return a.next(0);const{delay:p=0,keyframes:y,repeat:v,repeatType:x,repeatDelay:_,type:S,onUpdate:T,finalKeyframe:k}=this.options;this.speed>0?this.startTime=Math.min(this.startTime,e):this.speed<0&&(this.startTime=Math.min(e-l/this.speed,this.startTime)),i?this.currentTime=e:this.updateTime(e);const R=this.currentTime-p*(this.playbackSpeed>=0?1:-1),M=this.playbackSpeed>=0?R<0:R>l;this.currentTime=Math.max(R,0),this.state==="finished"&&this.holdTime===null&&(this.currentTime=l);let N=this.currentTime,P=a;if(v){const Y=Math.min(this.currentTime,l)/d;let se=Math.floor(Y),J=Y%1;!J&&Y>=1&&(J=1),J===1&&se--,se=Math.min(se,v+1),!!(se%2)&&(x==="reverse"?(J=1-J,_&&(J-=_/d)):x==="mirror"&&(P=u)),N=ts(0,1,J)*d}let G;M?(this.delayState.value=y[0],G=this.delayState):G=P.next(N),c&&!M&&(G.value=c(G.value));let{done:X}=G;!M&&m!==null&&(X=this.playbackSpeed>=0?this.currentTime>=l:this.currentTime<=0);const q=this.holdTime===null&&(this.state==="finished"||this.state==="running"&&X);return q&&S!==Vd&&(G.value=Vc(y,this.options,k,this.speed)),T&&T(G.value),q&&this.finish(),G}then(e,i){return this.finished.then(e,i)}get duration(){return En(this.calculatedDuration)}get iterationDuration(){const{delay:e=0}=this.options||{};return this.duration+En(e)}get time(){return En(this.currentTime)}set time(e){e=dn(e),this.currentTime=e,this.startTime===null||this.holdTime!==null||this.playbackSpeed===0?this.holdTime=e:this.driver&&(this.startTime=this.driver.now()-e/this.playbackSpeed),this.driver?this.driver.start(!1):(this.startTime=0,this.state="paused",this.holdTime=e,this.tick(e))}getGeneratorVelocity(){const e=this.currentTime;if(e<=0)return this.options.velocity||0;if(this.generator.velocity)return this.generator.velocity(e);const i=this.generator.next(e).value;return Qv(a=>this.generator.next(a).value,e,i)}get speed(){return this.playbackSpeed}set speed(e){const i=this.playbackSpeed!==e;i&&this.driver&&this.updateTime(Ft.now()),this.playbackSpeed=e,i&&this.driver&&(this.time=En(this.currentTime))}play(){var l,c;if(this.isStopped)return;const{driver:e=K1,startTime:i}=this.options;this.driver||(this.driver=e(u=>this.tick(u))),(c=(l=this.options).onPlay)==null||c.call(l);const a=this.driver.now();this.state==="finished"?(this.updateFinished(),this.startTime=a):this.holdTime!==null?this.startTime=a-this.holdTime:this.startTime||(this.startTime=i??a),this.state==="finished"&&this.speed<0&&(this.startTime+=this.calculatedDuration),this.holdTime=null,this.state="running",this.driver.start()}pause(){this.state="paused",this.updateTime(Ft.now()),this.holdTime=this.currentTime}complete(){this.state!=="running"&&this.play(),this.state="finished",this.holdTime=null}finish(){var e,i;this.notifyFinished(),this.teardown(),this.state="finished",(i=(e=this.options).onComplete)==null||i.call(e)}cancel(){var e,i;this.holdTime=null,this.startTime=0,this.tick(0),this.teardown(),(i=(e=this.options).onCancel)==null||i.call(e)}teardown(){this.state="idle",this.stopDriver(),this.startTime=this.holdTime=null}stopDriver(){this.driver&&(this.driver.stop(),this.driver=void 0)}sample(e){return this.startTime=0,this.tick(e,!0)}attachTimeline(e){var i;return this.options.allowFlatten&&(this.options.type="keyframes",this.options.ease="linear",this.initAnimation()),(i=this.driver)==null||i.stop(),e.observe(this)}}function hT(n){for(let e=1;en*180/Math.PI,Hd=n=>{const e=Li(Math.atan2(n[1],n[0]));return $d(e)},dT={x:4,y:5,translateX:4,translateY:5,scaleX:0,scaleY:3,scale:n=>(Math.abs(n[0])+Math.abs(n[3]))/2,rotate:Hd,rotateZ:Hd,skewX:n=>Li(Math.atan(n[1])),skewY:n=>Li(Math.atan(n[2])),skew:n=>(Math.abs(n[1])+Math.abs(n[2]))/2},$d=n=>(n=n%360,n<0&&(n+=360),n),u0=Hd,h0=n=>Math.sqrt(n[0]*n[0]+n[1]*n[1]),d0=n=>Math.sqrt(n[4]*n[4]+n[5]*n[5]),fT={x:12,y:13,z:14,translateX:12,translateY:13,translateZ:14,scaleX:h0,scaleY:d0,scale:n=>(h0(n)+d0(n))/2,rotateX:n=>$d(Li(Math.atan2(n[6],n[5]))),rotateY:n=>$d(Li(Math.atan2(-n[2],n[0]))),rotateZ:u0,rotate:u0,skewX:n=>Li(Math.atan(n[4])),skewY:n=>Li(Math.atan(n[1])),skew:n=>(Math.abs(n[1])+Math.abs(n[4]))/2};function qd(n){return n.includes("scale")?1:0}function Fd(n,e){if(!n||n==="none")return qd(e);const i=n.match(/^matrix3d\(([-\d.e\s,]+)\)$/u);let a,l;if(i)a=fT,l=i;else{const d=n.match(/^matrix\(([-\d.e\s,]+)\)$/u);a=dT,l=d}if(!l)return qd(e);const c=a[e],u=l[1].split(",").map(pT);return typeof c=="function"?c(u):u[c]}const mT=(n,e)=>{const{transform:i="none"}=getComputedStyle(n);return Fd(i,e)};function pT(n){return parseFloat(n.trim())}const Xa=["transformPerspective","x","y","z","translateX","translateY","translateZ","scale","scaleX","scaleY","rotate","rotateX","rotateY","rotateZ","skew","skewX","skewY"],Ja=new Set([...Xa,"pathRotation"]),f0=n=>n===Ya||n===ce,gT=new Set(["x","y","z"]),yT=Xa.filter(n=>!gT.has(n));function bT(n){const e=[];return yT.forEach(i=>{const a=n.getValue(i);a!==void 0&&(e.push([i,a.get()]),a.set(i.startsWith("scale")?1:0))}),e}const ri={width:({x:n},{paddingLeft:e="0",paddingRight:i="0",boxSizing:a})=>{const l=n.max-n.min;return a==="border-box"?l:l-parseFloat(e)-parseFloat(i)},height:({y:n},{paddingTop:e="0",paddingBottom:i="0",boxSizing:a})=>{const l=n.max-n.min;return a==="border-box"?l:l-parseFloat(e)-parseFloat(i)},top:(n,{top:e})=>parseFloat(e),left:(n,{left:e})=>parseFloat(e),bottom:({y:n},{top:e})=>parseFloat(e)+(n.max-n.min),right:({x:n},{left:e})=>parseFloat(e)+(n.max-n.min),x:(n,{transform:e})=>Fd(e,"x"),y:(n,{transform:e})=>Fd(e,"y")};ri.translateX=ri.x;ri.translateY=ri.y;const Pi=new Set;let Id=!1,Gd=!1,Kd=!1;function Wv(){if(Gd){const n=Array.from(Pi).filter(a=>a.needsMeasurement),e=new Set(n.map(a=>a.element)),i=new Map;e.forEach(a=>{const l=bT(a);l.length&&(i.set(a,l),a.render())}),n.forEach(a=>a.measureInitialState()),e.forEach(a=>{a.render();const l=i.get(a);l&&l.forEach(([c,u])=>{var d;(d=a.getValue(c))==null||d.set(u)})}),n.forEach(a=>a.measureEndState()),n.forEach(a=>{a.suspendedScrollY!==void 0&&window.scrollTo(0,a.suspendedScrollY)})}Gd=!1,Id=!1,Pi.forEach(n=>n.complete(Kd)),Pi.clear()}function ex(){Pi.forEach(n=>{n.readKeyframes(),n.needsMeasurement&&(Gd=!0)})}function vT(){Kd=!0,ex(),Wv(),Kd=!1}class Pf{constructor(e,i,a,l,c,u=!1){this.state="pending",this.isAsync=!1,this.needsMeasurement=!1,this.unresolvedKeyframes=[...e],this.onComplete=i,this.name=a,this.motionValue=l,this.element=c,this.isAsync=u}scheduleResolve(){this.state="scheduled",this.isAsync?(Pi.add(this),Id||(Id=!0,Xe.read(ex),Xe.resolveKeyframes(Wv))):(this.readKeyframes(),this.complete())}readKeyframes(){const{unresolvedKeyframes:e,name:i,element:a,motionValue:l}=this;if(e[0]===null){const c=l==null?void 0:l.get(),u=e[e.length-1];if(c!==void 0)e[0]=c;else if(a&&i){const d=a.readValue(i,u);d!=null&&(e[0]=d)}e[0]===void 0&&(e[0]=u),l&&c===void 0&&l.set(e[0])}hT(e)}setFinalKeyframe(){}measureInitialState(){}renderEndStyles(){}measureEndState(){}complete(e=!1){this.state="complete",this.onComplete(this.unresolvedKeyframes,this.finalKeyframe,e),Pi.delete(this)}cancel(){this.state==="scheduled"&&(Pi.delete(this),this.state="pending")}resume(){this.state==="pending"&&this.scheduleResolve()}}const xT=n=>n.startsWith("--");function tx(n,e,i){xT(e)?n.style.setProperty(e,i):n.style[e]=i}const wT={};function nx(n,e){const i=kv(n);return()=>wT[e]??i()}const _T=nx(()=>window.ScrollTimeline!==void 0,"scrollTimeline"),sx=nx(()=>{try{document.createElement("div").animate({opacity:0},{easing:"linear(0, 1)"})}catch{return!1}return!0},"linearEasing"),Xr=([n,e,i,a])=>`cubic-bezier(${n}, ${e}, ${i}, ${a})`,m0={linear:"linear",ease:"ease",easeIn:"ease-in",easeOut:"ease-out",easeInOut:"ease-in-out",circIn:Xr([0,.65,.55,1]),circOut:Xr([.55,0,1,.45]),backIn:Xr([.31,.01,.66,-.59]),backOut:Xr([.33,1.53,.69,.99])};function ix(n,e){if(n)return typeof n=="function"?sx()?Jv(n,e):"ease-out":Vv(n)?Xr(n):Array.isArray(n)?n.map(i=>ix(i,e)||m0.easeOut):m0[n]}function ST(n,e,i,{delay:a=0,duration:l=300,repeat:c=0,repeatType:u="loop",ease:d="easeOut",times:m}={},p=void 0){const y={[e]:i};m&&(y.offset=m);const v=ix(d,l);Array.isArray(v)&&(y.easing=v);const x={delay:a,duration:l,easing:Array.isArray(v)?"linear":v,fill:"both",iterations:c+1,direction:u==="reverse"?"alternate":"normal"};return p&&(x.pseudoElement=p),n.animate(y,x)}function ax(n){return typeof n=="function"&&"applyToOptions"in n}function TT({type:n,...e}){return ax(n)&&sx()?n.applyToOptions(e):(e.duration??(e.duration=300),e.ease??(e.ease="easeOut"),e)}class rx extends zf{constructor(e){if(super(),this.finishedTime=null,this.isStopped=!1,this.manualStartTime=null,!e)return;const{element:i,name:a,keyframes:l,pseudoElement:c,allowFlatten:u=!1,finalKeyframe:d,onComplete:m}=e;this.isPseudoElement=!!c,this.allowFlatten=u,this.options=e,kf(typeof e.type!="string");const p=TT(e);this.animation=ST(i,a,l,p,c),p.autoplay===!1&&this.animation.pause(),this.animation.onfinish=()=>{if(this.finishedTime=this.time,!c){const y=Vc(l,this.options,d,this.speed);this.updateMotionValue&&this.updateMotionValue(y),tx(i,a,y),this.animation.cancel()}m==null||m(),this.notifyFinished()}}play(){this.isStopped||(this.manualStartTime=null,this.animation.play(),this.state==="finished"&&this.updateFinished())}pause(){this.animation.pause()}complete(){var e,i;(i=(e=this.animation).finish)==null||i.call(e)}cancel(){try{this.animation.cancel()}catch{}}stop(){if(this.isStopped)return;this.isStopped=!0;const{state:e}=this;e==="idle"||e==="finished"||(this.updateMotionValue?this.updateMotionValue():this.commitStyles(),this.isPseudoElement||this.cancel())}commitStyles(){var i,a,l;const e=(i=this.options)==null?void 0:i.element;!this.isPseudoElement&&(e!=null&&e.isConnected)&&((l=(a=this.animation).commitStyles)==null||l.call(a))}get duration(){var i,a;const e=((a=(i=this.animation.effect)==null?void 0:i.getComputedTiming)==null?void 0:a.call(i).duration)||0;return En(Number(e))}get iterationDuration(){const{delay:e=0}=this.options||{};return this.duration+En(e)}get time(){return En(Number(this.animation.currentTime)||0)}set time(e){const i=this.finishedTime!==null;this.manualStartTime=null,this.finishedTime=null,this.animation.currentTime=dn(e),i&&this.animation.pause()}get speed(){return this.animation.playbackRate}set speed(e){e<0&&(this.finishedTime=null),this.animation.playbackRate=e}get state(){return this.finishedTime!==null?"finished":this.animation.playState}get startTime(){return this.manualStartTime??Number(this.animation.startTime)}set startTime(e){this.manualStartTime=this.animation.startTime=e}attachTimeline({timeline:e,rangeStart:i,rangeEnd:a,observe:l}){var c;return this.allowFlatten&&((c=this.animation.effect)==null||c.updateTiming({easing:"linear"})),this.animation.onfinish=null,e&&_T()?(this.animation.timeline=e,i&&(this.animation.rangeStart=i),a&&(this.animation.rangeEnd=a),An):l(this)}}const ox={anticipate:Uv,backInOut:Bv,circInOut:zv};function ET(n){return n in ox}function AT(n){typeof n.ease=="string"&&ET(n.ease)&&(n.ease=ox[n.ease])}const md=10;class jT extends rx{constructor(e){AT(e),Zv(e),super(e),e.startTime!==void 0&&e.autoplay!==!1&&(this.startTime=e.startTime),this.options=e}updateMotionValue(e){const{motionValue:i,onUpdate:a,onComplete:l,element:c,...u}=this.options;if(!i)return;if(e!==void 0){i.set(e);return}const d=new Sc({...u,autoplay:!1}),m=Math.max(md,Ft.now()-this.startTime),p=ts(0,md,m-md),y=d.sample(m).value,{name:v}=this.options;c&&v&&tx(c,v,y),i.setWithVelocity(d.sample(Math.max(0,m-p)).value,y,p),d.stop()}}const p0=(n,e)=>e==="zIndex"?!1:!!(typeof n=="number"||Array.isArray(n)||typeof n=="string"&&($n.test(n)||n==="0")&&!n.startsWith("url("));function NT(n){const e=n[0];if(n.length===1)return!0;for(let i=0;iObject.hasOwnProperty.call(Element.prototype,"animate"));function MT(n){var v;const{motionValue:e,name:i,repeatDelay:a,repeatType:l,damping:c,type:u,keyframes:d}=n;if(!(((v=e==null?void 0:e.owner)==null?void 0:v.current)instanceof HTMLElement))return!1;const{onUpdate:p,transformTemplate:y}=e.owner.getProps();return DT()&&i&&(lx.has(i)||OT.has(i)&&CT(d))&&(i!=="transform"||!y)&&!p&&!a&&l!=="mirror"&&c!==0&&u!=="inertia"}const BT=40;class UT extends zf{constructor({autoplay:e=!0,delay:i=0,type:a="keyframes",repeat:l=0,repeatDelay:c=0,repeatType:u="loop",keyframes:d,name:m,motionValue:p,element:y,...v}){var S;super(),this.stop=()=>{var T,k;this._animation&&(this._animation.stop(),(T=this.stopTimeline)==null||T.call(this)),(k=this.keyframeResolver)==null||k.cancel()},this.createdAt=Ft.now();const x={autoplay:e,delay:i,type:a,repeat:l,repeatDelay:c,repeatType:u,name:m,motionValue:p,element:y,...v},_=(y==null?void 0:y.KeyframeResolver)||Pf;this.keyframeResolver=new _(d,(T,k,R)=>this.onKeyframesResolved(T,k,x,!R),m,p,y),(S=this.keyframeResolver)==null||S.scheduleResolve()}onKeyframesResolved(e,i,a,l){var R,M;this.keyframeResolver=void 0;const{name:c,type:u,velocity:d,delay:m,isHandoff:p,onUpdate:y}=a;this.resolvedAt=Ft.now();let v=!0;kT(e,c,u,d)||(v=!1,(oi.instantAnimations||!m)&&(y==null||y(Vc(e,a,i))),e[0]=e[e.length-1],Yd(a),a.repeat=0);const _={startTime:l?this.resolvedAt?this.resolvedAt-this.createdAt>BT?this.resolvedAt:this.createdAt:this.createdAt:void 0,finalKeyframe:i,...a,keyframes:e},S=v&&!p&&MT(_),T=(M=(R=_.motionValue)==null?void 0:R.owner)==null?void 0:M.current;let k;if(S)try{k=new jT({..._,element:T})}catch{k=new Sc(_)}else k=new Sc(_);k.finished.then(()=>{this.notifyFinished()}).catch(An),this.pendingTimeline&&(this.stopTimeline=k.attachTimeline(this.pendingTimeline),this.pendingTimeline=void 0),this._animation=k}get finished(){return this._animation?this.animation.finished:this._finished}then(e,i){return this.finished.finally(e).then(()=>{})}get animation(){var e;return this._animation||((e=this.keyframeResolver)==null||e.resume(),vT()),this._animation}get duration(){return this.animation.duration}get iterationDuration(){return this.animation.iterationDuration}get time(){return this.animation.time}set time(e){this.animation.time=e}get speed(){return this.animation.speed}get state(){return this.animation.state}set speed(e){this.animation.speed=e}get startTime(){return this.animation.startTime}attachTimeline(e){return this._animation?this.stopTimeline=this.animation.attachTimeline(e):this.pendingTimeline=e,()=>this.stop()}play(){this.animation.play()}pause(){this.animation.pause()}complete(){this.animation.complete()}cancel(){var e;this._animation&&this.animation.cancel(),(e=this.keyframeResolver)==null||e.cancel()}}function cx(n,e,i,a=0,l=1){const c=Array.from(n).sort((p,y)=>p.sortNodePosition(y)).indexOf(e),u=n.size,d=(u-1)*a;return typeof i=="function"?i(c,u):l===1?c*a:d-c*a}const g0=30,LT=n=>!isNaN(parseFloat(n));class zT{constructor(e,i={}){this.canTrackVelocity=null,this.events={},this.updateAndNotify=a=>{var c;const l=Ft.now();if(this.updatedAt!==l&&this.setPrevFrameValue(),this.prev=this.current,this.setCurrent(a),this.current!==this.prev&&((c=this.events.change)==null||c.notify(this.current),this.dependents))for(const u of this.dependents)u.dirty()},this.hasAnimated=!1,this.setCurrent(e),this.owner=i.owner}setCurrent(e){this.current=e,this.updatedAt=Ft.now(),this.canTrackVelocity===null&&e!==void 0&&(this.canTrackVelocity=LT(this.current))}setPrevFrameValue(e=this.current){this.prevFrameValue=e,this.prevUpdatedAt=this.updatedAt}onChange(e){return this.on("change",e)}on(e,i){this.events[e]||(this.events[e]=new Rf);const a=this.events[e].add(i);return e==="change"?()=>{a(),Xe.read(()=>{this.events.change.getSize()||this.stop()})}:a}clearListeners(){for(const e in this.events)this.events[e].clear()}attach(e,i){this.passiveEffect=e,this.stopPassiveEffect=i}set(e){this.passiveEffect?this.passiveEffect(e,this.updateAndNotify):this.updateAndNotify(e)}setWithVelocity(e,i,a){this.set(i),this.prev=void 0,this.prevFrameValue=e,this.prevUpdatedAt=this.updatedAt-a}jump(e,i=!0){this.updateAndNotify(e),this.prev=e,this.prevUpdatedAt=this.prevFrameValue=void 0,i&&this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}dirty(){var e;(e=this.events.change)==null||e.notify(this.current)}addDependent(e){this.dependents||(this.dependents=new Set),this.dependents.add(e)}removeDependent(e){this.dependents&&this.dependents.delete(e)}get(){return this.current}getPrevious(){return this.prev}getVelocity(){const e=Ft.now();if(!this.canTrackVelocity||this.prevFrameValue===void 0||e-this.updatedAt>g0)return 0;const i=Math.min(this.updatedAt-this.prevUpdatedAt,g0);return Rv(parseFloat(this.current)-parseFloat(this.prevFrameValue),i)}start(e){return this.stop(),new Promise(i=>{this.hasAnimated=!0,this.animation=e(i),this.events.animationStart&&this.events.animationStart.notify()}).then(()=>{this.events.animationComplete&&this.events.animationComplete.notify(),this.clearAnimation()})}stop(){this.animation&&(this.animation.stop(),this.events.animationCancel&&this.events.animationCancel.notify()),this.clearAnimation()}isAnimating(){return!!this.animation}clearAnimation(){delete this.animation}destroy(){var e,i;(e=this.dependents)==null||e.clear(),(i=this.events.destroy)==null||i.notify(),this.clearListeners(),this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}}function Ga(n,e){return new zT(n,e)}function ux(n,e){if(n!=null&&n.inherit&&e){const{inherit:i,...a}=n;return{...e,...a}}return n}function Vf(n,e){const i=(n==null?void 0:n[e])??(n==null?void 0:n.default)??n;return i!==n?ux(i,n):i}const PT={type:"spring",stiffness:500,damping:25,restSpeed:10},VT=n=>({type:"spring",stiffness:550,damping:n===0?2*Math.sqrt(550):30,restSpeed:10}),HT={type:"keyframes",duration:.8},$T={type:"keyframes",ease:[.25,.1,.35,1],duration:.3},qT=(n,{keyframes:e})=>e.length>2?HT:Ja.has(n)?n.startsWith("scale")?VT(e[1]):PT:$T,FT=new Set(["when","delay","delayChildren","staggerChildren","staggerDirection","repeat","repeatType","repeatDelay","from","elapsed"]);function IT(n){for(const e in n)if(!FT.has(e))return!0;return!1}const Hf=(n,e,i,a={},l,c)=>u=>{const d=Vf(a,n)||{},m=d.delay||a.delay||0;let{elapsed:p=0}=a;p=p-dn(m);const y={keyframes:Array.isArray(i)?i:[null,i],ease:"easeOut",velocity:e.getVelocity(),...d,delay:-p,onUpdate:x=>{e.set(x),d.onUpdate&&d.onUpdate(x)},onComplete:()=>{u(),d.onComplete&&d.onComplete()},name:n,motionValue:e,element:c?void 0:l};IT(d)||Object.assign(y,qT(n,y)),y.duration&&(y.duration=dn(y.duration)),y.repeatDelay&&(y.repeatDelay=dn(y.repeatDelay)),y.from!==void 0&&(y.keyframes[0]=y.from);let v=!1;if((y.type===!1||y.duration===0&&!y.repeatDelay)&&(Yd(y),y.delay===0&&(v=!0)),(oi.instantAnimations||oi.skipAnimations||l!=null&&l.shouldSkipAnimations||d.skipAnimations)&&(v=!0,Yd(y),y.delay=0),y.allowFlatten=!d.type&&!d.ease,v&&!c&&e.get()!==void 0){const x=Vc(y.keyframes,d);if(x!==void 0){Xe.update(()=>{y.onUpdate(x),y.onComplete()});return}}return d.isSync?new Sc(y):new UT(y)},GT=/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;function KT(n){const e=GT.exec(n);if(!e)return[,];const[,i,a,l]=e;return[`--${i??a}`,l]}function hx(n,e,i=1){const[a,l]=KT(n);if(!a)return;const c=window.getComputedStyle(e).getPropertyValue(a);if(c){const u=c.trim();return Av(u)?parseFloat(u):u}return Df(l)?hx(l,e,i+1):l}function y0(n){const e=[{},{}];return n==null||n.values.forEach((i,a)=>{e[0][a]=i.get(),e[1][a]=i.getVelocity()}),e}function $f(n,e,i,a){if(typeof e=="function"){const[l,c]=y0(a);e=e(i!==void 0?i:n.custom,l,c)}if(typeof e=="string"&&(e=n.variants&&n.variants[e]),typeof e=="function"){const[l,c]=y0(a);e=e(i!==void 0?i:n.custom,l,c)}return e}function Vi(n,e,i){const a=n.getProps();return $f(a,e,i!==void 0?i:a.custom,n)}const dx=new Set(["width","height","top","left","right","bottom",...Xa]),Xd=n=>Array.isArray(n);function YT(n,e,i){n.hasValue(e)?n.getValue(e).set(i):n.addValue(e,Ga(i))}function XT(n){return Xd(n)?n[n.length-1]||0:n}function JT(n,e){const i=Vi(n,e);let{transitionEnd:a={},transition:l={},...c}=i||{};c={...c,...a};for(const u in c){const d=XT(c[u]);YT(n,u,d)}}const Ut=n=>!!(n&&n.getVelocity);function QT(n){return!!(Ut(n)&&n.add)}function Jd(n,e){const i=n.getValue("willChange");if(QT(i))return i.add(e);if(!i&&oi.WillChange){const a=new oi.WillChange("auto");n.addValue("willChange",a),a.add(e)}}function qf(n){return n.replace(/([A-Z])/g,e=>`-${e.toLowerCase()}`)}const ZT="framerAppearId",fx="data-"+qf(ZT);function mx(n){return n.props[fx]}function WT({protectedKeys:n,needsAnimating:e},i){const a=n.hasOwnProperty(i)&&e[i]!==!0;return e[i]=!1,a}function px(n,e,{delay:i=0,transitionOverride:a,type:l}={}){let{transition:c,transitionEnd:u,...d}=e;const m=n.getDefaultTransition();c=c?ux(c,m):m;const p=c==null?void 0:c.reduceMotion,y=c==null?void 0:c.skipAnimations;a&&(c=a);const v=[],x=l&&n.animationState&&n.animationState.getState()[l],_=c==null?void 0:c.path;_&&_.animateVisualElement(n,d,c,i,v);for(const S in d){const T=n.getValue(S,n.latestValues[S]??null),k=d[S];if(k===void 0||x&&WT(x,S))continue;const R={delay:i,...Vf(c||{},S)};y&&(R.skipAnimations=!0);const M=T.get();if(M!==void 0&&!T.isAnimating()&&!Array.isArray(k)&&k===M&&!R.velocity){Xe.update(()=>T.set(k));continue}let N=!1;if(window.MotionHandoffAnimation){const X=mx(n);if(X){const q=window.MotionHandoffAnimation(X,S,Xe);q!==null&&(R.startTime=q,N=!0)}}Jd(n,S);const P=p??n.shouldReduceMotion;T.start(Hf(S,T,k,P&&dx.has(S)?{type:!1}:R,n,N));const G=T.animation;G&&v.push(G)}if(u){const S=()=>Xe.update(()=>{u&&JT(n,u)});v.length?Promise.all(v).then(S):S()}return v}function Qd(n,e,i={}){var m;const a=Vi(n,e,i.type==="exit"?(m=n.presenceContext)==null?void 0:m.custom:void 0);let{transition:l=n.getDefaultTransition()||{}}=a||{};i.transitionOverride&&(l=i.transitionOverride);const c=a?()=>Promise.all(px(n,a,i)):()=>Promise.resolve(),u=n.variantChildren&&n.variantChildren.size?(p=0)=>{const{delayChildren:y=0,staggerChildren:v,staggerDirection:x}=l;return eE(n,e,p,y,v,x,i)}:()=>Promise.resolve(),{when:d}=l;if(d){const[p,y]=d==="beforeChildren"?[c,u]:[u,c];return p().then(()=>y())}else return Promise.all([c(),u(i.delay)])}function eE(n,e,i=0,a=0,l=0,c=1,u){const d=[];for(const m of n.variantChildren)m.notify("AnimationStart",e),d.push(Qd(m,e,{...u,delay:i+(typeof a=="function"?0:a)+cx(n.variantChildren,m,a,l,c)}).then(()=>m.notify("AnimationComplete",e)));return Promise.all(d)}function tE(n,e,i={}){n.notify("AnimationStart",e);let a;if(Array.isArray(e)){const l=e.map(c=>Qd(n,c,i));a=Promise.all(l)}else if(typeof e=="string")a=Qd(n,e,i);else{const l=typeof e=="function"?Vi(n,e,i.custom):e;a=Promise.all(px(n,l,i))}return a.then(()=>{n.notify("AnimationComplete",e)})}const nE={test:n=>n==="auto",parse:n=>n},gx=n=>e=>e.test(n),yx=[Ya,ce,es,As,N1,j1,nE],b0=n=>yx.find(gx(n));function sE(n){return typeof n=="number"?n===0:n!==null?n==="none"||n==="0"||Nv(n):!0}const iE=new Set(["brightness","contrast","saturate","opacity"]);function aE(n){const[e,i]=n.slice(0,-1).split("(");if(e==="drop-shadow")return n;const[a]=i.match(Mf)||[];if(!a)return n;const l=i.replace(a,"");let c=iE.has(e)?1:0;return a!==i&&(c*=100),e+"("+c+l+")"}const rE=/\b([a-z-]*)\(.*?\)/gu,Zd={...$n,getAnimatableNone:n=>{const e=n.match(rE);return e?e.map(aE).join(" "):n}},Wd={...$n,getAnimatableNone:n=>{const e=$n.parse(n);return $n.createTransformer(n)(e.map(a=>typeof a=="number"?0:typeof a=="object"?{...a,alpha:1}:a))}},v0={...Ya,transform:Math.round},oE={rotate:As,pathRotation:As,rotateX:As,rotateY:As,rotateZ:As,scale:Xl,scaleX:Xl,scaleY:Xl,scaleZ:Xl,skew:As,skewX:As,skewY:As,distance:ce,translateX:ce,translateY:ce,translateZ:ce,x:ce,y:ce,z:ce,perspective:ce,transformPerspective:ce,opacity:co,originX:a0,originY:a0,originZ:ce},Tc={borderWidth:ce,borderTopWidth:ce,borderRightWidth:ce,borderBottomWidth:ce,borderLeftWidth:ce,borderRadius:ce,borderTopLeftRadius:ce,borderTopRightRadius:ce,borderBottomRightRadius:ce,borderBottomLeftRadius:ce,width:ce,maxWidth:ce,height:ce,maxHeight:ce,top:ce,right:ce,bottom:ce,left:ce,inset:ce,insetBlock:ce,insetBlockStart:ce,insetBlockEnd:ce,insetInline:ce,insetInlineStart:ce,insetInlineEnd:ce,padding:ce,paddingTop:ce,paddingRight:ce,paddingBottom:ce,paddingLeft:ce,paddingBlock:ce,paddingBlockStart:ce,paddingBlockEnd:ce,paddingInline:ce,paddingInlineStart:ce,paddingInlineEnd:ce,margin:ce,marginTop:ce,marginRight:ce,marginBottom:ce,marginLeft:ce,marginBlock:ce,marginBlockStart:ce,marginBlockEnd:ce,marginInline:ce,marginInlineStart:ce,marginInlineEnd:ce,fontSize:ce,backgroundPositionX:ce,backgroundPositionY:ce,...oE,zIndex:v0,fillOpacity:co,strokeOpacity:co,numOctaves:v0},lE={...Tc,color:vt,backgroundColor:vt,outlineColor:vt,fill:vt,stroke:vt,borderColor:vt,borderTopColor:vt,borderRightColor:vt,borderBottomColor:vt,borderLeftColor:vt,filter:Zd,WebkitFilter:Zd,mask:Wd,WebkitMask:Wd},bx=n=>lE[n],cE=new Set([Zd,Wd]);function vx(n,e){let i=bx(n);return cE.has(i)||(i=$n),i.getAnimatableNone?i.getAnimatableNone(e):void 0}const uE=new Set(["auto","none","0"]);function hE(n,e,i){let a=0,l;for(;a{e.getValue(m).set(p)}),this.resolveNoneKeyframes()}}const Ff=["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"];function xx(n,e,i){if(n==null)return[];if(n instanceof EventTarget)return[n];if(typeof n=="string"){let a=document;const l=(i==null?void 0:i[n])??a.querySelectorAll(n);return l?Array.from(l):[]}return Array.from(n).filter(a=>a!=null)}const ef=(n,e)=>e&&typeof n=="number"?e.transform(n):n;function hc(n){return jv(n)&&"offsetHeight"in n&&!("ownerSVGElement"in n)}const{schedule:If}=Hv(queueMicrotask,!1),Ln={x:!1,y:!1};function wx(){return Ln.x||Ln.y}function fE(n){return n==="x"||n==="y"?Ln[n]?null:(Ln[n]=!0,()=>{Ln[n]=!1}):Ln.x||Ln.y?null:(Ln.x=Ln.y=!0,()=>{Ln.x=Ln.y=!1})}function _x(n,e){const i=xx(n),a=new AbortController,l={passive:!0,...e,signal:a.signal};return[i,l,()=>a.abort()]}function mE(n){return!(n.pointerType==="touch"||wx())}function pE(n,e,i={}){const[a,l,c]=_x(n,i);return a.forEach(u=>{let d=!1,m=!1,p;const y=()=>{u.removeEventListener("pointerleave",S)},v=k=>{p&&(p(k),p=void 0),y()},x=k=>{d=!1,window.removeEventListener("pointerup",x),window.removeEventListener("pointercancel",x),m&&(m=!1,v(k))},_=()=>{d=!0,window.addEventListener("pointerup",x,l),window.addEventListener("pointercancel",x,l)},S=k=>{if(k.pointerType!=="touch"){if(d){m=!0;return}v(k)}},T=k=>{if(!mE(k))return;m=!1;const R=e(u,k);typeof R=="function"&&(p=R,u.addEventListener("pointerleave",S,l))};u.addEventListener("pointerenter",T,l),u.addEventListener("pointerdown",_,l)}),c}const Sx=(n,e)=>e?n===e?!0:Sx(n,e.parentElement):!1,Gf=n=>n.pointerType==="mouse"?typeof n.button!="number"||n.button<=0:n.isPrimary!==!1,gE=new Set(["BUTTON","INPUT","SELECT","TEXTAREA","A"]);function yE(n){return gE.has(n.tagName)||n.isContentEditable===!0}const bE=new Set(["INPUT","SELECT","TEXTAREA"]);function vE(n){return bE.has(n.tagName)||n.isContentEditable===!0}const dc=new WeakSet;function x0(n){return e=>{e.key==="Enter"&&n(e)}}function pd(n,e){n.dispatchEvent(new PointerEvent("pointer"+e,{isPrimary:!0,bubbles:!0}))}const xE=(n,e)=>{const i=n.currentTarget;if(!i)return;const a=x0(()=>{if(dc.has(i))return;pd(i,"down");const l=x0(()=>{pd(i,"up")}),c=()=>pd(i,"cancel");i.addEventListener("keyup",l,e),i.addEventListener("blur",c,e)});i.addEventListener("keydown",a,e),i.addEventListener("blur",()=>i.removeEventListener("keydown",a),e)};function w0(n){return Gf(n)&&!wx()}const _0=new WeakSet;function wE(n,e,i={}){const[a,l,c]=_x(n,i),u=d=>{const m=d.currentTarget;if(!w0(d)||_0.has(d))return;dc.add(m),i.stopPropagation&&_0.add(d);const p=e(m,d),y={...l,capture:!0},v=(S,T)=>{window.removeEventListener("pointerup",x,y),window.removeEventListener("pointercancel",_,y),dc.has(m)&&dc.delete(m),w0(S)&&typeof p=="function"&&p(S,{success:T})},x=S=>{v(S,m===window||m===document||i.useGlobalTarget||Sx(m,S.target))},_=S=>{v(S,!1)};window.addEventListener("pointerup",x,y),window.addEventListener("pointercancel",_,y)};return a.forEach(d=>{(i.useGlobalTarget?window:d).addEventListener("pointerdown",u,l),hc(d)&&(d.addEventListener("focus",p=>xE(p,l)),!yE(d)&&!d.hasAttribute("tabindex")&&(d.tabIndex=0))}),c}function Kf(n){return jv(n)&&"ownerSVGElement"in n}const fc=new WeakMap;let ni;const Tx=(n,e,i)=>(a,l)=>l&&l[0]?l[0][n+"Size"]:Kf(a)&&"getBBox"in a?a.getBBox()[e]:a[i],_E=Tx("inline","width","offsetWidth"),SE=Tx("block","height","offsetHeight");function TE({target:n,borderBoxSize:e}){var i;(i=fc.get(n))==null||i.forEach(a=>{a(n,{get width(){return _E(n,e)},get height(){return SE(n,e)}})})}function EE(n){n.forEach(TE)}function AE(){typeof ResizeObserver>"u"||(ni=new ResizeObserver(EE))}function jE(n,e){ni||AE();const i=xx(n);return i.forEach(a=>{let l=fc.get(a);l||(l=new Set,fc.set(a,l)),l.add(e),ni==null||ni.observe(a)}),()=>{i.forEach(a=>{const l=fc.get(a);l==null||l.delete(e),l!=null&&l.size||ni==null||ni.unobserve(a)})}}const mc=new Set;let za;function NE(){za=()=>{const n={get width(){return window.innerWidth},get height(){return window.innerHeight}};mc.forEach(e=>e(n))},window.addEventListener("resize",za)}function kE(n){return mc.add(n),za||NE(),()=>{mc.delete(n),!mc.size&&typeof za=="function"&&(window.removeEventListener("resize",za),za=void 0)}}function S0(n,e){return typeof n=="function"?kE(n):jE(n,e)}function RE(n){return Kf(n)&&n.tagName==="svg"}const CE=[...yx,vt,$n],OE=n=>CE.find(gx(n)),T0=()=>({translate:0,scale:1,origin:0,originPoint:0}),Pa=()=>({x:T0(),y:T0()}),E0=()=>({min:0,max:0}),St=()=>({x:E0(),y:E0()}),DE=new WeakMap;function Hc(n){return n!==null&&typeof n=="object"&&typeof n.start=="function"}function uo(n){return typeof n=="string"||Array.isArray(n)}const Yf=["animate","whileInView","whileFocus","whileHover","whileTap","whileDrag","exit"],Xf=["initial",...Yf];function $c(n){return Hc(n.animate)||Xf.some(e=>uo(n[e]))}function Ex(n){return!!($c(n)||n.variants)}function ME(n,e,i){for(const a in e){const l=e[a],c=i[a];if(Ut(l))n.addValue(a,l);else if(Ut(c))n.addValue(a,Ga(l,{owner:n}));else if(c!==l)if(n.hasValue(a)){const u=n.getValue(a);u.liveStyle===!0?u.jump(l):u.hasAnimated||u.set(l)}else{const u=n.getStaticValue(a);n.addValue(a,Ga(u!==void 0?u:l,{owner:n}))}}for(const a in i)e[a]===void 0&&n.removeValue(a);return e}const tf={current:null},Ax={current:!1},BE=typeof window<"u";function UE(){if(Ax.current=!0,!!BE)if(window.matchMedia){const n=window.matchMedia("(prefers-reduced-motion)"),e=()=>tf.current=n.matches;n.addEventListener("change",e),e()}else tf.current=!1}const A0=["AnimationStart","AnimationComplete","Update","BeforeLayoutMeasure","LayoutMeasure","LayoutAnimationStart","LayoutAnimationComplete"];let Ec={};function jx(n){Ec=n}function LE(){return Ec}class zE{scrapeMotionValuesFromProps(e,i,a){return{}}constructor({parent:e,props:i,presenceContext:a,reducedMotionConfig:l,skipAnimations:c,blockInitialAnimation:u,visualState:d},m={}){this.current=null,this.children=new Set,this.isVariantNode=!1,this.isControllingVariants=!1,this.shouldReduceMotion=null,this.shouldSkipAnimations=!1,this.values=new Map,this.KeyframeResolver=Pf,this.features={},this.valueSubscriptions=new Map,this.prevMotionValues={},this.hasBeenMounted=!1,this.events={},this.propEventSubscriptions={},this.notifyUpdate=()=>this.notify("Update",this.latestValues),this.render=()=>{this.current&&(this.triggerBuild(),this.renderInstance(this.current,this.renderState,this.props.style,this.projection))},this.renderScheduledAt=0,this.scheduleRender=()=>{const _=Ft.now();this.renderScheduledAt<_&&(this.renderScheduledAt=_,Xe.render(this.render,!1,!0))};const{latestValues:p,renderState:y}=d;this.latestValues=p,this.baseTarget={...p},this.initialValues=i.initial?{...p}:{},this.renderState=y,this.parent=e,this.props=i,this.presenceContext=a,this.depth=e?e.depth+1:0,this.reducedMotionConfig=l,this.skipAnimationsConfig=c,this.options=m,this.blockInitialAnimation=!!u,this.isControllingVariants=$c(i),this.isVariantNode=Ex(i),this.isVariantNode&&(this.variantChildren=new Set),this.manuallyAnimateOnMount=!!(e&&e.current);const{willChange:v,...x}=this.scrapeMotionValuesFromProps(i,{},this);for(const _ in x){const S=x[_];p[_]!==void 0&&Ut(S)&&S.set(p[_])}}mount(e){var i,a;if(this.hasBeenMounted)for(const l in this.initialValues)(i=this.values.get(l))==null||i.jump(this.initialValues[l]),this.latestValues[l]=this.initialValues[l];this.current=e,DE.set(e,this),this.projection&&!this.projection.instance&&this.projection.mount(e),this.parent&&this.isVariantNode&&!this.isControllingVariants&&(this.removeFromVariantTree=this.parent.addVariantChild(this)),this.values.forEach((l,c)=>this.bindToMotionValue(c,l)),this.reducedMotionConfig==="never"?this.shouldReduceMotion=!1:this.reducedMotionConfig==="always"?this.shouldReduceMotion=!0:(Ax.current||UE(),this.shouldReduceMotion=tf.current),this.shouldSkipAnimations=this.skipAnimationsConfig??!1,(a=this.parent)==null||a.addChild(this),this.update(this.props,this.presenceContext),this.hasBeenMounted=!0}unmount(){var e;this.projection&&this.projection.unmount(),li(this.notifyUpdate),li(this.render),this.valueSubscriptions.forEach(i=>i()),this.valueSubscriptions.clear(),this.removeFromVariantTree&&this.removeFromVariantTree(),(e=this.parent)==null||e.removeChild(this);for(const i in this.events)this.events[i].clear();for(const i in this.features){const a=this.features[i];a&&(a.unmount(),a.isMounted=!1)}this.current=null}addChild(e){this.children.add(e),this.enteringChildren??(this.enteringChildren=new Set),this.enteringChildren.add(e)}removeChild(e){this.children.delete(e),this.enteringChildren&&this.enteringChildren.delete(e)}bindToMotionValue(e,i){if(this.valueSubscriptions.has(e)&&this.valueSubscriptions.get(e)(),i.accelerate&&lx.has(e)&&this.current instanceof HTMLElement){const{factory:u,keyframes:d,times:m,ease:p,duration:y}=i.accelerate,v=new rx({element:this.current,name:e,keyframes:d,times:m,ease:p,duration:dn(y)}),x=u(v);this.valueSubscriptions.set(e,()=>{x(),v.cancel()});return}const a=Ja.has(e);a&&this.onBindTransform&&this.onBindTransform();const l=i.on("change",u=>{this.latestValues[e]=u,this.props.onUpdate&&Xe.preRender(this.notifyUpdate),a&&this.projection&&(this.projection.isTransformDirty=!0),this.scheduleRender()});let c;typeof window<"u"&&window.MotionCheckAppearSync&&(c=window.MotionCheckAppearSync(this,e,i)),this.valueSubscriptions.set(e,()=>{l(),c&&c()})}sortNodePosition(e){return!this.current||!this.sortInstanceNodePosition||this.type!==e.type?0:this.sortInstanceNodePosition(this.current,e.current)}updateFeatures(){let e="animation";for(e in Ec){const i=Ec[e];if(!i)continue;const{isEnabled:a,Feature:l}=i;if(!this.features[e]&&l&&a(this.props)&&(this.features[e]=new l(this)),this.features[e]){const c=this.features[e];c.isMounted?c.update():(c.mount(),c.isMounted=!0)}}}triggerBuild(){this.build(this.renderState,this.latestValues,this.props)}measureViewportBox(){return this.current?this.measureInstanceViewportBox(this.current,this.props):St()}getStaticValue(e){return this.latestValues[e]}setStaticValue(e,i){this.latestValues[e]=i}update(e,i){(e.transformTemplate||this.props.transformTemplate)&&this.scheduleRender(),this.prevProps=this.props,this.props=e,this.prevPresenceContext=this.presenceContext,this.presenceContext=i;for(let a=0;ai.variantChildren.delete(e)}addValue(e,i){const a=this.values.get(e);i!==a&&(a&&this.removeValue(e),this.bindToMotionValue(e,i),this.values.set(e,i),this.latestValues[e]=i.get())}removeValue(e){this.values.delete(e);const i=this.valueSubscriptions.get(e);i&&(i(),this.valueSubscriptions.delete(e)),delete this.latestValues[e],this.removeValueFromRenderState(e,this.renderState)}hasValue(e){return this.values.has(e)}getValue(e,i){if(this.props.values&&this.props.values[e])return this.props.values[e];let a=this.values.get(e);return a===void 0&&i!==void 0&&(a=Ga(i===null?void 0:i,{owner:this}),this.addValue(e,a)),a}readValue(e,i){let a=this.latestValues[e]!==void 0||!this.current?this.latestValues[e]:this.getBaseTargetFromProps(this.props,e)??this.readValueFromInstance(this.current,e,this.options);return a!=null&&(typeof a=="string"&&(Av(a)||Nv(a))?a=parseFloat(a):!OE(a)&&$n.test(i)&&(a=vx(e,i)),this.setBaseTarget(e,Ut(a)?a.get():a)),Ut(a)?a.get():a}setBaseTarget(e,i){this.baseTarget[e]=i}getBaseTarget(e){var c;const{initial:i}=this.props;let a;if(typeof i=="string"||typeof i=="object"){const u=$f(this.props,i,(c=this.presenceContext)==null?void 0:c.custom);u&&(a=u[e])}if(i&&a!==void 0)return a;const l=this.getBaseTargetFromProps(this.props,e);return l!==void 0&&!Ut(l)?l:this.initialValues[e]!==void 0&&a===void 0?void 0:this.baseTarget[e]}on(e,i){return this.events[e]||(this.events[e]=new Rf),this.events[e].add(i)}notify(e,...i){this.events[e]&&this.events[e].notify(...i)}scheduleRenderMicrotask(){If.render(this.render)}}class Nx extends zE{constructor(){super(...arguments),this.KeyframeResolver=dE}sortInstanceNodePosition(e,i){return e.compareDocumentPosition(i)&2?1:-1}getBaseTargetFromProps(e,i){const a=e.style;return a?a[i]:void 0}removeValueFromRenderState(e,{vars:i,style:a}){delete i[e],delete a[e]}handleChildMotionValue(){this.childSubscription&&(this.childSubscription(),delete this.childSubscription);const{children:e}=this.props;Ut(e)&&(this.childSubscription=e.on("change",i=>{this.current&&(this.current.textContent=`${i}`)}))}}class ci{constructor(e){this.isMounted=!1,this.node=e}update(){}}function kx({top:n,left:e,right:i,bottom:a}){return{x:{min:e,max:i},y:{min:n,max:a}}}function PE({x:n,y:e}){return{top:e.min,right:n.max,bottom:e.max,left:n.min}}function VE(n,e){if(!e)return n;const i=e({x:n.left,y:n.top}),a=e({x:n.right,y:n.bottom});return{top:i.y,left:i.x,bottom:a.y,right:a.x}}function gd(n){return n===void 0||n===1}function nf({scale:n,scaleX:e,scaleY:i}){return!gd(n)||!gd(e)||!gd(i)}function Mi(n){return nf(n)||Rx(n)||n.z||n.rotate||n.rotateX||n.rotateY||n.skewX||n.skewY}function Rx(n){return j0(n.x)||j0(n.y)}function j0(n){return n&&n!=="0%"}function Ac(n,e,i){const a=n-i,l=e*a;return i+l}function N0(n,e,i,a,l){return l!==void 0&&(n=Ac(n,l,a)),Ac(n,i,a)+e}function sf(n,e=0,i=1,a,l){n.min=N0(n.min,e,i,a,l),n.max=N0(n.max,e,i,a,l)}function Cx(n,{x:e,y:i}){sf(n.x,e.translate,e.scale,e.originPoint),sf(n.y,i.translate,i.scale,i.originPoint)}const k0=.999999999999,R0=1.0000000000001;function HE(n,e,i,a=!1){var d;const l=i.length;if(!l)return;e.x=e.y=1;let c,u;for(let m=0;mk0&&(e.x=1),e.yk0&&(e.y=1)}function Zn(n,e){n.min+=e,n.max+=e}function C0(n,e,i,a,l=.5){const c=Ye(n.min,n.max,l);sf(n,e,i,c,a)}function O0(n,e){return typeof n=="string"?parseFloat(n)/100*(e.max-e.min):n}function pc(n,e,i){const a=i??n;C0(n.x,O0(e.x,a.x),e.scaleX,e.scale,e.originX),C0(n.y,O0(e.y,a.y),e.scaleY,e.scale,e.originY)}function Ox(n,e){return kx(VE(n.getBoundingClientRect(),e))}function $E(n,e,i){const a=Ox(n,i),{scroll:l}=e;return l&&(Zn(a.x,l.offset.x),Zn(a.y,l.offset.y)),a}const qE={x:"translateX",y:"translateY",z:"translateZ",transformPerspective:"perspective"},FE=Xa.length;function IE(n,e,i){let a="",l=!0;for(let u=0;u{if(!e.target)return n;if(typeof n=="string")if(ce.test(n))n=parseFloat(n);else return n;const i=D0(n,e.target.x),a=D0(n,e.target.y);return`${i}% ${a}%`}},GE={correct:(n,{treeScale:e,projectionDelta:i})=>{const a=n,l=$n.parse(n);if(l.length>5)return a;const c=$n.createTransformer(n),u=typeof l[0]!="number"?1:0,d=i.x.scale*e.x,m=i.y.scale*e.y;l[0+u]/=d,l[1+u]/=m;const p=Ye(d,m,.5);return typeof l[2+u]=="number"&&(l[2+u]/=p),typeof l[3+u]=="number"&&(l[3+u]/=p),c(l)}},af={borderRadius:{...Ir,applyTo:[...Ff]},borderTopLeftRadius:Ir,borderTopRightRadius:Ir,borderBottomLeftRadius:Ir,borderBottomRightRadius:Ir,boxShadow:GE};function Mx(n,{layout:e,layoutId:i}){return Ja.has(n)||n.startsWith("origin")||(e||i!==void 0)&&(!!af[n]||n==="opacity")}function Qf(n,e,i){var u;const a=n.style,l=e==null?void 0:e.style,c={};if(!a)return c;for(const d in a)(Ut(a[d])||l&&Ut(l[d])||Mx(d,n)||((u=i==null?void 0:i.getValue(d))==null?void 0:u.liveStyle)!==void 0)&&(c[d]=a[d]);return c}function KE(n){return window.getComputedStyle(n)}class YE extends Nx{constructor(){super(...arguments),this.type="html",this.renderInstance=Dx}readValueFromInstance(e,i){var a;if(Ja.has(i))return(a=this.projection)!=null&&a.isProjecting?qd(i):mT(e,i);{const l=KE(e),c=(qv(i)?l.getPropertyValue(i):l[i])||0;return typeof c=="string"?c.trim():c}}measureInstanceViewportBox(e,{transformPagePoint:i}){return Ox(e,i)}build(e,i,a){Jf(e,i,a.transformTemplate)}scrapeMotionValuesFromProps(e,i,a){return Qf(e,i,a)}}const XE={offset:"stroke-dashoffset",array:"stroke-dasharray"},JE={offset:"strokeDashoffset",array:"strokeDasharray"};function QE(n,e,i=1,a=0,l=!0){n.pathLength=1;const c=l?XE:JE;n[c.offset]=`${-a}`,n[c.array]=`${e} ${i}`}const ZE=["offsetDistance","offsetPath","offsetRotate","offsetAnchor"];function Bx(n,{attrX:e,attrY:i,attrScale:a,pathLength:l,pathSpacing:c=1,pathOffset:u=0,...d},m,p,y){if(Jf(n,d,p),m){n.style.viewBox&&(n.attrs.viewBox=n.style.viewBox);return}n.attrs=n.style,n.style={};const{attrs:v,style:x}=n;v.transform&&(x.transform=v.transform,delete v.transform),(x.transform||v.transformOrigin)&&(x.transformOrigin=v.transformOrigin??"50% 50%",delete v.transformOrigin),x.transform&&(x.transformBox=(y==null?void 0:y.transformBox)??"fill-box",delete v.transformBox);for(const _ of ZE)v[_]!==void 0&&(x[_]=v[_],delete v[_]);e!==void 0&&(v.x=e),i!==void 0&&(v.y=i),a!==void 0&&(v.scale=a),l!==void 0&&QE(v,l,c,u,!1)}const Ux=new Set(["baseFrequency","diffuseConstant","kernelMatrix","kernelUnitLength","keySplines","keyTimes","limitingConeAngle","markerHeight","markerWidth","numOctaves","targetX","targetY","surfaceScale","specularConstant","specularExponent","stdDeviation","tableValues","viewBox","gradientTransform","pathLength","startOffset","textLength","lengthAdjust"]),Lx=n=>typeof n=="string"&&n.toLowerCase()==="svg";function WE(n,e,i,a){Dx(n,e,void 0,a);for(const l in e.attrs)n.setAttribute(Ux.has(l)?l:qf(l),e.attrs[l])}function zx(n,e,i){const a=Qf(n,e,i);for(const l in n)if(Ut(n[l])||Ut(e[l])){const c=Xa.indexOf(l)!==-1?"attr"+l.charAt(0).toUpperCase()+l.substring(1):l;a[c]=n[l]}return a}class eA extends Nx{constructor(){super(...arguments),this.type="svg",this.isSVGTag=!1,this.measureInstanceViewportBox=St}getBaseTargetFromProps(e,i){return e[i]}readValueFromInstance(e,i){if(Ja.has(i)){const a=bx(i);return a&&a.default||0}return i=Ux.has(i)?i:qf(i),e.getAttribute(i)}scrapeMotionValuesFromProps(e,i,a){return zx(e,i,a)}build(e,i,a){Bx(e,i,this.isSVGTag,a.transformTemplate,a.style)}renderInstance(e,i,a,l){WE(e,i,a,l)}mount(e){this.isSVGTag=Lx(e.tagName),super.mount(e)}}const tA=Xf.length;function Px(n){if(!n)return;if(!n.isControllingVariants){const i=n.parent?Px(n.parent)||{}:{};return n.props.initial!==void 0&&(i.initial=n.props.initial),i}const e={};for(let i=0;iPromise.all(e.map(({animation:i,options:a})=>tE(n,i,a)))}function aA(n){let e=iA(n),i=M0(),a=!0,l=!1;const c=p=>(y,v)=>{var _;const x=Vi(n,v,p==="exit"?(_=n.presenceContext)==null?void 0:_.custom:void 0);if(x){const{transition:S,transitionEnd:T,...k}=x;y={...y,...k,...T}}return y};function u(p){e=p(n)}function d(p){const{props:y}=n,v=Px(n.parent)||{},x=[],_=new Set;let S={},T=1/0;for(let R=0;RT&&G,J=!1;const he=Array.isArray(P)?P:[P];let fe=he.reduce(c(M),{});X===!1&&(fe={});const{prevResolvedValues:Ae={}}=N,ve={...Ae,...fe},Ce=Z=>{se=!0,_.has(Z)&&(J=!0,_.delete(Z)),N.needsAnimating[Z]=!0;const pe=n.getValue(Z);pe&&(pe.liveStyle=!1)};for(const Z in ve){const pe=fe[Z],ie=Ae[Z];if(S.hasOwnProperty(Z))continue;let E=!1;Xd(pe)&&Xd(ie)?E=!Vx(pe,ie)||Y:E=pe!==ie,E?pe!=null?Ce(Z):_.add(Z):pe!==void 0&&_.has(Z)?Ce(Z):N.protectedKeys[Z]=!0}N.prevProp=P,N.prevResolvedValues=fe,N.isActive&&(S={...S,...fe}),(a||l)&&n.blockInitialAnimation&&(se=!1);const L=q&&Y;se&&(!L||J)&&x.push(...he.map(Z=>{const pe={type:M};if(typeof Z=="string"&&(a||l)&&!L&&n.manuallyAnimateOnMount&&n.parent){const{parent:ie}=n,E=Vi(ie,Z);if(ie.enteringChildren&&E){const{delayChildren:H}=E.transition||{};pe.delay=cx(ie.enteringChildren,n,H)}}return{animation:Z,options:pe}}))}if(_.size){const R={};if(typeof y.initial!="boolean"){const M=Vi(n,Array.isArray(y.initial)?y.initial[0]:y.initial);M&&M.transition&&(R.transition=M.transition)}_.forEach(M=>{const N=n.getBaseTarget(M),P=n.getValue(M);P&&(P.liveStyle=!0),R[M]=N??null}),x.push({animation:R})}let k=!!x.length;return a&&(y.initial===!1||y.initial===y.animate)&&!n.manuallyAnimateOnMount&&(k=!1),a=!1,l=!1,k?e(x):Promise.resolve()}function m(p,y){var x;if(i[p].isActive===y)return Promise.resolve();(x=n.variantChildren)==null||x.forEach(_=>{var S;return(S=_.animationState)==null?void 0:S.setActive(p,y)}),i[p].isActive=y;const v=d(p);for(const _ in i)i[_].protectedKeys={};return v}return{animateChanges:d,setActive:m,setAnimateFunction:u,getState:()=>i,reset:()=>{i=M0(),l=!0}}}function rA(n,e){return typeof e=="string"?e!==n:Array.isArray(e)?!Vx(e,n):!1}function Ci(n=!1){return{isActive:n,protectedKeys:{},needsAnimating:{},prevResolvedValues:{}}}function M0(){return{animate:Ci(!0),whileInView:Ci(),whileHover:Ci(),whileTap:Ci(),whileDrag:Ci(),whileFocus:Ci(),exit:Ci()}}function rf(n,e){n.min=e.min,n.max=e.max}function Bn(n,e){rf(n.x,e.x),rf(n.y,e.y)}function B0(n,e){n.translate=e.translate,n.scale=e.scale,n.originPoint=e.originPoint,n.origin=e.origin}const Hx=1e-4,oA=1-Hx,lA=1+Hx,$x=.01,cA=0-$x,uA=0+$x;function It(n){return n.max-n.min}function hA(n,e,i){return Math.abs(n-e)<=i}function U0(n,e,i,a=.5){n.origin=a,n.originPoint=Ye(e.min,e.max,n.origin),n.scale=It(i)/It(e),n.translate=Ye(i.min,i.max,n.origin)-n.originPoint,(n.scale>=oA&&n.scale<=lA||isNaN(n.scale))&&(n.scale=1),(n.translate>=cA&&n.translate<=uA||isNaN(n.translate))&&(n.translate=0)}function no(n,e,i,a){U0(n.x,e.x,i.x,a?a.originX:void 0),U0(n.y,e.y,i.y,a?a.originY:void 0)}function L0(n,e,i,a=0){const l=a?Ye(i.min,i.max,a):i.min;n.min=l+e.min,n.max=n.min+It(e)}function dA(n,e,i,a){L0(n.x,e.x,i.x,a==null?void 0:a.x),L0(n.y,e.y,i.y,a==null?void 0:a.y)}function z0(n,e,i,a=0){const l=a?Ye(i.min,i.max,a):i.min;n.min=e.min-l,n.max=n.min+It(e)}function jc(n,e,i,a){z0(n.x,e.x,i.x,a==null?void 0:a.x),z0(n.y,e.y,i.y,a==null?void 0:a.y)}function P0(n,e,i,a,l){return n-=e,n=Ac(n,1/i,a),l!==void 0&&(n=Ac(n,1/l,a)),n}function fA(n,e=0,i=1,a=.5,l,c=n,u=n){if(es.test(e)&&(e=parseFloat(e),e=Ye(u.min,u.max,e/100)-u.min),typeof e!="number")return;let d=Ye(c.min,c.max,a);n===c&&(d-=e),n.min=P0(n.min,e,i,d,l),n.max=P0(n.max,e,i,d,l)}function V0(n,e,[i,a,l],c,u){fA(n,e[i],e[a],e[l],e.scale,c,u)}const mA=["x","scaleX","originX"],pA=["y","scaleY","originY"];function H0(n,e,i,a){V0(n.x,e,mA,i?i.x:void 0,a?a.x:void 0),V0(n.y,e,pA,i?i.y:void 0,a?a.y:void 0)}function $0(n){return n.translate===0&&n.scale===1}function qx(n){return $0(n.x)&&$0(n.y)}function q0(n,e){return n.min===e.min&&n.max===e.max}function gA(n,e){return q0(n.x,e.x)&&q0(n.y,e.y)}function F0(n,e){return Math.round(n.min)===Math.round(e.min)&&Math.round(n.max)===Math.round(e.max)}function Fx(n,e){return F0(n.x,e.x)&&F0(n.y,e.y)}function I0(n){return It(n.x)/It(n.y)}function G0(n,e){return n.translate===e.translate&&n.scale===e.scale&&n.originPoint===e.originPoint}function Jn(n){return[n("x"),n("y")]}function yA(n,e,i){let a="";const l=n.x.translate/e.x,c=n.y.translate/e.y,u=(i==null?void 0:i.z)||0;if((l||c||u)&&(a=`translate3d(${l}px, ${c}px, ${u}px) `),(e.x!==1||e.y!==1)&&(a+=`scale(${1/e.x}, ${1/e.y}) `),i){const{transformPerspective:p,rotate:y,pathRotation:v,rotateX:x,rotateY:_,skewX:S,skewY:T}=i;p&&(a=`perspective(${p}px) ${a}`),y&&(a+=`rotate(${y}deg) `),v&&(a+=`rotate(${v}deg) `),x&&(a+=`rotateX(${x}deg) `),_&&(a+=`rotateY(${_}deg) `),S&&(a+=`skewX(${S}deg) `),T&&(a+=`skewY(${T}deg) `)}const d=n.x.scale*e.x,m=n.y.scale*e.y;return(d!==1||m!==1)&&(a+=`scale(${d}, ${m})`),a||"none"}const bA=Ff.length,K0=n=>typeof n=="string"?parseFloat(n):n,Y0=n=>typeof n=="number"||ce.test(n);function vA(n,e,i,a,l,c){l?(n.opacity=Ye(0,i.opacity??1,xA(a)),n.opacityExit=Ye(e.opacity??1,0,wA(a))):c&&(n.opacity=Ye(e.opacity??1,i.opacity??1,a));for(let u=0;uae?1:i(lo(n,e,a))}function _A(n,e,i){const a=Ut(n)?n:Ga(n);return a.start(Hf("",a,e,i)),a.animation}function ho(n,e,i,a={passive:!0}){return n.addEventListener(e,i,a),()=>n.removeEventListener(e,i,a)}const SA=(n,e)=>n.depth-e.depth;class TA{constructor(){this.children=[],this.isDirty=!1}add(e){Nf(this.children,e),this.isDirty=!0}remove(e){vc(this.children,e),this.isDirty=!0}forEach(e){this.isDirty&&this.children.sort(SA),this.isDirty=!1,this.children.forEach(e)}}function EA(n,e){const i=Ft.now(),a=({timestamp:l})=>{const c=l-i;c>=e&&(li(a),n(c-e))};return Xe.setup(a,!0),()=>li(a)}function gc(n){return Ut(n)?n.get():n}class AA{constructor(){this.members=[]}add(e){Nf(this.members,e);for(let i=this.members.length-1;i>=0;i--){const a=this.members[i];if(a===e||a===this.lead||a===this.prevLead)continue;const l=a.instance;(!l||l.isConnected===!1)&&!a.snapshot&&(vc(this.members,a),a.unmount())}e.scheduleRender()}remove(e){if(vc(this.members,e),e===this.prevLead&&(this.prevLead=void 0),e===this.lead){const i=this.members[this.members.length-1];i&&this.promote(i)}}relegate(e){var i;for(let a=this.members.indexOf(e)-1;a>=0;a--){const l=this.members[a];if(l.isPresent!==!1&&((i=l.instance)==null?void 0:i.isConnected)!==!1)return this.promote(l),!0}return!1}promote(e,i){var l;const a=this.lead;if(e!==a&&(this.prevLead=a,this.lead=e,e.show(),a)){a.updateSnapshot(),e.scheduleRender();const{layoutDependency:c}=a.options,{layoutDependency:u}=e.options;(c===void 0||c!==u)&&(e.resumeFrom=a,i&&(a.preserveOpacity=!0),a.snapshot&&(e.snapshot=a.snapshot,e.snapshot.latestValues=a.animationValues||a.latestValues),(l=e.root)!=null&&l.isUpdating&&(e.isLayoutDirty=!0)),e.options.crossfade===!1&&a.hide()}}exitAnimationComplete(){this.members.forEach(e=>{var i,a,l,c,u;(a=(i=e.options).onExitComplete)==null||a.call(i),(u=(l=e.resumingFrom)==null?void 0:(c=l.options).onExitComplete)==null||u.call(c)})}scheduleRender(){this.members.forEach(e=>e.instance&&e.scheduleRender(!1))}removeLeadSnapshot(){var e;(e=this.lead)!=null&&e.snapshot&&(this.lead.snapshot=void 0)}}const yc={hasAnimatedSinceResize:!0,hasEverUpdated:!1},yd=["","X","Y","Z"],jA=1e3;let NA=0;function bd(n,e,i,a){const{latestValues:l}=e;l[n]&&(i[n]=l[n],e.setStaticValue(n,0),a&&(a[n]=0))}function Gx(n){if(n.hasCheckedOptimisedAppear=!0,n.root===n)return;const{visualElement:e}=n.options;if(!e)return;const i=mx(e);if(window.MotionHasOptimisedAnimation(i,"transform")){const{layout:l,layoutId:c}=n.options;window.MotionCancelOptimisedAnimation(i,"transform",Xe,!(l||c))}const{parent:a}=n;a&&!a.hasCheckedOptimisedAppear&&Gx(a)}function Kx({attachResizeListener:n,defaultParent:e,measureScroll:i,checkIsScrollRoot:a,resetTransform:l}){return class{constructor(u={},d=e==null?void 0:e()){this.id=NA++,this.animationId=0,this.animationCommitId=0,this.children=new Set,this.options={},this.isTreeAnimating=!1,this.isAnimationBlocked=!1,this.isLayoutDirty=!1,this.isProjectionDirty=!1,this.isSharedProjectionDirty=!1,this.isTransformDirty=!1,this.updateManuallyBlocked=!1,this.updateBlockedByResize=!1,this.isUpdating=!1,this.isSVG=!1,this.needsReset=!1,this.shouldResetTransform=!1,this.hasCheckedOptimisedAppear=!1,this.treeScale={x:1,y:1},this.eventHandlers=new Map,this.hasTreeAnimated=!1,this.layoutVersion=0,this.updateScheduled=!1,this.scheduleUpdate=()=>this.update(),this.projectionUpdateScheduled=!1,this.checkUpdateFailed=()=>{this.isUpdating&&(this.isUpdating=!1,this.clearAllSnapshots())},this.updateProjection=()=>{this.projectionUpdateScheduled=!1,this.nodes.forEach(CA),this.nodes.forEach(LA),this.nodes.forEach(zA),this.nodes.forEach(OA)},this.resolvedRelativeTargetAt=0,this.linkedParentVersion=0,this.hasProjected=!1,this.isVisible=!0,this.animationProgress=0,this.sharedNodes=new Map,this.latestValues=u,this.root=d?d.root||d:this,this.path=d?[...d.path,d]:[],this.parent=d,this.depth=d?d.depth+1:0;for(let m=0;mthis.root.updateBlockedByResize=!1;Xe.read(()=>{v=window.innerWidth}),n(u,()=>{const _=window.innerWidth;_!==v&&(v=_,this.root.updateBlockedByResize=!0,y&&y(),y=EA(x,250),yc.hasAnimatedSinceResize&&(yc.hasAnimatedSinceResize=!1,this.nodes.forEach(Z0)))})}d&&this.root.registerSharedNode(d,this),this.options.animate!==!1&&p&&(d||m)&&this.addEventListener("didUpdate",({delta:y,hasLayoutChanged:v,hasRelativeLayoutChanged:x,layout:_})=>{if(this.isTreeAnimationBlocked()){this.target=void 0,this.relativeTarget=void 0;return}const S=this.options.transition||p.getDefaultTransition()||qA,{onLayoutAnimationStart:T,onLayoutAnimationComplete:k}=p.getProps(),R=!this.targetLayout||!Fx(this.targetLayout,_),M=!v&&x;if(this.options.layoutRoot||this.resumeFrom||M||v&&(R||!this.currentAnimation)){this.resumeFrom&&(this.resumingFrom=this.resumeFrom,this.resumingFrom.resumingFrom=void 0);const N={...Vf(S,"layout"),onPlay:T,onComplete:k};(p.shouldReduceMotion||this.options.layoutRoot)&&(N.delay=0,N.type=!1),this.startAnimation(N),this.setAnimationOrigin(y,M,N.path)}else v||Z0(this),this.isLead()&&this.options.onExitComplete&&this.options.onExitComplete();this.targetLayout=_})}unmount(){this.options.layoutId&&this.willUpdate(),this.root.nodes.remove(this);const u=this.getStack();u&&u.remove(this),this.parent&&this.parent.children.delete(this),this.instance=void 0,this.eventHandlers.clear(),li(this.updateProjection)}blockUpdate(){this.updateManuallyBlocked=!0}unblockUpdate(){this.updateManuallyBlocked=!1}isUpdateBlocked(){return this.updateManuallyBlocked||this.updateBlockedByResize}isTreeAnimationBlocked(){return this.isAnimationBlocked||this.parent&&this.parent.isTreeAnimationBlocked()||!1}startUpdate(){this.isUpdateBlocked()||(this.isUpdating=!0,this.nodes&&this.nodes.forEach(PA),this.animationId++)}getTransformTemplate(){const{visualElement:u}=this.options;return u&&u.getProps().transformTemplate}willUpdate(u=!0){if(this.root.hasTreeAnimated=!0,this.root.isUpdateBlocked()){this.options.onExitComplete&&this.options.onExitComplete();return}if(window.MotionCancelOptimisedAnimation&&!this.hasCheckedOptimisedAppear&&Gx(this),!this.root.isUpdating&&this.root.startUpdate(),this.isLayoutDirty)return;this.isLayoutDirty=!0;for(let y=0;y{this.isLayoutDirty?this.root.didUpdate():this.root.checkUpdateFailed()})}updateSnapshot(){this.snapshot||!this.instance||(this.snapshot=this.measure(),this.snapshot&&!It(this.snapshot.measuredBox.x)&&!It(this.snapshot.measuredBox.y)&&(this.snapshot=void 0))}updateLayout(){if(!this.instance||(this.updateScroll(),!(this.options.alwaysMeasureLayout&&this.isLead())&&!this.isLayoutDirty))return;if(this.resumeFrom&&!this.resumeFrom.instance)for(let m=0;m{const q=X/1e3,Y=G==null?void 0:G(q);Y?(x.x.translate=Y.x,x.x.scale=Ye(u.x.scale,1,q),x.x.origin=u.x.origin,x.x.originPoint=u.x.originPoint,x.y.translate=Y.y,x.y.scale=Ye(u.y.scale,1,q),x.y.origin=u.y.origin,x.y.originPoint=u.y.originPoint):(W0(x.x,u.x,q),W0(x.y,u.y,q)),this.setTargetDelta(x),this.relativeTarget&&this.relativeTargetOrigin&&this.layout&&this.relativeParent&&this.relativeParent.layout&&(jc(_,this.layout.layoutBox,this.relativeParent.layout.layoutBox,this.options.layoutAnchor||void 0),HA(this.relativeTarget,this.relativeTargetOrigin,_,q),P&&gA(this.relativeTarget,P)&&(this.isProjectionDirty=!1),P||(P=St()),Bn(P,this.relativeTarget)),k&&(this.animationValues=v,vA(v,y,this.latestValues,q,N,M)),Y&&Y.rotate!==void 0&&(this.animationValues||(this.animationValues=v),this.animationValues.pathRotation=Y.rotate),this.root.scheduleUpdateProjection(),this.scheduleRender(),this.animationProgress=q},this.mixTargetDelta(this.options.layoutRoot?1e3:0)}startAnimation(u){var d,m,p;this.notifyListeners("animationStart"),(d=this.currentAnimation)==null||d.stop(),(p=(m=this.resumingFrom)==null?void 0:m.currentAnimation)==null||p.stop(),this.pendingAnimation&&(li(this.pendingAnimation),this.pendingAnimation=void 0),this.pendingAnimation=Xe.update(()=>{yc.hasAnimatedSinceResize=!0,this.motionValue||(this.motionValue=Ga(0)),this.motionValue.jump(0,!1),this.currentAnimation=_A(this.motionValue,[0,1e3],{...u,velocity:0,isSync:!0,onUpdate:y=>{this.mixTargetDelta(y),u.onUpdate&&u.onUpdate(y)},onComplete:()=>{u.onComplete&&u.onComplete(),this.completeAnimation()}}),this.resumingFrom&&(this.resumingFrom.currentAnimation=this.currentAnimation),this.pendingAnimation=void 0})}completeAnimation(){this.resumingFrom&&(this.resumingFrom.currentAnimation=void 0,this.resumingFrom.preserveOpacity=void 0);const u=this.getStack();u&&u.exitAnimationComplete(),this.resumingFrom=this.currentAnimation=this.animationValues=void 0,this.notifyListeners("animationComplete")}finishAnimation(){this.currentAnimation&&(this.mixTargetDelta&&this.mixTargetDelta(jA),this.currentAnimation.stop()),this.completeAnimation()}applyTransformsToTarget(){const u=this.getLead();let{targetWithTransforms:d,target:m,layout:p,latestValues:y}=u;if(!(!d||!m||!p)){if(this!==u&&this.layout&&p&&Yx(this.options.animationType,this.layout.layoutBox,p.layoutBox)){m=this.target||St();const v=It(this.layout.layoutBox.x);m.x.min=u.target.x.min,m.x.max=m.x.min+v;const x=It(this.layout.layoutBox.y);m.y.min=u.target.y.min,m.y.max=m.y.min+x}Bn(d,m),pc(d,y),no(this.projectionDeltaWithTransform,this.layoutCorrected,d,y)}}registerSharedNode(u,d){this.sharedNodes.has(u)||this.sharedNodes.set(u,new AA),this.sharedNodes.get(u).add(d);const p=d.options.initialPromotionConfig;d.promote({transition:p?p.transition:void 0,preserveFollowOpacity:p&&p.shouldPreserveFollowOpacity?p.shouldPreserveFollowOpacity(d):void 0})}isLead(){const u=this.getStack();return u?u.lead===this:!0}getLead(){var d;const{layoutId:u}=this.options;return u?((d=this.getStack())==null?void 0:d.lead)||this:this}getPrevLead(){var d;const{layoutId:u}=this.options;return u?(d=this.getStack())==null?void 0:d.prevLead:void 0}getStack(){const{layoutId:u}=this.options;if(u)return this.root.sharedNodes.get(u)}promote({needsReset:u,transition:d,preserveFollowOpacity:m}={}){const p=this.getStack();p&&p.promote(this,m),u&&(this.projectionDelta=void 0,this.needsReset=!0),d&&this.setOptions({transition:d})}relegate(){const u=this.getStack();return u?u.relegate(this):!1}resetSkewAndRotation(){const{visualElement:u}=this.options;if(!u)return;let d=!1;const{latestValues:m}=u;if((m.z||m.rotate||m.rotateX||m.rotateY||m.rotateZ||m.skewX||m.skewY)&&(d=!0),!d)return;const p={};m.z&&bd("z",u,p,this.animationValues);for(let y=0;y{var d;return(d=u.currentAnimation)==null?void 0:d.stop()}),this.root.nodes.forEach(J0),this.root.sharedNodes.clear()}}}function kA(n){n.updateLayout()}function RA(n){var i;const e=((i=n.resumeFrom)==null?void 0:i.snapshot)||n.snapshot;if(n.isLead()&&n.layout&&e&&n.hasListeners("didUpdate")){const{layoutBox:a,measuredBox:l}=n.layout,{animationType:c}=n.options,u=e.source!==n.layout.source;if(c==="size")Jn(v=>{const x=u?e.measuredBox[v]:e.layoutBox[v],_=It(x);x.min=a[v].min,x.max=x.min+_});else if(c==="x"||c==="y"){const v=c==="x"?"y":"x";rf(u?e.measuredBox[v]:e.layoutBox[v],a[v])}else Yx(c,e.layoutBox,a)&&Jn(v=>{const x=u?e.measuredBox[v]:e.layoutBox[v],_=It(a[v]);x.max=x.min+_,n.relativeTarget&&!n.currentAnimation&&(n.isProjectionDirty=!0,n.relativeTarget[v].max=n.relativeTarget[v].min+_)});const d=Pa();no(d,a,e.layoutBox);const m=Pa();u?no(m,n.applyTransform(l,!0),e.measuredBox):no(m,a,e.layoutBox);const p=!qx(d);let y=!1;if(!n.resumeFrom){const v=n.getClosestProjectingParent();if(v&&!v.resumeFrom){const{snapshot:x,layout:_}=v;if(x&&_){const S=n.options.layoutAnchor||void 0,T=St();jc(T,e.layoutBox,x.layoutBox,S);const k=St();jc(k,a,_.layoutBox,S),Fx(T,k)||(y=!0),v.options.layoutRoot&&(n.relativeTarget=k,n.relativeTargetOrigin=T,n.relativeParent=v)}}}n.notifyListeners("didUpdate",{layout:a,snapshot:e,delta:m,layoutDelta:d,hasLayoutChanged:p,hasRelativeLayoutChanged:y})}else if(n.isLead()){const{onExitComplete:a}=n.options;a&&a()}n.options.transition=void 0}function CA(n){n.parent&&(n.isProjecting()||(n.isProjectionDirty=n.parent.isProjectionDirty),n.isSharedProjectionDirty||(n.isSharedProjectionDirty=!!(n.isProjectionDirty||n.parent.isProjectionDirty||n.parent.isSharedProjectionDirty)),n.isTransformDirty||(n.isTransformDirty=n.parent.isTransformDirty))}function OA(n){n.isProjectionDirty=n.isSharedProjectionDirty=n.isTransformDirty=!1}function DA(n){n.clearSnapshot()}function J0(n){n.clearMeasurements()}function MA(n){n.isLayoutDirty=!0,n.updateLayout()}function Q0(n){n.isLayoutDirty=!1}function BA(n){n.isAnimationBlocked&&n.layout&&!n.isLayoutDirty&&(n.snapshot=n.layout,n.isLayoutDirty=!0)}function UA(n){const{visualElement:e}=n.options;e&&e.getProps().onBeforeLayoutMeasure&&e.notify("BeforeLayoutMeasure"),n.resetTransform()}function Z0(n){n.finishAnimation(),n.targetDelta=n.relativeTarget=n.target=void 0,n.isProjectionDirty=!0}function LA(n){n.resolveTargetDelta()}function zA(n){n.calcProjection()}function PA(n){n.resetSkewAndRotation()}function VA(n){n.removeLeadSnapshot()}function W0(n,e,i){n.translate=Ye(e.translate,0,i),n.scale=Ye(e.scale,1,i),n.origin=e.origin,n.originPoint=e.originPoint}function eb(n,e,i,a){n.min=Ye(e.min,i.min,a),n.max=Ye(e.max,i.max,a)}function HA(n,e,i,a){eb(n.x,e.x,i.x,a),eb(n.y,e.y,i.y,a)}function $A(n){return n.animationValues&&n.animationValues.opacityExit!==void 0}const qA={duration:.45,ease:[.4,0,.1,1]},tb=n=>typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().includes(n),nb=tb("applewebkit/")&&!tb("chrome/")?Math.round:An;function sb(n){n.min=nb(n.min),n.max=nb(n.max)}function FA(n){sb(n.x),sb(n.y)}function Yx(n,e,i){return n==="position"||n==="preserve-aspect"&&!hA(I0(e),I0(i),.2)}function IA(n){var e;return n!==n.root&&((e=n.scroll)==null?void 0:e.wasRoot)}const GA=Kx({attachResizeListener:(n,e)=>ho(n,"resize",e),measureScroll:()=>{var n,e;return{x:document.documentElement.scrollLeft||((n=document.body)==null?void 0:n.scrollLeft)||0,y:document.documentElement.scrollTop||((e=document.body)==null?void 0:e.scrollTop)||0}},checkIsScrollRoot:()=>!0}),vd={current:void 0},Xx=Kx({measureScroll:n=>({x:n.scrollLeft,y:n.scrollTop}),defaultParent:()=>{if(!vd.current){const n=new GA({});n.mount(window),n.setOptions({layoutScroll:!0}),vd.current=n}return vd.current},resetTransform:(n,e)=>{n.style.transform=e!==void 0?e:"none"},checkIsScrollRoot:n=>window.getComputedStyle(n).position==="fixed"}),Zf=D.createContext({transformPagePoint:n=>n,isStatic:!1,reducedMotion:"never"});function ib(n,e){if(typeof n=="function")return n(e);n!=null&&(n.current=e)}function KA(...n){return e=>{let i=!1;const a=n.map(l=>{const c=ib(l,e);return!i&&typeof c=="function"&&(i=!0),c});if(i)return()=>{for(let l=0;l{const{width:_,height:S,top:T,left:k,right:R,bottom:M,direction:N}=m.current;if(e||c===!1||!d.current||!_||!S)return;const P=N==="rtl",G=i==="left"?P?`right: ${R}`:`left: ${k}`:P?`left: ${k}`:`right: ${R}`,X=a==="bottom"?`bottom: ${M}`:`top: ${T}`;d.current.dataset.motionPopId=u;const q=document.createElement("style");p&&(q.nonce=p);const Y=l??document.head;return Y.appendChild(q),q.sheet&&q.sheet.insertRule(` - [data-motion-pop-id="${u}"] { - position: absolute !important; - width: ${_}px !important; - height: ${S}px !important; - ${G}px !important; - ${X}px !important; - } - `),()=>{var se;(se=d.current)==null||se.removeAttribute("data-motion-pop-id"),Y.contains(q)&&Y.removeChild(q)}},[e]),g.jsx(XA,{isPresent:e,childRef:d,sizeRef:m,pop:c,children:c===!1?n:D.cloneElement(n,{ref:v})})}const QA=({children:n,initial:e,isPresent:i,onExitComplete:a,custom:l,presenceAffectsLayout:c,mode:u,anchorX:d,anchorY:m,root:p})=>{const y=Af(ZA),v=D.useId(),x=D.useRef(i),_=D.useRef(a);jf(()=>{x.current=i,_.current=a});let S=!0,T=D.useMemo(()=>(S=!1,{id:v,initial:e,isPresent:i,custom:l,onExitComplete:k=>{y.set(k,!0);for(const R of y.values())if(!R)return;a&&a()},register:k=>(y.set(k,!1),()=>{var R;y.delete(k),!x.current&&!y.size&&((R=_.current)==null||R.call(_))})}),[i,y,a]);return c&&S&&(T={...T}),D.useMemo(()=>{y.forEach((k,R)=>y.set(R,!1))},[i]),D.useEffect(()=>{!i&&!y.size&&a&&a()},[i]),n=g.jsx(JA,{pop:u==="popLayout",isPresent:i,anchorX:d,anchorY:m,root:p,children:n}),g.jsx(Pc.Provider,{value:T,children:n})};function ZA(){return new Map}function Jx(n=!0){const e=D.useContext(Pc);if(e===null)return[!0,null];const{isPresent:i,onExitComplete:a,register:l}=e,c=D.useId();D.useEffect(()=>{if(n)return l(c)},[n]);const u=D.useCallback(()=>n&&a&&a(c),[c,a,n]);return!i&&a?[!1,u]:[!0]}const Jl=n=>n.key||"";function ab(n){const e=[];return D.Children.forEach(n,i=>{D.isValidElement(i)&&e.push(i)}),e}const si=({children:n,custom:e,initial:i=!0,onExitComplete:a,presenceAffectsLayout:l=!0,mode:c="sync",propagate:u=!1,anchorX:d="left",anchorY:m="top",root:p})=>{const[y,v]=Jx(u),x=D.useMemo(()=>ab(n),[n]),_=u&&!y?[]:x.map(Jl),S=D.useRef(!0),T=D.useRef(x),k=Af(()=>new Map),R=D.useRef(new Set),[M,N]=D.useState(x),[P,G]=D.useState(x);jf(()=>{S.current=!1,T.current=x;for(let Y=0;Y{const se=Jl(Y),J=u&&!y?!1:x===P||_.includes(se),he=()=>{if(R.current.has(se))return;if(k.has(se))R.current.add(se),k.set(se,!0);else return;let fe=!0;k.forEach(Ae=>{Ae||(fe=!1)}),fe&&(q==null||q(),G(T.current),u&&(v==null||v()),a&&a())};return g.jsx(QA,{isPresent:J,initial:!S.current||i?void 0:!1,custom:e,presenceAffectsLayout:l,mode:c,root:p,onExitComplete:J?void 0:he,anchorX:d,anchorY:m,children:Y},se)})})},Qx=D.createContext({strict:!1}),rb={animation:["animate","variants","whileHover","whileTap","exit","whileInView","whileFocus","whileDrag"],exit:["exit"],drag:["drag","dragControls"],focus:["whileFocus"],hover:["whileHover","onHoverStart","onHoverEnd"],tap:["whileTap","onTap","onTapStart","onTapCancel"],pan:["onPan","onPanStart","onPanSessionStart","onPanEnd"],inView:["whileInView","onViewportEnter","onViewportLeave"],layout:["layout","layoutId"]};let ob=!1;function WA(){if(ob)return;const n={};for(const e in rb)n[e]={isEnabled:i=>rb[e].some(a=>!!i[a])};jx(n),ob=!0}function Zx(){return WA(),LE()}function e2(n){const e=Zx();for(const i in n)e[i]={...e[i],...n[i]};jx(e)}const t2=new Set(["animate","exit","variants","initial","style","values","variants","transition","transformTemplate","custom","inherit","onBeforeLayoutMeasure","onAnimationStart","onAnimationComplete","onUpdate","onDragStart","onDrag","onDragEnd","onMeasureDragConstraints","onDirectionLock","onDragTransitionEnd","_dragX","_dragY","onHoverStart","onHoverEnd","onViewportEnter","onViewportLeave","globalTapTarget","propagate","ignoreStrict","viewport"]);function Nc(n){return n.startsWith("while")||n.startsWith("drag")&&n!=="draggable"||n.startsWith("layout")||n.startsWith("onTap")||n.startsWith("onPan")||n.startsWith("onLayout")||t2.has(n)}let Wx=n=>!Nc(n);function n2(n){typeof n=="function"&&(Wx=e=>e.startsWith("on")?!Nc(e):n(e))}try{n2(require("@emotion/is-prop-valid").default)}catch{}function s2(n,e,i){const a={};for(const l in n)l==="values"&&typeof n.values=="object"||Ut(n[l])||(Wx(l)||i===!0&&Nc(l)||!e&&!Nc(l)||n.draggable&&l.startsWith("onDrag"))&&(a[l]=n[l]);return a}const qc=D.createContext({});function i2(n,e){if($c(n)){const{initial:i,animate:a}=n;return{initial:i===!1||uo(i)?i:void 0,animate:uo(a)?a:void 0}}return n.inherit!==!1?e:{}}function a2(n){const{initial:e,animate:i}=i2(n,D.useContext(qc));return D.useMemo(()=>({initial:e,animate:i}),[lb(e),lb(i)])}function lb(n){return Array.isArray(n)?n.join(" "):n}const Wf=()=>({style:{},transform:{},transformOrigin:{},vars:{}});function ew(n,e,i){for(const a in e)!Ut(e[a])&&!Mx(a,i)&&(n[a]=e[a])}function r2({transformTemplate:n},e){return D.useMemo(()=>{const i=Wf();return Jf(i,e,n),Object.assign({},i.vars,i.style)},[e])}function o2(n,e){const i=n.style||{},a={};return ew(a,i,n),Object.assign(a,r2(n,e)),a}function l2(n,e){const i={},a=o2(n,e);return n.drag&&n.dragListener!==!1&&(i.draggable=!1,a.userSelect=a.WebkitUserSelect=a.WebkitTouchCallout="none",a.touchAction=n.drag===!0?"none":`pan-${n.drag==="x"?"y":"x"}`),n.tabIndex===void 0&&(n.onTap||n.onTapStart||n.whileTap)&&(i.tabIndex=0),i.style=a,i}const tw=()=>({...Wf(),attrs:{}});function c2(n,e,i,a){const l=D.useMemo(()=>{const c=tw();return Bx(c,e,Lx(a),n.transformTemplate,n.style),{...c.attrs,style:{...c.style}}},[e]);if(n.style){const c={};ew(c,n.style,n),l.style={...c,...l.style}}return l}const u2=["animate","circle","defs","desc","ellipse","g","image","line","filter","marker","mask","metadata","path","pattern","polygon","polyline","rect","stop","switch","symbol","svg","text","tspan","use","view"];function em(n){return typeof n!="string"||n.includes("-")?!1:!!(u2.indexOf(n)>-1||/[A-Z]/u.test(n))}function h2(n,e,i,{latestValues:a},l,c=!1,u){const m=(u??em(n)?c2:l2)(e,a,l,n),p=s2(e,typeof n=="string",c),y=n!==D.Fragment?{...p,...m,ref:i}:{},{children:v}=e,x=D.useMemo(()=>Ut(v)?v.get():v,[v]);return D.createElement(n,{...y,children:x})}function d2({scrapeMotionValuesFromProps:n,createRenderState:e},i,a,l){return{latestValues:f2(i,a,l,n),renderState:e()}}function f2(n,e,i,a){const l={},c=a(n,{});for(const x in c)l[x]=gc(c[x]);let{initial:u,animate:d}=n;const m=$c(n),p=Ex(n);e&&p&&!m&&n.inherit!==!1&&(u===void 0&&(u=e.initial),d===void 0&&(d=e.animate));let y=i?i.initial===!1:!1;y=y||u===!1;const v=y?d:u;if(v&&typeof v!="boolean"&&!Hc(v)){const x=Array.isArray(v)?v:[v];for(let _=0;_(e,i)=>{const a=D.useContext(qc),l=D.useContext(Pc),c=()=>d2(n,e,a,l);return i?c():Af(c)},m2=nw({scrapeMotionValuesFromProps:Qf,createRenderState:Wf}),p2=nw({scrapeMotionValuesFromProps:zx,createRenderState:tw}),g2=Symbol.for("motionComponentSymbol");function y2(n,e,i){const a=D.useRef(i);D.useInsertionEffect(()=>{a.current=i});const l=D.useRef(null);return D.useCallback(c=>{var d;c&&((d=n.onMount)==null||d.call(n,c)),e&&(c?e.mount(c):e.unmount());const u=a.current;if(typeof u=="function")if(c){const m=u(c);typeof m=="function"&&(l.current=m)}else l.current?(l.current(),l.current=null):u(c);else u&&(u.current=c)},[e])}const sw=D.createContext({});function Ca(n){return n&&typeof n=="object"&&Object.prototype.hasOwnProperty.call(n,"current")}function b2(n,e,i,a,l,c){var N,P;const{visualElement:u}=D.useContext(qc),d=D.useContext(Qx),m=D.useContext(Pc),p=D.useContext(Zf),y=p.reducedMotion,v=p.skipAnimations,x=D.useRef(null),_=D.useRef(!1);a=a||d.renderer,!x.current&&a&&(x.current=a(n,{visualState:e,parent:u,props:i,presenceContext:m,blockInitialAnimation:m?m.initial===!1:!1,reducedMotionConfig:y,skipAnimations:v,isSVG:c}),_.current&&x.current&&(x.current.manuallyAnimateOnMount=!0));const S=x.current,T=D.useContext(sw);S&&!S.projection&&l&&(S.type==="html"||S.type==="svg")&&v2(x.current,i,l,T);const k=D.useRef(!1);D.useInsertionEffect(()=>{S&&k.current&&S.update(i,m)});const R=i[fx],M=D.useRef(!!R&&typeof window<"u"&&!((N=window.MotionHandoffIsComplete)!=null&&N.call(window,R))&&((P=window.MotionHasOptimisedAnimation)==null?void 0:P.call(window,R)));return jf(()=>{_.current=!0,S&&(k.current=!0,window.MotionIsMounted=!0,S.updateFeatures(),S.scheduleRenderMicrotask(),M.current&&S.animationState&&S.animationState.animateChanges())}),D.useEffect(()=>{S&&(!M.current&&S.animationState&&S.animationState.animateChanges(),M.current&&(queueMicrotask(()=>{var G;(G=window.MotionHandoffMarkAsComplete)==null||G.call(window,R)}),M.current=!1),S.enteringChildren=void 0)}),S}function v2(n,e,i,a){const{layoutId:l,layout:c,drag:u,dragConstraints:d,layoutScroll:m,layoutRoot:p,layoutAnchor:y,layoutCrossfade:v}=e;n.projection=new i(n.latestValues,e["data-framer-portal-id"]?void 0:iw(n.parent)),n.projection.setOptions({layoutId:l,layout:c,alwaysMeasureLayout:!!u||d&&Ca(d),visualElement:n,animationType:typeof c=="string"?c:"both",initialPromotionConfig:a,crossfade:v,layoutScroll:m,layoutRoot:p,layoutAnchor:y})}function iw(n){if(n)return n.options.allowProjection!==!1?n.projection:iw(n.parent)}function xd(n,{forwardMotionProps:e=!1,type:i}={},a,l){a&&e2(a);const c=i?i==="svg":em(n),u=c?p2:m2;function d(p,y){let v;const x={...D.useContext(Zf),...p,layoutId:x2(p)},{isStatic:_}=x,S=a2(p),T=u(p,_);if(!_&&typeof window<"u"){w2();const k=_2(x);v=k.MeasureLayout,S.visualElement=b2(n,T,x,l,k.ProjectionNode,c)}return g.jsxs(qc.Provider,{value:S,children:[v&&S.visualElement?g.jsx(v,{visualElement:S.visualElement,...x}):null,h2(n,p,y2(T,S.visualElement,y),T,_,e,c)]})}d.displayName=`motion.${typeof n=="string"?n:`create(${n.displayName??n.name??""})`}`;const m=D.forwardRef(d);return m[g2]=n,m}function x2({layoutId:n}){const e=D.useContext(Ef).id;return e&&n!==void 0?e+"-"+n:n}function w2(n,e){D.useContext(Qx).strict}function _2(n){const e=Zx(),{drag:i,layout:a}=e;if(!i&&!a)return{};const l={...i,...a};return{MeasureLayout:i!=null&&i.isEnabled(n)||a!=null&&a.isEnabled(n)?l.MeasureLayout:void 0,ProjectionNode:l.ProjectionNode}}function S2(n,e){if(typeof Proxy>"u")return xd;const i=new Map,a=(c,u)=>xd(c,u,n,e),l=(c,u)=>a(c,u);return new Proxy(l,{get:(c,u)=>u==="create"?a:(i.has(u)||i.set(u,xd(u,void 0,n,e)),i.get(u))})}const T2=(n,e)=>e.isSVG??em(n)?new eA(e):new YE(e,{allowProjection:n!==D.Fragment});class E2 extends ci{constructor(e){super(e),e.animationState||(e.animationState=aA(e))}updateAnimationControlsSubscription(){const{animate:e}=this.node.getProps();Hc(e)&&(this.unmountControls=e.subscribe(this.node))}mount(){this.updateAnimationControlsSubscription()}update(){const{animate:e}=this.node.getProps(),{animate:i}=this.node.prevProps||{};e!==i&&this.updateAnimationControlsSubscription()}unmount(){var e;this.node.animationState.reset(),(e=this.unmountControls)==null||e.call(this)}}let A2=0;class j2 extends ci{constructor(){super(...arguments),this.id=A2++,this.isExitComplete=!1}update(){var c;if(!this.node.presenceContext)return;const{isPresent:e,onExitComplete:i}=this.node.presenceContext,{isPresent:a}=this.node.prevPresenceContext||{};if(!this.node.animationState||e===a)return;if(e&&a===!1){if(this.isExitComplete){const{initial:u,custom:d}=this.node.getProps();if(typeof u=="string"||typeof u=="object"&&u!==null&&!Array.isArray(u)){const m=Vi(this.node,u,d);if(m){const{transition:p,transitionEnd:y,...v}=m;for(const x in v)(c=this.node.getValue(x))==null||c.jump(v[x])}}this.node.animationState.reset(),this.node.animationState.animateChanges()}else this.node.animationState.setActive("exit",!1);this.isExitComplete=!1;return}const l=this.node.animationState.setActive("exit",!e);i&&!e&&l.then(()=>{this.isExitComplete=!0,i(this.id)})}mount(){const{register:e,onExitComplete:i}=this.node.presenceContext||{};i&&i(this.id),e&&(this.unmount=e(this.id))}unmount(){}}const N2={animation:{Feature:E2},exit:{Feature:j2}};function jo(n){return{point:{x:n.pageX,y:n.pageY}}}const k2=n=>e=>Gf(e)&&n(e,jo(e));function so(n,e,i,a){return ho(n,e,k2(i),a)}const aw=({current:n})=>n?n.ownerDocument.defaultView:null,cb=(n,e)=>Math.abs(n-e);function R2(n,e){const i=cb(n.x,e.x),a=cb(n.y,e.y);return Math.sqrt(i**2+a**2)}const ub=new Set(["auto","scroll"]);class rw{constructor(e,i,{transformPagePoint:a,contextWindow:l=window,dragSnapToOrigin:c=!1,distanceThreshold:u=3,element:d}={}){if(this.startEvent=null,this.lastMoveEvent=null,this.lastMoveEventInfo=null,this.lastRawMoveEventInfo=null,this.handlers={},this.contextWindow=window,this.scrollPositions=new Map,this.removeScrollListeners=null,this.onElementScroll=S=>{this.handleScroll(S.target)},this.onWindowScroll=()=>{this.handleScroll(window)},this.updatePoint=()=>{if(!(this.lastMoveEvent&&this.lastMoveEventInfo))return;this.lastRawMoveEventInfo&&(this.lastMoveEventInfo=Ql(this.lastRawMoveEventInfo,this.transformPagePoint));const S=wd(this.lastMoveEventInfo,this.history),T=this.startEvent!==null,k=R2(S.offset,{x:0,y:0})>=this.distanceThreshold;if(!T&&!k)return;const{point:R}=S,{timestamp:M}=Bt;this.history.push({...R,timestamp:M});const{onStart:N,onMove:P}=this.handlers;T||(N&&N(this.lastMoveEvent,S),this.startEvent=this.lastMoveEvent),P&&P(this.lastMoveEvent,S)},this.handlePointerMove=(S,T)=>{this.lastMoveEvent=S,this.lastRawMoveEventInfo=T,this.lastMoveEventInfo=Ql(T,this.transformPagePoint),Xe.update(this.updatePoint,!0)},this.handlePointerUp=(S,T)=>{this.end();const{onEnd:k,onSessionEnd:R,resumeAnimation:M}=this.handlers;if((this.dragSnapToOrigin||!this.startEvent)&&M&&M(),!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const N=wd(S.type==="pointercancel"?this.lastMoveEventInfo:Ql(T,this.transformPagePoint),this.history);this.startEvent&&k&&k(S,N),R&&R(S,N)},!Gf(e))return;this.dragSnapToOrigin=c,this.handlers=i,this.transformPagePoint=a,this.distanceThreshold=u,this.contextWindow=l||window;const m=jo(e),p=Ql(m,this.transformPagePoint),{point:y}=p,{timestamp:v}=Bt;this.history=[{...y,timestamp:v}];const{onSessionStart:x}=i;x&&x(e,wd(p,this.history));const _={passive:!0,capture:!0};this.removeListeners=To(so(this.contextWindow,"pointermove",this.handlePointerMove,_),so(this.contextWindow,"pointerup",this.handlePointerUp,_),so(this.contextWindow,"pointercancel",this.handlePointerUp,_)),d&&this.startScrollTracking(d)}startScrollTracking(e){let i=e.parentElement;for(;i;){const a=getComputedStyle(i);(ub.has(a.overflowX)||ub.has(a.overflowY))&&this.scrollPositions.set(i,{x:i.scrollLeft,y:i.scrollTop}),i=i.parentElement}this.scrollPositions.set(window,{x:window.scrollX,y:window.scrollY}),window.addEventListener("scroll",this.onElementScroll,{capture:!0}),window.addEventListener("scroll",this.onWindowScroll),this.removeScrollListeners=()=>{window.removeEventListener("scroll",this.onElementScroll,{capture:!0}),window.removeEventListener("scroll",this.onWindowScroll)}}handleScroll(e){const i=this.scrollPositions.get(e);if(!i)return;const a=e===window,l=a?{x:window.scrollX,y:window.scrollY}:{x:e.scrollLeft,y:e.scrollTop},c={x:l.x-i.x,y:l.y-i.y};c.x===0&&c.y===0||(a?this.lastMoveEventInfo&&(this.lastMoveEventInfo.point.x+=c.x,this.lastMoveEventInfo.point.y+=c.y):this.history.length>0&&(this.history[0].x-=c.x,this.history[0].y-=c.y),this.scrollPositions.set(e,l),Xe.update(this.updatePoint,!0))}updateHandlers(e){this.handlers=e}end(){this.removeListeners&&this.removeListeners(),this.removeScrollListeners&&this.removeScrollListeners(),this.scrollPositions.clear(),li(this.updatePoint)}}function Ql(n,e){return e?{point:e(n.point)}:n}function hb(n,e){return{x:n.x-e.x,y:n.y-e.y}}function wd({point:n},e){return{point:n,delta:hb(n,ow(e)),offset:hb(n,C2(e)),velocity:O2(e,.1)}}function C2(n){return n[0]}function ow(n){return n[n.length-1]}function O2(n,e){if(n.length<2)return{x:0,y:0};let i=n.length-1,a=null;const l=ow(n);for(;i>=0&&(a=n[i],!(l.timestamp-a.timestamp>dn(e)));)i--;if(!a)return{x:0,y:0};a===n[0]&&n.length>2&&l.timestamp-a.timestamp>dn(e)*2&&(a=n[1]);const c=En(l.timestamp-a.timestamp);if(c===0)return{x:0,y:0};const u={x:(l.x-a.x)/c,y:(l.y-a.y)/c};return u.x===1/0&&(u.x=0),u.y===1/0&&(u.y=0),u}function D2(n,{min:e,max:i},a){return e!==void 0&&ni&&(n=a?Ye(i,n,a.max):Math.min(n,i)),n}function db(n,e,i){return{min:e!==void 0?n.min+e:void 0,max:i!==void 0?n.max+i-(n.max-n.min):void 0}}function M2(n,{top:e,left:i,bottom:a,right:l}){return{x:db(n.x,i,l),y:db(n.y,e,a)}}function fb(n,e){let i=e.min-n.min,a=e.max-n.max;return e.max-e.mina?i=lo(e.min,e.max-a,n.min):a>l&&(i=lo(n.min,n.max-l,e.min)),ts(0,1,i)}function L2(n,e){const i={};return e.min!==void 0&&(i.min=e.min-n.min),e.max!==void 0&&(i.max=e.max-n.min),i}const of=.35;function z2(n=of){return n===!1?n=0:n===!0&&(n=of),{x:mb(n,"left","right"),y:mb(n,"top","bottom")}}function mb(n,e,i){return{min:pb(n,e),max:pb(n,i)}}function pb(n,e){return typeof n=="number"?n:n[e]||0}const P2=new WeakMap;class V2{constructor(e){this.openDragLock=null,this.isDragging=!1,this.currentDirection=null,this.originPoint={x:0,y:0},this.constraints=!1,this.hasMutatedConstraints=!1,this.elastic=St(),this.latestPointerEvent=null,this.latestPanInfo=null,this.visualElement=e}start(e,{snapToCursor:i=!1,distanceThreshold:a}={}){const{presenceContext:l}=this.visualElement;if(l&&l.isPresent===!1)return;const c=v=>{i&&this.snapToCursor(jo(v).point),this.stopAnimation()},u=(v,x)=>{const{drag:_,dragPropagation:S,onDragStart:T}=this.getProps();if(_&&!S&&(this.openDragLock&&this.openDragLock(),this.openDragLock=fE(_),!this.openDragLock))return;this.latestPointerEvent=v,this.latestPanInfo=x,this.isDragging=!0,this.currentDirection=null,this.resolveConstraints(),this.visualElement.projection&&(this.visualElement.projection.isAnimationBlocked=!0,this.visualElement.projection.target=void 0),Jn(R=>{let M=this.getAxisMotionValue(R).get()||0;if(es.test(M)){const{projection:N}=this.visualElement;if(N&&N.layout){const P=N.layout.layoutBox[R];P&&(M=It(P)*(parseFloat(M)/100))}}this.originPoint[R]=M}),T&&Xe.update(()=>T(v,x),!1,!0),Jd(this.visualElement,"transform");const{animationState:k}=this.visualElement;k&&k.setActive("whileDrag",!0)},d=(v,x)=>{this.latestPointerEvent=v,this.latestPanInfo=x;const{dragPropagation:_,dragDirectionLock:S,onDirectionLock:T,onDrag:k}=this.getProps();if(!_&&!this.openDragLock)return;const{offset:R}=x;if(S&&this.currentDirection===null){this.currentDirection=$2(R),this.currentDirection!==null&&T&&T(this.currentDirection);return}this.updateAxis("x",x.point,R),this.updateAxis("y",x.point,R),this.visualElement.render(),k&&Xe.update(()=>k(v,x),!1,!0)},m=(v,x)=>{this.latestPointerEvent=v,this.latestPanInfo=x,this.stop(v,x),this.latestPointerEvent=null,this.latestPanInfo=null},p=()=>{const{dragSnapToOrigin:v}=this.getProps();(v||this.constraints)&&this.startAnimation({x:0,y:0})},{dragSnapToOrigin:y}=this.getProps();this.panSession=new rw(e,{onSessionStart:c,onStart:u,onMove:d,onSessionEnd:m,resumeAnimation:p},{transformPagePoint:this.visualElement.getTransformPagePoint(),dragSnapToOrigin:y,distanceThreshold:a,contextWindow:aw(this.visualElement),element:this.visualElement.current})}stop(e,i){const a=e||this.latestPointerEvent,l=i||this.latestPanInfo,c=this.isDragging;if(this.cancel(),!c||!l||!a)return;const{velocity:u}=l;this.startAnimation(u);const{onDragEnd:d}=this.getProps();d&&Xe.postRender(()=>d(a,l))}cancel(){this.isDragging=!1;const{projection:e,animationState:i}=this.visualElement;e&&(e.isAnimationBlocked=!1),this.endPanSession();const{dragPropagation:a}=this.getProps();!a&&this.openDragLock&&(this.openDragLock(),this.openDragLock=null),i&&i.setActive("whileDrag",!1)}endPanSession(){this.panSession&&this.panSession.end(),this.panSession=void 0}updateAxis(e,i,a){const{drag:l}=this.getProps();if(!a||!Zl(e,l,this.currentDirection))return;const c=this.getAxisMotionValue(e);let u=this.originPoint[e]+a[e];this.constraints&&this.constraints[e]&&(u=D2(u,this.constraints[e],this.elastic[e])),c.set(u)}resolveConstraints(){var c;const{dragConstraints:e,dragElastic:i}=this.getProps(),a=this.visualElement.projection&&!this.visualElement.projection.layout?this.visualElement.projection.measure(!1):(c=this.visualElement.projection)==null?void 0:c.layout,l=this.constraints;e&&Ca(e)?this.constraints||(this.constraints=this.resolveRefConstraints()):e&&a?this.constraints=M2(a.layoutBox,e):this.constraints=!1,this.elastic=z2(i),l!==this.constraints&&!Ca(e)&&a&&this.constraints&&!this.hasMutatedConstraints&&Jn(u=>{this.constraints!==!1&&this.getAxisMotionValue(u)&&(this.constraints[u]=L2(a.layoutBox[u],this.constraints[u]))})}resolveRefConstraints(){const{dragConstraints:e,onMeasureDragConstraints:i}=this.getProps();if(!e||!Ca(e))return!1;const a=e.current,{projection:l}=this.visualElement;if(!l||!l.layout)return!1;l.root&&(l.root.scroll=void 0,l.root.updateScroll());const c=$E(a,l.root,this.visualElement.getTransformPagePoint());let u=B2(l.layout.layoutBox,c);if(i){const d=i(PE(u));this.hasMutatedConstraints=!!d,d&&(u=kx(d))}return u}startAnimation(e){const{drag:i,dragMomentum:a,dragElastic:l,dragTransition:c,dragSnapToOrigin:u,onDragTransitionEnd:d}=this.getProps(),m=this.constraints||{},p=Jn(y=>{if(!Zl(y,i,this.currentDirection))return;let v=m&&m[y]||{};(u===!0||u===y)&&(v={min:0,max:0});const x=l?200:1e6,_=l?40:1e7,S={type:"inertia",velocity:a?e[y]:0,bounceStiffness:x,bounceDamping:_,timeConstant:750,restDelta:1,restSpeed:10,...c,...v};return this.startAxisValueAnimation(y,S)});return Promise.all(p).then(d)}startAxisValueAnimation(e,i){const a=this.getAxisMotionValue(e);return Jd(this.visualElement,e),a.start(Hf(e,a,0,i,this.visualElement,!1))}stopAnimation(){Jn(e=>this.getAxisMotionValue(e).stop())}getAxisMotionValue(e){const i=`_drag${e.toUpperCase()}`,l=this.visualElement.getProps()[i];return l||this.visualElement.getValue(e,this.visualElement.latestValues[e]??0)}snapToCursor(e){Jn(i=>{const{drag:a}=this.getProps();if(!Zl(i,a,this.currentDirection))return;const{projection:l}=this.visualElement,c=this.getAxisMotionValue(i);if(l&&l.layout){const{min:u,max:d}=l.layout.layoutBox[i],m=c.get()||0;c.set(e[i]-Ye(u,d,.5)+m)}})}scalePositionWithinConstraints(){if(!this.visualElement.current)return;const{drag:e,dragConstraints:i}=this.getProps(),{projection:a}=this.visualElement;if(!Ca(i)||!a||!this.constraints)return;this.stopAnimation();const l={x:0,y:0};Jn(u=>{const d=this.getAxisMotionValue(u);if(d&&this.constraints!==!1){const m=d.get();l[u]=U2({min:m,max:m},this.constraints[u])}});const{transformTemplate:c}=this.visualElement.getProps();this.visualElement.current.style.transform=c?c({},""):"none",a.root&&a.root.updateScroll(),a.updateLayout(),this.constraints=!1,this.resolveConstraints(),Jn(u=>{if(!Zl(u,e,null))return;const d=this.getAxisMotionValue(u),{min:m,max:p}=this.constraints[u];d.set(Ye(m,p,l[u]))}),this.visualElement.render()}addListeners(){if(!this.visualElement.current)return;P2.set(this.visualElement,this);const e=this.visualElement.current,i=so(e,"pointerdown",p=>{const{drag:y,dragListener:v=!0}=this.getProps(),x=p.target,_=x!==e&&vE(x);y&&v&&!_&&this.start(p)});let a;const l=()=>{const{dragConstraints:p}=this.getProps();Ca(p)&&p.current&&(this.constraints=this.resolveRefConstraints(),a||(a=H2(e,p.current,()=>this.scalePositionWithinConstraints())))},{projection:c}=this.visualElement,u=c.addEventListener("measure",l);c&&!c.layout&&(c.root&&c.root.updateScroll(),c.updateLayout()),Xe.read(l);const d=ho(window,"resize",()=>this.scalePositionWithinConstraints()),m=c.addEventListener("didUpdate",(({delta:p,hasLayoutChanged:y})=>{this.isDragging&&y&&(Jn(v=>{const x=this.getAxisMotionValue(v);x&&(this.originPoint[v]+=p[v].translate,x.set(x.get()+p[v].translate))}),this.visualElement.render())}));return()=>{d(),i(),u(),m&&m(),a&&a()}}getProps(){const e=this.visualElement.getProps(),{drag:i=!1,dragDirectionLock:a=!1,dragPropagation:l=!1,dragConstraints:c=!1,dragElastic:u=of,dragMomentum:d=!0}=e;return{...e,drag:i,dragDirectionLock:a,dragPropagation:l,dragConstraints:c,dragElastic:u,dragMomentum:d}}}function gb(n){let e=!0;return()=>{if(e){e=!1;return}n()}}function H2(n,e,i){const a=S0(n,gb(i)),l=S0(e,gb(i));return()=>{a(),l()}}function Zl(n,e,i){return(e===!0||e===n)&&(i===null||i===n)}function $2(n,e=10){let i=null;return Math.abs(n.y)>e?i="y":Math.abs(n.x)>e&&(i="x"),i}class q2 extends ci{constructor(e){super(e),this.removeGroupControls=An,this.removeListeners=An,this.controls=new V2(e)}mount(){const{dragControls:e}=this.node.getProps();e&&(this.removeGroupControls=e.subscribe(this.controls)),this.removeListeners=this.controls.addListeners()||An}update(){const{dragControls:e}=this.node.getProps(),{dragControls:i}=this.node.prevProps||{};e!==i&&(this.removeGroupControls(),e&&(this.removeGroupControls=e.subscribe(this.controls)))}unmount(){this.removeGroupControls(),this.removeListeners(),this.controls.isDragging||this.controls.endPanSession()}}const _d=n=>(e,i)=>{n&&Xe.update(()=>n(e,i),!1,!0)};class F2 extends ci{constructor(){super(...arguments),this.removePointerDownListener=An}onPointerDown(e){this.session=new rw(e,this.createPanHandlers(),{transformPagePoint:this.node.getTransformPagePoint(),contextWindow:aw(this.node)})}createPanHandlers(){const{onPanSessionStart:e,onPanStart:i,onPan:a,onPanEnd:l}=this.node.getProps();return{onSessionStart:_d(e),onStart:_d(i),onMove:_d(a),onEnd:(c,u)=>{delete this.session,l&&Xe.postRender(()=>l(c,u))}}}mount(){this.removePointerDownListener=so(this.node.current,"pointerdown",e=>this.onPointerDown(e))}update(){this.session&&this.session.updateHandlers(this.createPanHandlers())}unmount(){this.removePointerDownListener(),this.session&&this.session.end()}}let Sd=!1;class I2 extends D.Component{componentDidMount(){const{visualElement:e,layoutGroup:i,switchLayoutGroup:a,layoutId:l}=this.props,{projection:c}=e;c&&(i.group&&i.group.add(c),a&&a.register&&l&&a.register(c),Sd&&c.root.didUpdate(),c.addEventListener("animationComplete",()=>{this.safeToRemove()}),c.setOptions({...c.options,layoutDependency:this.props.layoutDependency,onExitComplete:()=>this.safeToRemove()})),yc.hasEverUpdated=!0}getSnapshotBeforeUpdate(e){const{layoutDependency:i,visualElement:a,drag:l,isPresent:c}=this.props,{projection:u}=a;return u&&(u.isPresent=c,e.layoutDependency!==i&&u.setOptions({...u.options,layoutDependency:i}),Sd=!0,l||e.layoutDependency!==i||i===void 0||e.isPresent!==c?u.willUpdate():this.safeToRemove(),e.isPresent!==c&&(c?u.promote():u.relegate()||Xe.postRender(()=>{const d=u.getStack();(!d||!d.members.length)&&this.safeToRemove()}))),null}componentDidUpdate(){const{visualElement:e,layoutAnchor:i}=this.props,{projection:a}=e;a&&(a.options.layoutAnchor=i,a.root.didUpdate(),If.postRender(()=>{!a.currentAnimation&&a.isLead()&&this.safeToRemove()}))}componentWillUnmount(){const{visualElement:e,layoutGroup:i,switchLayoutGroup:a}=this.props,{projection:l}=e;Sd=!0,l&&(l.scheduleCheckAfterUnmount(),i&&i.group&&i.group.remove(l),a&&a.deregister&&a.deregister(l))}safeToRemove(){const{safeToRemove:e}=this.props;e&&e()}render(){return null}}function lw(n){const[e,i]=Jx(),a=D.useContext(Ef);return g.jsx(I2,{...n,layoutGroup:a,switchLayoutGroup:D.useContext(sw),isPresent:e,safeToRemove:i})}const G2={pan:{Feature:F2},drag:{Feature:q2,ProjectionNode:Xx,MeasureLayout:lw}};function yb(n,e,i){const{props:a}=n;n.animationState&&a.whileHover&&n.animationState.setActive("whileHover",i==="Start");const l="onHover"+i,c=a[l];c&&Xe.postRender(()=>c(e,jo(e)))}class K2 extends ci{mount(){const{current:e}=this.node;e&&(this.unmount=pE(e,(i,a)=>(yb(this.node,a,"Start"),l=>yb(this.node,l,"End"))))}unmount(){}}class Y2 extends ci{constructor(){super(...arguments),this.isActive=!1}onFocus(){let e=!1;try{e=this.node.current.matches(":focus-visible")}catch{e=!0}!e||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!0),this.isActive=!0)}onBlur(){!this.isActive||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!1),this.isActive=!1)}mount(){this.unmount=To(ho(this.node.current,"focus",()=>this.onFocus()),ho(this.node.current,"blur",()=>this.onBlur()))}unmount(){}}function bb(n,e,i){const{props:a}=n;if(n.current instanceof HTMLButtonElement&&n.current.disabled)return;n.animationState&&a.whileTap&&n.animationState.setActive("whileTap",i==="Start");const l="onTap"+(i==="End"?"":i),c=a[l];c&&Xe.postRender(()=>c(e,jo(e)))}class X2 extends ci{mount(){const{current:e}=this.node;if(!e)return;const{globalTapTarget:i,propagate:a}=this.node.props;this.unmount=wE(e,(l,c)=>(bb(this.node,c,"Start"),(u,{success:d})=>bb(this.node,u,d?"End":"Cancel")),{useGlobalTarget:i,stopPropagation:(a==null?void 0:a.tap)===!1})}unmount(){}}const lf=new WeakMap,Td=new WeakMap,J2=n=>{const e=lf.get(n.target);e&&e(n)},Q2=n=>{n.forEach(J2)};function Z2({root:n,...e}){const i=n||document;Td.has(i)||Td.set(i,{});const a=Td.get(i),l=JSON.stringify(e);return a[l]||(a[l]=new IntersectionObserver(Q2,{root:n,...e})),a[l]}function W2(n,e,i){const a=Z2(e);return lf.set(n,i),a.observe(n),()=>{lf.delete(n),a.unobserve(n)}}const ej={some:0,all:1};class tj extends ci{constructor(){super(...arguments),this.hasEnteredView=!1,this.isInView=!1}startObserver(){var m;(m=this.stopObserver)==null||m.call(this);const{viewport:e={}}=this.node.getProps(),{root:i,margin:a,amount:l="some",once:c}=e,u={root:i?i.current:void 0,rootMargin:a,threshold:typeof l=="number"?l:ej[l]},d=p=>{const{isIntersecting:y}=p;if(this.isInView===y||(this.isInView=y,c&&!y&&this.hasEnteredView))return;y&&(this.hasEnteredView=!0),this.node.animationState&&this.node.animationState.setActive("whileInView",y);const{onViewportEnter:v,onViewportLeave:x}=this.node.getProps(),_=y?v:x;_&&_(p)};this.stopObserver=W2(this.node.current,u,d)}mount(){this.startObserver()}update(){if(typeof IntersectionObserver>"u")return;const{props:e,prevProps:i}=this.node;["amount","margin","root"].some(nj(e,i))&&this.startObserver()}unmount(){var e;(e=this.stopObserver)==null||e.call(this),this.hasEnteredView=!1,this.isInView=!1}}function nj({viewport:n={}},{viewport:e={}}={}){return i=>n[i]!==e[i]}const sj={inView:{Feature:tj},tap:{Feature:X2},focus:{Feature:Y2},hover:{Feature:K2}},ij={layout:{ProjectionNode:Xx,MeasureLayout:lw}},aj={...N2,...sj,...G2,...ij},rj=S2(aj,T2),un=rj;/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const oj=n=>n.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),lj=n=>n.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,i,a)=>a?a.toUpperCase():i.toLowerCase()),vb=n=>{const e=lj(n);return e.charAt(0).toUpperCase()+e.slice(1)},cw=(...n)=>n.filter((e,i,a)=>!!e&&e.trim()!==""&&a.indexOf(e)===i).join(" ").trim(),cj=n=>{for(const e in n)if(e.startsWith("aria-")||e==="role"||e==="title")return!0};/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */var uj={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const hj=D.forwardRef(({color:n="currentColor",size:e=24,strokeWidth:i=2,absoluteStrokeWidth:a,className:l="",children:c,iconNode:u,...d},m)=>D.createElement("svg",{ref:m,...uj,width:e,height:e,stroke:n,strokeWidth:a?Number(i)*24/Number(e):i,className:cw("lucide",l),...!c&&!cj(d)&&{"aria-hidden":"true"},...d},[...u.map(([p,y])=>D.createElement(p,y)),...Array.isArray(c)?c:[c]]));/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Me=(n,e)=>{const i=D.forwardRef(({className:a,...l},c)=>D.createElement(hj,{ref:c,iconNode:e,className:cw(`lucide-${oj(vb(n))}`,`lucide-${n}`,a),...l}));return i.displayName=vb(n),i};/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const dj=[["path",{d:"M8 3 4 7l4 4",key:"9rb6wj"}],["path",{d:"M4 7h16",key:"6tx8e3"}],["path",{d:"m16 21 4-4-4-4",key:"siv7j2"}],["path",{d:"M20 17H4",key:"h6l3hr"}]],fj=Me("arrow-left-right",dj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const mj=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]],pj=Me("arrow-right",mj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const gj=[["rect",{width:"20",height:"12",x:"2",y:"6",rx:"2",key:"9lu3g6"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}],["path",{d:"M6 12h.01M18 12h.01",key:"113zkx"}]],xb=Me("banknote",gj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const yj=[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}],["path",{d:"M8 14h.01",key:"6423bh"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M16 14h.01",key:"1gbofw"}],["path",{d:"M8 18h.01",key:"lrp35t"}],["path",{d:"M12 18h.01",key:"mhygvu"}],["path",{d:"M16 18h.01",key:"kzsmim"}]],bj=Me("calendar-days",yj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const vj=[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}]],xj=Me("calendar",vj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const wj=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],_j=Me("chevron-down",wj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Sj=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]],Tj=Me("circle-alert",Sj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Ej=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],kc=Me("circle-check",Ej);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Aj=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"10",r:"3",key:"ilqhr7"}],["path",{d:"M7 20.662V19a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v1.662",key:"154egf"}]],jj=Me("circle-user",Aj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Nj=[["path",{d:"M21.54 15H17a2 2 0 0 0-2 2v4.54",key:"1djwo0"}],["path",{d:"M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17",key:"1tzkfa"}],["path",{d:"M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05",key:"14pb5j"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],uw=Me("earth",Nj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const kj=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],Rj=Me("external-link",kj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Cj=[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],Oj=Me("eye",Cj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Dj=[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M8 13h2",key:"yr2amv"}],["path",{d:"M14 13h2",key:"un5t4a"}],["path",{d:"M8 17h2",key:"2yhykz"}],["path",{d:"M14 17h2",key:"10kma7"}]],Oa=Me("file-spreadsheet",Dj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Mj=[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]],Wl=Me("file-text",Mj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Bj=[["path",{d:"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z",key:"sc7q7i"}]],Uj=Me("funnel",Bj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Lj=[["rect",{x:"3",y:"8",width:"18",height:"4",rx:"1",key:"bkv52"}],["path",{d:"M12 8v13",key:"1c76mn"}],["path",{d:"M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7",key:"6wjy6b"}],["path",{d:"M7.5 8a2.5 2.5 0 0 1 0-5A4.8 8 0 0 1 12 8a4.8 8 0 0 1 4.5-5 2.5 2.5 0 0 1 0 5",key:"1ihvrl"}]],wb=Me("gift",Lj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const zj=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M12 7v5l4 2",key:"1fdv2h"}]],Pj=Me("history",zj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Vj=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],hw=Me("info",Vj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Hj=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],$a=Me("loader-circle",Hj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const $j=[["circle",{cx:"12",cy:"16",r:"1",key:"1au0dj"}],["rect",{x:"3",y:"10",width:"18",height:"12",rx:"2",key:"6s8ecr"}],["path",{d:"M7 10V7a5 5 0 0 1 10 0v3",key:"1pqi11"}]],qj=Me("lock-keyhole",$j);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Fj=[["path",{d:"m16 17 5-5-5-5",key:"1bji2h"}],["path",{d:"M21 12H9",key:"dn1m92"}],["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}]],Ij=Me("log-out",Fj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Gj=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],dw=Me("menu",Gj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Kj=[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}],["path",{d:"M12 15h.01",key:"q59x07"}],["path",{d:"M12 7v4",key:"xawao1"}]],Yj=Me("message-square-warning",Kj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Xj=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]],Jj=Me("play",Xj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Qj=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]],Zj=Me("plus",Qj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const Wj=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],eN=Me("refresh-cw",Wj);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const tN=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],Jr=Me("search",tN);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const nN=[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]],fw=Me("send",nN);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const sN=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],Ea=Me("trash-2",sN);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const iN=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],fo=Me("triangle-alert",iN);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const aN=[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]],Gr=Me("upload",aN);/** - * @license lucide-react v0.546.0 - ISC - * - * This source code is licensed under the ISC license. - * See the LICENSE file in the root directory of this source tree. - */const rN=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Ka=Me("x",rN),mo=[{code:"GT",name:"Guatemala",flag:"/cruce-cuentas/gt-flag.png",currency:"GTQ",locale:"es-GT",enabled:!0},{code:"TT",name:"Trinidad y Tobago",flag:"/cruce-cuentas/tt-flag.png",currency:"TTD",locale:"en-TT",enabled:!0},{code:"PA",name:"Panamá",flag:"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_Panama.svg",currency:"USD",locale:"es-PA",enabled:!0},{code:"SV",name:"El Salvador",flag:"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_El_Salvador.svg.webp",currency:"USD",locale:"es-SV",enabled:!0},{code:"HN",name:"Honduras",flag:"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Bandera%20de%20Honduras.webp",currency:"HNL",locale:"es-HN",enabled:!0},{code:"PR",name:"Puerto Rico",flag:"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/bandera-nacional-tela-puerto-rico_113767-1759.avif",currency:"USD",locale:"es-PR",enabled:!0}];function _b(n){return mo.find(e=>e.code===n)??mo[0]}const oN="https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png";function lN({currentView:n,onViewChange:e,onNewCruce:i,isSidebarOpen:a=!1,onCloseSidebar:l,user:c,isAuthEnabled:u=!1,onLogout:d,country:m,onCountryChange:p,onChooseAnotherCountry:y}){const[v,x]=D.useState(!1),_=D.useRef(null);return D.useEffect(()=>{function S(T){_.current&&!_.current.contains(T.target)&&x(!1)}return document.addEventListener("mousedown",S),()=>document.removeEventListener("mousedown",S)},[]),g.jsxs("aside",{className:`bg-neutral-100 h-screen w-64 fixed left-0 top-0 flex flex-col z-50 pb-6 min-h-screen font-sans transition-transform duration-300 md:translate-x-0 ${a?"translate-x-0":"-translate-x-full"}`,children:[g.jsx("div",{className:"absolute right-0 top-0 h-[80px] w-px bg-[#D0D0D0] pointer-events-none z-10 hidden md:block"}),g.jsx("div",{className:"absolute right-0 top-[84px] bottom-0 w-px bg-[#D0D0D0] pointer-events-none z-10 hidden md:block"}),g.jsxs("div",{className:"h-[84px] px-4 flex justify-between md:justify-center items-center bg-white border-b-4 border-[#6CC24A] relative",children:[g.jsx("img",{alt:"GomezLee Marketing logo",className:"h-10 object-contain selection:bg-transparent",src:oN}),g.jsx("button",{onClick:l,className:"md:hidden p-2 text-neutral-500 hover:text-neutral-800 transition-colors","aria-label":"Cerrar menú",children:g.jsx(Ka,{className:"w-5 h-5"})})]}),g.jsxs("div",{className:"px-4 pt-5",children:[g.jsxs("label",{className:"block",children:[g.jsxs("span",{className:"text-[9px] uppercase tracking-wider font-black text-neutral-400 flex items-center gap-1.5 mb-1.5",children:[g.jsx(uw,{className:"w-3.5 h-3.5"}),"País"]}),g.jsxs("div",{className:"relative",ref:_,children:[g.jsxs("button",{type:"button",onClick:()=>x(!v),className:"w-full border border-neutral-300 bg-white px-3 py-2 text-xs font-bold text-[#4F758B] focus:outline-none focus:border-[#4F758B] flex items-center justify-between transition-colors hover:bg-neutral-50",children:[g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx("img",{src:m.flag,alt:"",className:"w-5 h-3.5 object-cover shadow-sm border border-neutral-200"}),g.jsx("span",{children:m.name})]}),g.jsx(_j,{className:`w-4 h-4 text-[#4F758B] transition-transform ${v?"rotate-180":""}`})]}),v&&g.jsx("ul",{className:"absolute left-0 right-0 top-full mt-1 bg-white border border-neutral-300 shadow-lg z-50 py-1",children:mo.map(S=>g.jsx("li",{children:g.jsxs("button",{type:"button",disabled:!S.enabled,onClick:()=>{p(S.code),x(!1)},className:`w-full text-left px-3 py-2.5 text-xs font-bold flex items-center gap-2.5 transition-colors ${S.enabled?"hover:bg-neutral-100 text-[#4F758B]":"opacity-60 cursor-not-allowed text-neutral-500 bg-neutral-50"}`,children:[g.jsx("img",{src:S.flag,alt:"",className:"w-6 h-4 object-cover shadow-sm border border-neutral-200 bg-white flex-shrink-0"}),g.jsxs("span",{className:"min-w-0 text-left leading-tight",children:[g.jsx("span",{className:"block",children:S.name}),!S.enabled&&g.jsx("span",{className:"block mt-1 text-[10px] text-neutral-400 font-medium italic",children:"Próximamente"})]})]})},S.code))})]})]}),g.jsx("button",{type:"button",onClick:y,className:"mt-2 text-[9px] font-bold uppercase tracking-wider text-neutral-400 hover:text-[#4F758B]",children:"Ver países disponibles"})]}),g.jsx("nav",{className:"flex-1 flex flex-col mt-5",children:g.jsxs("ul",{className:"space-y-1",children:[g.jsx("li",{children:g.jsxs("button",{onClick:()=>e("cruce"),className:`w-full flex items-center gap-3 px-6 py-3.5 transition-all duration-150 text-left font-bold text-sm tracking-wide ${n==="cruce"?"bg-[#4F758B] text-white":"text-neutral-600 hover:bg-neutral-200 hover:text-neutral-800"}`,children:[g.jsx(fj,{className:`w-4 h-4 ${n==="cruce"?"text-[#6CC24A]":""}`}),g.jsx("span",{children:"Cruce de Cuentas"})]})}),g.jsx("li",{children:g.jsxs("button",{onClick:()=>e("historial"),className:`w-full flex items-center gap-3 px-6 py-3.5 transition-all duration-150 text-left font-bold text-sm tracking-wide ${n==="historial"?"bg-[#4F758B] text-white":"text-neutral-600 hover:bg-neutral-200 hover:text-neutral-800"}`,children:[g.jsx(Pj,{className:`w-4 h-4 ${n==="historial"?"text-[#6CC24A]":""}`}),g.jsx("span",{children:"Reportes Históricos"})]})})]})}),g.jsxs("div",{className:"px-4 space-y-3 pt-4 border-t border-[#D0D0D0] bg-neutral-100",children:[c&&g.jsxs("div",{className:"border border-neutral-200 bg-white px-3 py-3 flex items-center gap-2",children:[g.jsx(jj,{className:"w-4 h-4 text-[#4F758B] flex-shrink-0"}),g.jsxs("div",{className:"min-w-0",children:[g.jsx("p",{className:"text-[11px] font-black text-neutral-700 truncate",title:c.name,children:c.name}),g.jsx("p",{className:"text-[9px] text-neutral-400 truncate",title:c.email,children:c.email})]})]}),g.jsxs("button",{onClick:i,className:"w-full bg-[#6CC24A] hover:bg-[#5bb03c] text-white py-3 px-4 font-bold text-xs uppercase tracking-wider flex items-center justify-center gap-2 transition-all duration-150 shadow-sm active:scale-98",children:[g.jsx(Zj,{className:"w-4 h-4"}),g.jsx("span",{children:"Nuevo Cruce"})]}),u&&d&&g.jsxs("button",{onClick:d,className:"w-full border border-neutral-300 bg-white hover:bg-neutral-50 text-neutral-600 py-2.5 px-4 font-bold text-[11px] uppercase tracking-wider flex items-center justify-center gap-2 transition-all duration-150",children:[g.jsx(Ij,{className:"w-4 h-4"}),g.jsx("span",{children:"Cerrar sesión"})]})]})]})}function Fc(n,e){var i={};for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&e.indexOf(a)<0&&(i[a]=n[a]);if(n!=null&&typeof Object.getOwnPropertySymbols=="function")for(var l=0,a=Object.getOwnPropertySymbols(n);ln?(...e)=>n(...e):(...e)=>fetch(...e);class tm extends Error{constructor(e,i="FunctionsError",a){super(e),this.name=i,this.context=a}toJSON(){return{name:this.name,message:this.message,context:this.context}}}class hN extends tm{constructor(e){super("Failed to send a request to the Edge Function","FunctionsFetchError",e)}}class Sb extends tm{constructor(e){super("Relay Error invoking the Edge Function","FunctionsRelayError",e)}}class Tb extends tm{constructor(e){super("Edge Function returned a non-2xx status code","FunctionsHttpError",e)}}var cf;(function(n){n.Any="any",n.ApNortheast1="ap-northeast-1",n.ApNortheast2="ap-northeast-2",n.ApSouth1="ap-south-1",n.ApSoutheast1="ap-southeast-1",n.ApSoutheast2="ap-southeast-2",n.CaCentral1="ca-central-1",n.EuCentral1="eu-central-1",n.EuWest1="eu-west-1",n.EuWest2="eu-west-2",n.EuWest3="eu-west-3",n.SaEast1="sa-east-1",n.UsEast1="us-east-1",n.UsWest1="us-west-1",n.UsWest2="us-west-2"})(cf||(cf={}));class dN{constructor(e,{headers:i={},customFetch:a,region:l=cf.Any}={}){this.url=e,this.headers=i,this.region=l,this.fetch=uN(a)}setAuth(e){this.headers.Authorization=`Bearer ${e}`}invoke(e){return cN(this,arguments,void 0,function*(i,a={}){var l;let c,u;try{const{headers:d,method:m,body:p,signal:y,timeout:v}=a;let x={},{region:_}=a;_||(_=this.region);const S=new URL(`${this.url}/${i}`);_&&_!=="any"&&(x["x-region"]=_,S.searchParams.set("forceFunctionRegion",_));let T;const k=!!d&&Object.keys(d).some(X=>X.toLowerCase()==="content-type");p&&!k?typeof Blob<"u"&&p instanceof Blob||p instanceof ArrayBuffer?(x["Content-Type"]="application/octet-stream",T=p):typeof p=="string"?(x["Content-Type"]="text/plain",T=p):typeof FormData<"u"&&p instanceof FormData?T=p:(x["Content-Type"]="application/json",T=JSON.stringify(p)):p&&typeof p!="string"&&!(typeof Blob<"u"&&p instanceof Blob)&&!(p instanceof ArrayBuffer)&&!(typeof FormData<"u"&&p instanceof FormData)?T=JSON.stringify(p):T=p;let R=y;v&&(u=new AbortController,c=setTimeout(()=>u.abort(),v),y?(R=u.signal,y.addEventListener("abort",()=>u.abort())):R=u.signal);const M=yield this.fetch(S.toString(),{method:m||"POST",headers:Object.assign(Object.assign(Object.assign({},x),this.headers),d),body:T,signal:R}).catch(X=>{throw new hN(X)}),N=M.headers.get("x-relay-error");if(N&&N==="true")throw new Sb(M);if(!M.ok)throw new Tb(M);let P=((l=M.headers.get("Content-Type"))!==null&&l!==void 0?l:"text/plain").split(";")[0].trim(),G;return P==="application/json"?G=yield M.json():P==="application/octet-stream"||P==="application/pdf"?G=yield M.blob():P==="text/event-stream"?G=M:P==="multipart/form-data"?G=yield M.formData():G=yield M.text(),{data:G,error:null,response:M}}catch(d){return{data:null,error:d,response:d instanceof Tb||d instanceof Sb?d.context:void 0}}finally{c&&clearTimeout(c)}})}}const mw=3,Eb=n=>Math.min(1e3*2**n,3e4),fN=[520,503],pw=["GET","HEAD","OPTIONS"];var Ab=class extends Error{constructor(n){super(n.message),this.name="PostgrestError",this.details=n.details,this.hint=n.hint,this.code=n.code}toJSON(){return{name:this.name,message:this.message,details:this.details,hint:this.hint,code:this.code}}};function jb(n,e){return new Promise(i=>{if(e!=null&&e.aborted){i();return}const a=setTimeout(()=>{e==null||e.removeEventListener("abort",l),i()},n);function l(){clearTimeout(a),i()}e==null||e.addEventListener("abort",l)})}function mN(n,e,i,a){return!(!a||i>=mw||!pw.includes(n)||!fN.includes(e))}var pN=class{constructor(n){var e,i,a,l,c;this.shouldThrowOnError=!1,this.retryEnabled=!0,this.method=n.method,this.url=n.url,this.headers=new Headers(n.headers),this.schema=n.schema,this.body=n.body,this.shouldThrowOnError=(e=n.shouldThrowOnError)!==null&&e!==void 0?e:!1,this.signal=n.signal,this.isMaybeSingle=(i=n.isMaybeSingle)!==null&&i!==void 0?i:!1,this.shouldStripNulls=(a=n.shouldStripNulls)!==null&&a!==void 0?a:!1,this.urlLengthLimit=(l=n.urlLengthLimit)!==null&&l!==void 0?l:8e3,this.retryEnabled=(c=n.retry)!==null&&c!==void 0?c:!0,n.fetch?this.fetch=n.fetch:this.fetch=fetch}throwOnError(){return this.shouldThrowOnError=!0,this}stripNulls(){if(this.headers.get("Accept")==="text/csv")throw new Error("stripNulls() cannot be used with csv()");return this.shouldStripNulls=!0,this}setHeader(n,e){return this.headers=new Headers(this.headers),this.headers.set(n,e),this}retry(n){return this.retryEnabled=n,this}then(n,e){var i=this;if(this.schema===void 0||(["GET","HEAD"].includes(this.method)?this.headers.set("Accept-Profile",this.schema):this.headers.set("Content-Profile",this.schema)),this.method!=="GET"&&this.method!=="HEAD"&&this.headers.set("Content-Type","application/json"),this.shouldStripNulls){const u=this.headers.get("Accept");u==="application/vnd.pgrst.object+json"?this.headers.set("Accept","application/vnd.pgrst.object+json;nulls=stripped"):(!u||u==="application/json")&&this.headers.set("Accept","application/vnd.pgrst.array+json;nulls=stripped")}const a=this.fetch;let c=(async()=>{let u=0;for(;;){const p={};i.headers.forEach((v,x)=>{p[x]=v}),u>0&&(p["X-Retry-Count"]=String(u));let y;try{y=await a(i.url.toString(),{method:i.method,headers:p,body:JSON.stringify(i.body,(v,x)=>typeof x=="bigint"?x.toString():x),signal:i.signal})}catch(v){if((v==null?void 0:v.name)==="AbortError"||(v==null?void 0:v.code)==="ABORT_ERR"||!pw.includes(i.method))throw v;if(i.retryEnabled&&u{var d;let m="",p="",y="";const v=u==null?void 0:u.cause;if(v){var x,_,S,T;const M=(x=v==null?void 0:v.message)!==null&&x!==void 0?x:"",N=(_=v==null?void 0:v.code)!==null&&_!==void 0?_:"";m=`${(S=u==null?void 0:u.name)!==null&&S!==void 0?S:"FetchError"}: ${u==null?void 0:u.message}`,m+=` - -Caused by: ${(T=v==null?void 0:v.name)!==null&&T!==void 0?T:"Error"}: ${M}`,N&&(m+=` (${N})`),v!=null&&v.stack&&(m+=` -${v.stack}`)}else{var k;m=(k=u==null?void 0:u.stack)!==null&&k!==void 0?k:""}const R=this.url.toString().length;return(u==null?void 0:u.name)==="AbortError"||(u==null?void 0:u.code)==="ABORT_ERR"?(y="",p="Request was aborted (timeout or manual cancellation)",R>this.urlLengthLimit&&(p+=`. Note: Your request URL is ${R} characters, which may exceed server limits. If selecting many fields, consider using views. If filtering with large arrays (e.g., .in('id', [many IDs])), consider using an RPC function to pass values server-side.`)):((v==null?void 0:v.name)==="HeadersOverflowError"||(v==null?void 0:v.code)==="UND_ERR_HEADERS_OVERFLOW")&&(y="",p="HTTP headers exceeded server limits (typically 16KB)",R>this.urlLengthLimit&&(p+=`. Your request URL is ${R} characters. If selecting many fields, consider using views. If filtering with large arrays (e.g., .in('id', [200+ IDs])), consider using an RPC function instead.`)),{success:!1,error:{message:`${(d=u==null?void 0:u.name)!==null&&d!==void 0?d:"FetchError"}: ${u==null?void 0:u.message}`,details:m,hint:p,code:y},data:null,count:null,status:0,statusText:""}})),c.then(n,e)}async processResponse(n){var e=this;let i=null,a=null,l=null,c=n.status,u=n.statusText;if(n.ok){var d,m;if(e.method!=="HEAD"){var p;const x=await n.text();if(x!=="")if(e.headers.get("Accept")==="text/csv")a=x;else if(e.headers.get("Accept")&&(!((p=e.headers.get("Accept"))===null||p===void 0)&&p.includes("application/vnd.pgrst.plan+text")))a=x;else try{a=JSON.parse(x)}catch{if(i={message:x},a=null,e.shouldThrowOnError)throw new Ab({message:x,details:"",hint:"",code:""})}}const y=(d=e.headers.get("Prefer"))===null||d===void 0?void 0:d.match(/count=(exact|planned|estimated)/),v=(m=n.headers.get("content-range"))===null||m===void 0?void 0:m.split("/");y&&v&&v.length>1&&(l=parseInt(v[1])),e.isMaybeSingle&&Array.isArray(a)&&(a.length>1?(i={code:"PGRST116",details:`Results contain ${a.length} rows, application/vnd.pgrst.object+json requires 1 row`,hint:null,message:"JSON object requested, multiple (or no) rows returned"},a=null,l=null,c=406,u="Not Acceptable"):a.length===1?a=a[0]:a=null)}else{const y=await n.text();try{i=JSON.parse(y),Array.isArray(i)&&n.status===404&&(a=[],i=null,c=200,u="OK")}catch{n.status===404&&y===""?(c=204,u="No Content"):i={message:y}}if(i&&e.shouldThrowOnError)throw new Ab(i)}return{success:i===null,error:i,data:a,count:l,status:c,statusText:u}}returns(){return this}overrideTypes(){return this}},gN=class extends pN{throwOnError(){return super.throwOnError()}select(n){let e=!1;const i=(n??"*").split("").map(a=>/\s/.test(a)&&!e?"":(a==='"'&&(e=!e),a)).join("");return this.url.searchParams.set("select",i),this.headers.append("Prefer","return=representation"),this}order(n,{ascending:e=!0,nullsFirst:i,foreignTable:a,referencedTable:l=a}={}){const c=l?`${l}.order`:"order",u=this.url.searchParams.get(c);return this.url.searchParams.set(c,`${u?`${u},`:""}${n}.${e?"asc":"desc"}${i===void 0?"":i?".nullsfirst":".nullslast"}`),this}limit(n,{foreignTable:e,referencedTable:i=e}={}){const a=typeof i>"u"?"limit":`${i}.limit`;return this.url.searchParams.set(a,`${n}`),this}range(n,e,{foreignTable:i,referencedTable:a=i}={}){const l=typeof a>"u"?"offset":`${a}.offset`,c=typeof a>"u"?"limit":`${a}.limit`;return this.url.searchParams.set(l,`${n}`),this.url.searchParams.set(c,`${e-n+1}`),this}abortSignal(n){return this.signal=n,this}single(){return this.headers.set("Accept","application/vnd.pgrst.object+json"),this}maybeSingle(){return this.isMaybeSingle=!0,this}csv(){return this.headers.set("Accept","text/csv"),this}geojson(){return this.headers.set("Accept","application/geo+json"),this}explain({analyze:n=!1,verbose:e=!1,settings:i=!1,buffers:a=!1,wal:l=!1,format:c="text"}={}){var u;const d=[n?"analyze":null,e?"verbose":null,i?"settings":null,a?"buffers":null,l?"wal":null].filter(Boolean).join("|"),m=(u=this.headers.get("Accept"))!==null&&u!==void 0?u:"application/json";return this.headers.set("Accept",`application/vnd.pgrst.plan+${c}; for="${m}"; options=${d};`),c==="json"?this:this}rollback(){return this.headers.append("Prefer","tx=rollback"),this}returns(){return this}maxAffected(n){return this.headers.append("Prefer","handling=strict"),this.headers.append("Prefer",`max-affected=${n}`),this}};const Nb=new RegExp("[,()]");var Da=class extends gN{throwOnError(){return super.throwOnError()}eq(n,e){return this.url.searchParams.append(n,`eq.${e}`),this}neq(n,e){return this.url.searchParams.append(n,`neq.${e}`),this}gt(n,e){return this.url.searchParams.append(n,`gt.${e}`),this}gte(n,e){return this.url.searchParams.append(n,`gte.${e}`),this}lt(n,e){return this.url.searchParams.append(n,`lt.${e}`),this}lte(n,e){return this.url.searchParams.append(n,`lte.${e}`),this}like(n,e){return this.url.searchParams.append(n,`like.${e}`),this}likeAllOf(n,e){return this.url.searchParams.append(n,`like(all).{${e.join(",")}}`),this}likeAnyOf(n,e){return this.url.searchParams.append(n,`like(any).{${e.join(",")}}`),this}ilike(n,e){return this.url.searchParams.append(n,`ilike.${e}`),this}ilikeAllOf(n,e){return this.url.searchParams.append(n,`ilike(all).{${e.join(",")}}`),this}ilikeAnyOf(n,e){return this.url.searchParams.append(n,`ilike(any).{${e.join(",")}}`),this}regexMatch(n,e){return this.url.searchParams.append(n,`match.${e}`),this}regexIMatch(n,e){return this.url.searchParams.append(n,`imatch.${e}`),this}is(n,e){return this.url.searchParams.append(n,`is.${e}`),this}isDistinct(n,e){return this.url.searchParams.append(n,`isdistinct.${e}`),this}in(n,e){const i=Array.from(new Set(e)).map(a=>typeof a=="string"&&Nb.test(a)?`"${a}"`:`${a}`).join(",");return this.url.searchParams.append(n,`in.(${i})`),this}notIn(n,e){const i=Array.from(new Set(e)).map(a=>typeof a=="string"&&Nb.test(a)?`"${a}"`:`${a}`).join(",");return this.url.searchParams.append(n,`not.in.(${i})`),this}contains(n,e){return typeof e=="string"?this.url.searchParams.append(n,`cs.${e}`):Array.isArray(e)?this.url.searchParams.append(n,`cs.{${e.join(",")}}`):this.url.searchParams.append(n,`cs.${JSON.stringify(e)}`),this}containedBy(n,e){return typeof e=="string"?this.url.searchParams.append(n,`cd.${e}`):Array.isArray(e)?this.url.searchParams.append(n,`cd.{${e.join(",")}}`):this.url.searchParams.append(n,`cd.${JSON.stringify(e)}`),this}rangeGt(n,e){return this.url.searchParams.append(n,`sr.${e}`),this}rangeGte(n,e){return this.url.searchParams.append(n,`nxl.${e}`),this}rangeLt(n,e){return this.url.searchParams.append(n,`sl.${e}`),this}rangeLte(n,e){return this.url.searchParams.append(n,`nxr.${e}`),this}rangeAdjacent(n,e){return this.url.searchParams.append(n,`adj.${e}`),this}overlaps(n,e){return typeof e=="string"?this.url.searchParams.append(n,`ov.${e}`):this.url.searchParams.append(n,`ov.{${e.join(",")}}`),this}textSearch(n,e,{config:i,type:a}={}){let l="";a==="plain"?l="pl":a==="phrase"?l="ph":a==="websearch"&&(l="w");const c=i===void 0?"":`(${i})`;return this.url.searchParams.append(n,`${l}fts${c}.${e}`),this}match(n){return Object.entries(n).filter(([e,i])=>i!==void 0).forEach(([e,i])=>{this.url.searchParams.append(e,`eq.${i}`)}),this}not(n,e,i){return this.url.searchParams.append(n,`not.${e}.${i}`),this}or(n,{foreignTable:e,referencedTable:i=e}={}){const a=i?`${i}.or`:"or";return this.url.searchParams.append(a,`(${n})`),this}filter(n,e,i){return this.url.searchParams.append(n,`${e}.${i}`),this}},yN=class{constructor(n,{headers:e={},schema:i,fetch:a,urlLengthLimit:l=8e3,retry:c}){this.url=n,this.headers=new Headers(e),this.schema=i,this.fetch=a,this.urlLengthLimit=l,this.retry=c}cloneRequestState(){return{url:new URL(this.url.toString()),headers:new Headers(this.headers)}}select(n,e){const{head:i=!1,count:a}=e??{},l=i?"HEAD":"GET";let c=!1;const u=(n??"*").split("").map(p=>/\s/.test(p)&&!c?"":(p==='"'&&(c=!c),p)).join(""),{url:d,headers:m}=this.cloneRequestState();return d.searchParams.set("select",u),a&&m.append("Prefer",`count=${a}`),new Da({method:l,url:d,headers:m,schema:this.schema,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}insert(n,{count:e,defaultToNull:i=!0}={}){var a;const l="POST",{url:c,headers:u}=this.cloneRequestState();if(e&&u.append("Prefer",`count=${e}`),i||u.append("Prefer","missing=default"),Array.isArray(n)){const d=n.reduce((m,p)=>m.concat(Object.keys(p)),[]);if(d.length>0){const m=[...new Set(d)].map(p=>`"${p}"`);c.searchParams.set("columns",m.join(","))}}return new Da({method:l,url:c,headers:u,schema:this.schema,body:n,fetch:(a=this.fetch)!==null&&a!==void 0?a:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}upsert(n,{onConflict:e,ignoreDuplicates:i=!1,count:a,defaultToNull:l=!0}={}){var c;const u="POST",{url:d,headers:m}=this.cloneRequestState();if(m.append("Prefer",`resolution=${i?"ignore":"merge"}-duplicates`),e!==void 0&&d.searchParams.set("on_conflict",e),a&&m.append("Prefer",`count=${a}`),l||m.append("Prefer","missing=default"),Array.isArray(n)){const p=n.reduce((y,v)=>y.concat(Object.keys(v)),[]);if(p.length>0){const y=[...new Set(p)].map(v=>`"${v}"`);d.searchParams.set("columns",y.join(","))}}return new Da({method:u,url:d,headers:m,schema:this.schema,body:n,fetch:(c=this.fetch)!==null&&c!==void 0?c:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}update(n,{count:e}={}){var i;const a="PATCH",{url:l,headers:c}=this.cloneRequestState();return e&&c.append("Prefer",`count=${e}`),new Da({method:a,url:l,headers:c,schema:this.schema,body:n,fetch:(i=this.fetch)!==null&&i!==void 0?i:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}delete({count:n}={}){var e;const i="DELETE",{url:a,headers:l}=this.cloneRequestState();return n&&l.append("Prefer",`count=${n}`),new Da({method:i,url:a,headers:l,schema:this.schema,fetch:(e=this.fetch)!==null&&e!==void 0?e:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}};function po(n){"@babel/helpers - typeof";return po=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},po(n)}function bN(n,e){if(po(n)!="object"||!n)return n;var i=n[Symbol.toPrimitive];if(i!==void 0){var a=i.call(n,e);if(po(a)!="object")return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(n)}function vN(n){var e=bN(n,"string");return po(e)=="symbol"?e:e+""}function xN(n,e,i){return(e=vN(e))in n?Object.defineProperty(n,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):n[e]=i,n}function kb(n,e){var i=Object.keys(n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(n);e&&(a=a.filter(function(l){return Object.getOwnPropertyDescriptor(n,l).enumerable})),i.push.apply(i,a)}return i}function ec(n){for(var e=1;e0?this.fetch=(p,y)=>{const v=new AbortController,x=setTimeout(()=>v.abort(),c),_=y==null?void 0:y.signal;if(_){if(_.aborted)return clearTimeout(x),m(p,y);const S=()=>{clearTimeout(x),v.abort()};return _.addEventListener("abort",S,{once:!0}),m(p,ec(ec({},y),{},{signal:v.signal})).finally(()=>{clearTimeout(x),_.removeEventListener("abort",S)})}return m(p,ec(ec({},y),{},{signal:v.signal})).finally(()=>clearTimeout(x))}:this.fetch=m,this.retry=d}from(e){if(!e||typeof e!="string"||e.trim()==="")throw new Error("Invalid relation name: relation must be a non-empty string.");return new yN(new URL(`${this.url}/${e}`),{headers:new Headers(this.headers),schema:this.schemaName,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}schema(e){return new gw(this.url,{headers:this.headers,schema:e,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}rpc(e,i={},{head:a=!1,get:l=!1,count:c}={}){var u;let d;const m=new URL(`${this.url}/rpc/${e}`);let p;const y=_=>_!==null&&typeof _=="object"&&(!Array.isArray(_)||_.some(y)),v=a&&Object.values(i).some(y);v?(d="POST",p=i):a||l?(d=a?"HEAD":"GET",Object.entries(i).filter(([_,S])=>S!==void 0).map(([_,S])=>[_,Array.isArray(S)?`{${S.join(",")}}`:`${S}`]).forEach(([_,S])=>{m.searchParams.append(_,S)})):(d="POST",p=i);const x=new Headers(this.headers);return v?x.set("Prefer",c?`count=${c},return=minimal`:"return=minimal"):c&&x.set("Prefer",`count=${c}`),new Da({method:d,url:m,headers:x,schema:this.schemaName,body:p,fetch:(u=this.fetch)!==null&&u!==void 0?u:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}};class _N{constructor(){}static detectEnvironment(){var e;if(typeof WebSocket<"u")return{type:"native",wsConstructor:WebSocket};const i=globalThis;if(typeof globalThis<"u"&&typeof i.WebSocket<"u")return{type:"native",wsConstructor:i.WebSocket};const a=typeof global<"u"?global:void 0;if(a&&typeof a.WebSocket<"u")return{type:"native",wsConstructor:a.WebSocket};if(typeof globalThis<"u"&&typeof i.WebSocketPair<"u"&&typeof globalThis.WebSocket>"u")return{type:"cloudflare",error:"Cloudflare Workers detected. WebSocket clients are not supported in Cloudflare Workers.",workaround:"Use Cloudflare Workers WebSocket API for server-side WebSocket handling, or deploy to a different runtime."};if(typeof globalThis<"u"&&i.EdgeRuntime||typeof navigator<"u"&&(!((e=navigator.userAgent)===null||e===void 0)&&e.includes("Vercel-Edge")))return{type:"unsupported",error:"Edge runtime detected (Vercel Edge/Netlify Edge). WebSockets are not supported in edge functions.",workaround:"Use serverless functions or a different deployment target for WebSocket functionality."};const l=globalThis.process;if(l){const c=l.versions;if(c&&c.node)return{type:"unsupported",error:"Node.js detected but native WebSocket not found.",workaround:"Ensure you are running Node.js 22+ or provide a WebSocket implementation via the transport option."}}return{type:"unsupported",error:"Unknown JavaScript runtime without WebSocket support.",workaround:"Ensure you're running in a supported environment (browser, Node.js, Deno) or provide a custom WebSocket implementation."}}static getWebSocketConstructor(){const e=this.detectEnvironment();if(e.wsConstructor)return e.wsConstructor;let i=e.error||"WebSocket not supported in this environment.";throw e.workaround&&(i+=` - -Suggested solution: ${e.workaround}`),new Error(i)}static isWebSocketSupported(){try{return this.detectEnvironment().type==="native"}catch{return!1}}}const SN="2.110.2",TN=`realtime-js/${SN}`,EN="1.0.0",yw="2.0.0",AN=yw,jN=1e4,NN=100,ii={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},bw={close:"phx_close",error:"phx_error",join:"phx_join",leave:"phx_leave",access_token:"access_token"},uf={connecting:"connecting",closing:"closing",closed:"closed"};class kN{constructor(e){this.HEADER_LENGTH=1,this.USER_BROADCAST_PUSH_META_LENGTH=6,this.KINDS={userBroadcastPush:3,userBroadcast:4},this.BINARY_ENCODING=0,this.JSON_ENCODING=1,this.BROADCAST_EVENT="broadcast",this.allowedMetadataKeys=[],this.allowedMetadataKeys=e??[]}encode(e,i){if(e.event===this.BROADCAST_EVENT&&!(e.payload instanceof ArrayBuffer)&&typeof e.payload.event=="string")return i(this._binaryEncodeUserBroadcastPush(e));let a=[e.join_ref,e.ref,e.topic,e.event,e.payload];return i(JSON.stringify(a))}_binaryEncodeUserBroadcastPush(e){var i;return this._isArrayBuffer((i=e.payload)===null||i===void 0?void 0:i.payload)?this._encodeBinaryUserBroadcastPush(e):this._encodeJsonUserBroadcastPush(e)}_encodeBinaryUserBroadcastPush(e){var i,a;const l=(a=(i=e.payload)===null||i===void 0?void 0:i.payload)!==null&&a!==void 0?a:new ArrayBuffer(0);return this._encodeUserBroadcastPush(e,this.BINARY_ENCODING,l)}_encodeJsonUserBroadcastPush(e){var i,a;const l=(a=(i=e.payload)===null||i===void 0?void 0:i.payload)!==null&&a!==void 0?a:{},u=new TextEncoder().encode(JSON.stringify(l)).buffer;return this._encodeUserBroadcastPush(e,this.JSON_ENCODING,u)}_encodeUserBroadcastPush(e,i,a){var l,c;const u=e.topic,d=(l=e.ref)!==null&&l!==void 0?l:"",m=(c=e.join_ref)!==null&&c!==void 0?c:"",p=e.payload.event,y=this.allowedMetadataKeys?this._pick(e.payload,this.allowedMetadataKeys):{},v=Object.keys(y).length===0?"":JSON.stringify(y);if(m.length>255)throw new Error(`joinRef length ${m.length} exceeds maximum of 255`);if(d.length>255)throw new Error(`ref length ${d.length} exceeds maximum of 255`);if(u.length>255)throw new Error(`topic length ${u.length} exceeds maximum of 255`);if(p.length>255)throw new Error(`userEvent length ${p.length} exceeds maximum of 255`);if(v.length>255)throw new Error(`metadata length ${v.length} exceeds maximum of 255`);const x=this.USER_BROADCAST_PUSH_META_LENGTH+m.length+d.length+u.length+p.length+v.length,_=new ArrayBuffer(this.HEADER_LENGTH+x);let S=new DataView(_),T=0;S.setUint8(T++,this.KINDS.userBroadcastPush),S.setUint8(T++,m.length),S.setUint8(T++,d.length),S.setUint8(T++,u.length),S.setUint8(T++,p.length),S.setUint8(T++,v.length),S.setUint8(T++,i),Array.from(m,R=>S.setUint8(T++,R.charCodeAt(0))),Array.from(d,R=>S.setUint8(T++,R.charCodeAt(0))),Array.from(u,R=>S.setUint8(T++,R.charCodeAt(0))),Array.from(p,R=>S.setUint8(T++,R.charCodeAt(0))),Array.from(v,R=>S.setUint8(T++,R.charCodeAt(0)));var k=new Uint8Array(_.byteLength+a.byteLength);return k.set(new Uint8Array(_),0),k.set(new Uint8Array(a),_.byteLength),k.buffer}decode(e,i){if(this._isArrayBuffer(e)){let a=this._binaryDecode(e);return i(a)}if(typeof e=="string"){const a=JSON.parse(e),[l,c,u,d,m]=a;return i({join_ref:l,ref:c,topic:u,event:d,payload:m})}return i({})}_binaryDecode(e){const i=new DataView(e),a=i.getUint8(0),l=new TextDecoder;switch(a){case this.KINDS.userBroadcast:return this._decodeUserBroadcast(e,i,l)}}_decodeUserBroadcast(e,i,a){const l=i.getUint8(1),c=i.getUint8(2),u=i.getUint8(3),d=i.getUint8(4);let m=this.HEADER_LENGTH+4;const p=a.decode(e.slice(m,m+l));m=m+l;const y=a.decode(e.slice(m,m+c));m=m+c;const v=a.decode(e.slice(m,m+u));m=m+u;const x=e.slice(m,e.byteLength),_=d===this.JSON_ENCODING?JSON.parse(a.decode(x)):x,S={type:this.BROADCAST_EVENT,event:y,payload:_};return u>0&&(S.meta=JSON.parse(v)),{join_ref:null,ref:null,topic:p,event:this.BROADCAST_EVENT,payload:S}}_isArrayBuffer(e){var i;return e instanceof ArrayBuffer||((i=e==null?void 0:e.constructor)===null||i===void 0?void 0:i.name)==="ArrayBuffer"}_pick(e,i){return!e||typeof e!="object"?{}:Object.fromEntries(Object.entries(e).filter(([a])=>i.includes(a)))}}var Je;(function(n){n.abstime="abstime",n.bool="bool",n.date="date",n.daterange="daterange",n.float4="float4",n.float8="float8",n.int2="int2",n.int4="int4",n.int4range="int4range",n.int8="int8",n.int8range="int8range",n.json="json",n.jsonb="jsonb",n.money="money",n.numeric="numeric",n.oid="oid",n.reltime="reltime",n.text="text",n.time="time",n.timestamp="timestamp",n.timestamptz="timestamptz",n.timetz="timetz",n.tsrange="tsrange",n.tstzrange="tstzrange"})(Je||(Je={}));const Rb=(n,e,i={})=>{var a;const l=(a=i.skipTypes)!==null&&a!==void 0?a:[];return e?Object.keys(e).reduce((c,u)=>(c[u]=RN(u,n,e,l),c),{}):{}},RN=(n,e,i,a)=>{const l=e.find(d=>d.name===n),c=l==null?void 0:l.type,u=i[n];return c&&!a.includes(c)?vw(c,u):hf(u)},vw=(n,e)=>{if(n.charAt(0)==="_"){const i=n.slice(1,n.length);return MN(e,i)}switch(n){case Je.bool:return CN(e);case Je.float4:case Je.float8:case Je.int2:case Je.int4:case Je.int8:case Je.numeric:case Je.oid:return ON(e);case Je.json:case Je.jsonb:return DN(e);case Je.timestamp:return BN(e);case Je.abstime:case Je.date:case Je.daterange:case Je.int4range:case Je.int8range:case Je.money:case Je.reltime:case Je.text:case Je.time:case Je.timestamptz:case Je.timetz:case Je.tsrange:case Je.tstzrange:return hf(e);default:return hf(e)}},hf=n=>n,CN=n=>{switch(n){case"t":return!0;case"f":return!1;default:return n}},ON=n=>{if(typeof n=="string"){const e=parseFloat(n);if(!Number.isNaN(e))return e}return n},DN=n=>{if(typeof n=="string")try{return JSON.parse(n)}catch{return n}return n},MN=(n,e)=>{if(typeof n!="string")return n;const i=n.length-1,a=n[i];if(n[0]==="{"&&a==="}"){let c;const u=n.slice(1,i);try{c=JSON.parse("["+u+"]")}catch{c=u?u.split(","):[]}return c.map(d=>vw(e,d))}return n},BN=n=>typeof n=="string"?n.replace(" ","T"):n,xw=n=>{const e=new URL(n);return e.protocol=e.protocol.replace(/^ws/i,"http"),e.pathname=e.pathname.replace(/\/+$/,"").replace(/\/socket\/websocket$/i,"").replace(/\/socket$/i,"").replace(/\/websocket$/i,""),e.pathname===""||e.pathname==="/"?e.pathname="/api/broadcast":e.pathname=e.pathname+"/api/broadcast",e.href};var io=n=>typeof n=="function"?n:function(){return n},UN=typeof self<"u"?self:null,Ma=typeof window<"u"?window:null,Qn=UN||Ma||globalThis,LN="2.0.0",zN=1e4,PN=1e3,Wn={connecting:0,open:1,closing:2,closed:3},Wt={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},js={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},df={longpoll:"longpoll",websocket:"websocket"},VN={complete:4},ff="base64url.bearer.phx.",tc=class{constructor(n,e,i,a){this.channel=n,this.event=e,this.payload=i||function(){return{}},this.receivedResp=null,this.timeout=a,this.timeoutTimer=null,this.recHooks=[],this.sent=!1,this.ref=void 0}resend(n){this.timeout=n,this.reset(),this.send()}send(){this.hasReceived("timeout")||(this.startTimeout(),this.sent=!0,this.channel.socket.push({topic:this.channel.topic,event:this.event,payload:this.payload(),ref:this.ref,join_ref:this.channel.joinRef()}))}receive(n,e){return this.hasReceived(n)&&e(this.receivedResp.response),this.recHooks.push({status:n,callback:e}),this}reset(){this.cancelRefEvent(),this.ref=null,this.refEvent=null,this.receivedResp=null,this.sent=!1}destroy(){this.cancelRefEvent(),this.cancelTimeout()}matchReceive({status:n,response:e,_ref:i}){this.recHooks.filter(a=>a.status===n).forEach(a=>a.callback(e))}cancelRefEvent(){this.refEvent&&this.channel.off(this.refEvent)}cancelTimeout(){clearTimeout(this.timeoutTimer),this.timeoutTimer=null}startTimeout(){this.timeoutTimer&&this.cancelTimeout(),this.ref=this.channel.socket.makeRef(),this.refEvent=this.channel.replyEventName(this.ref),this.channel.on(this.refEvent,n=>{this.cancelRefEvent(),this.cancelTimeout(),this.receivedResp=n,this.matchReceive(n)}),this.timeoutTimer=setTimeout(()=>{this.trigger("timeout",{})},this.timeout)}hasReceived(n){return this.receivedResp&&this.receivedResp.status===n}trigger(n,e){this.channel.trigger(this.refEvent,{status:n,response:e})}},ww=class{constructor(n,e){this.callback=n,this.timerCalc=e,this.timer=void 0,this.tries=0}reset(){this.tries=0,clearTimeout(this.timer)}scheduleTimeout(){clearTimeout(this.timer),this.timer=setTimeout(()=>{this.tries=this.tries+1,this.callback()},this.timerCalc(this.tries+1))}},HN=class{constructor(n,e,i){this.state=Wt.closed,this.topic=n,this.params=io(e||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new tc(this,js.join,this.params,this.timeout),this.pushBuffer=[],this.stateChangeRefs=[],this.rejoinTimer=new ww(()=>{this.socket.isConnected()&&this.rejoin()},this.socket.rejoinAfterMs),this.stateChangeRefs.push(this.socket.onError(()=>this.rejoinTimer.reset())),this.stateChangeRefs.push(this.socket.onOpen(()=>{this.rejoinTimer.reset(),this.isErrored()&&this.rejoin()})),this.joinPush.receive("ok",()=>{this.state=Wt.joined,this.rejoinTimer.reset(),this.pushBuffer.forEach(a=>a.send()),this.pushBuffer=[]}),this.joinPush.receive("error",a=>{this.state=Wt.errored,this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,a),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.onClose(()=>{this.rejoinTimer.reset(),this.socket.hasLogger()&&this.socket.log("channel",`close ${this.topic}`),this.state=Wt.closed,this.socket.remove(this)}),this.onError(a=>{this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,a),this.isJoining()&&this.joinPush.reset(),this.state=Wt.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.joinPush.receive("timeout",()=>{this.socket.hasLogger()&&this.socket.log("channel",`timeout ${this.topic}`,this.joinPush.timeout),new tc(this,js.leave,io({}),this.timeout).send(),this.state=Wt.errored,this.joinPush.reset(),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.on(js.reply,(a,l)=>{this.trigger(this.replyEventName(l),a)})}join(n=this.timeout){if(this.joinedOnce)throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");return this.timeout=n,this.joinedOnce=!0,this.rejoin(),this.joinPush}teardown(){this.pushBuffer.forEach(n=>n.destroy()),this.pushBuffer=[],this.rejoinTimer.reset(),this.joinPush.destroy(),this.state=Wt.closed,this.bindings=[]}onClose(n){this.on(js.close,n)}onError(n){return this.on(js.error,e=>n(e))}on(n,e){let i=this.bindingRef++;return this.bindings.push({event:n,ref:i,callback:e}),i}off(n,e){this.bindings=this.bindings.filter(i=>!(i.event===n&&(typeof e>"u"||e===i.ref)))}canPush(){return this.socket.isConnected()&&this.isJoined()}push(n,e,i=this.timeout){if(e=e||{},!this.joinedOnce)throw new Error(`tried to push '${n}' to '${this.topic}' before joining. Use channel.join() before pushing events`);let a=new tc(this,n,function(){return e},i);return this.canPush()?a.send():(a.startTimeout(),this.pushBuffer.push(a)),a}leave(n=this.timeout){this.rejoinTimer.reset(),this.joinPush.cancelTimeout(),this.state=Wt.leaving;let e=()=>{this.socket.hasLogger()&&this.socket.log("channel",`leave ${this.topic}`),this.trigger(js.close,"leave")},i=new tc(this,js.leave,io({}),n);return i.receive("ok",()=>e()).receive("timeout",()=>e()),i.send(),this.canPush()||i.trigger("ok",{}),i}onMessage(n,e,i){return e}filterBindings(n,e,i){return!0}isMember(n,e,i,a){return this.topic!==n?!1:a&&a!==this.joinRef()?(this.socket.hasLogger()&&this.socket.log("channel","dropping outdated message",{topic:n,event:e,payload:i,joinRef:a}),!1):!0}joinRef(){return this.joinPush.ref}rejoin(n=this.timeout){this.isLeaving()||(this.socket.leaveOpenTopic(this.topic),this.state=Wt.joining,this.joinPush.resend(n))}trigger(n,e,i,a){let l=this.onMessage(n,e,i,a);if(e&&!l)throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");let c=this.bindings.filter(u=>u.event===n&&this.filterBindings(u,e,i));for(let u=0;um.abort(),l),d.signal=m.signal),Qn.fetch(e,d).then(p=>p.text()).then(p=>this.parseJSON(p)).then(p=>u&&u(p)).catch(p=>{p.name==="AbortError"&&c?c():u&&u(null)}),m}static xdomainRequest(n,e,i,a,l,c,u){return n.timeout=l,n.open(e,i),n.onload=()=>{let d=this.parseJSON(n.responseText);u&&u(d)},c&&(n.ontimeout=c),n.onprogress=()=>{},n.send(a),n}static xhrRequest(n,e,i,a,l,c,u,d){n.open(e,i,!0),n.timeout=c;for(let[m,p]of Object.entries(a))n.setRequestHeader(m,p);return n.onerror=()=>d&&d(null),n.onreadystatechange=()=>{if(n.readyState===VN.complete&&d){let m=this.parseJSON(n.responseText);d(m)}},u&&(n.ontimeout=u),n.send(l),n}static parseJSON(n){if(!n||n==="")return null;try{return JSON.parse(n)}catch{return console&&console.log("failed to parse JSON response",n),null}}static serialize(n,e){let i=[];for(var a in n){if(!Object.prototype.hasOwnProperty.call(n,a))continue;let l=e?`${e}[${a}]`:a,c=n[a];typeof c=="object"?i.push(this.serialize(c,l)):i.push(encodeURIComponent(l)+"="+encodeURIComponent(c))}return i.join("&")}static appendParams(n,e){if(Object.keys(e).length===0)return n;let i=n.match(/\?/)?"&":"?";return`${n}${i}${this.serialize(e)}`}},$N=n=>{let e="",i=new Uint8Array(n),a=i.byteLength;for(let l=0;lthis.poll(),0)}normalizeEndpoint(n){return n.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+df.websocket),"$1/"+df.longpoll)}endpointURL(){return Rc.appendParams(this.pollEndpoint,{token:this.token})}closeAndRetry(n,e,i){this.close(n,e,i),this.readyState=Wn.connecting}ontimeout(){this.onerror("timeout"),this.closeAndRetry(1005,"timeout",!1)}isActive(){return this.readyState===Wn.open||this.readyState===Wn.connecting}poll(){const n={Accept:"application/json"};this.authToken&&(n["X-Phoenix-AuthToken"]=this.authToken),this.ajax("GET",n,null,()=>this.ontimeout(),e=>{if(e){var{status:i,token:a,messages:l}=e;if(i===410&&this.token!==null){this.onerror(410),this.closeAndRetry(3410,"session_gone",!1);return}this.token=a}else i=0;switch(i){case 200:l.forEach(c=>{setTimeout(()=>this.onmessage({data:c}),0)}),this.poll();break;case 204:this.poll();break;case 410:this.readyState=Wn.open,this.onopen({}),this.poll();break;case 403:this.onerror(403),this.close(1008,"forbidden",!1);break;case 0:case 500:this.onerror(500),this.closeAndRetry(1011,"internal server error",500);break;default:throw new Error(`unhandled poll status ${i}`)}})}send(n){typeof n!="string"&&(n=$N(n)),this.currentBatch?this.currentBatch.push(n):this.awaitingBatchAck?this.batchBuffer.push(n):(this.currentBatch=[n],this.currentBatchTimer=setTimeout(()=>{this.batchSend(this.currentBatch),this.currentBatch=null},0))}batchSend(n){this.awaitingBatchAck=!0,this.ajax("POST",{"Content-Type":"application/x-ndjson"},n.join(` -`),()=>this.onerror("timeout"),e=>{this.awaitingBatchAck=!1,!e||e.status!==200?(this.onerror(e&&e.status),this.closeAndRetry(1011,"internal server error",!1)):this.batchBuffer.length>0&&(this.batchSend(this.batchBuffer),this.batchBuffer=[])})}close(n,e,i){for(let l of this.reqs)l.abort();this.readyState=Wn.closed;let a=Object.assign({code:1e3,reason:void 0,wasClean:!0},{code:n,reason:e,wasClean:i});this.batchBuffer=[],clearTimeout(this.currentBatchTimer),this.currentBatchTimer=null,typeof CloseEvent<"u"?this.onclose(new CloseEvent("close",a)):this.onclose(a)}ajax(n,e,i,a,l){let c,u=()=>{this.reqs.delete(c),a()};c=Rc.request(n,this.endpointURL(),e,i,this.timeout,u,d=>{this.reqs.delete(c),this.isActive()&&l(d)}),this.reqs.add(c)}},qN=class Qr{constructor(e,i={}){let a=i.events||{state:"presence_state",diff:"presence_diff"};this.state={},this.pendingDiffs=[],this.channel=e,this.joinRef=null,this.caller={onJoin:function(){},onLeave:function(){},onSync:function(){}},this.channel.on(a.state,l=>{let{onJoin:c,onLeave:u,onSync:d}=this.caller;this.joinRef=this.channel.joinRef(),this.state=Qr.syncState(this.state,l,c,u),this.pendingDiffs.forEach(m=>{this.state=Qr.syncDiff(this.state,m,c,u)}),this.pendingDiffs=[],d()}),this.channel.on(a.diff,l=>{let{onJoin:c,onLeave:u,onSync:d}=this.caller;this.inPendingSyncState()?this.pendingDiffs.push(l):(this.state=Qr.syncDiff(this.state,l,c,u),d())})}onJoin(e){this.caller.onJoin=e}onLeave(e){this.caller.onLeave=e}onSync(e){this.caller.onSync=e}list(e){return Qr.list(this.state,e)}inPendingSyncState(){return!this.joinRef||this.joinRef!==this.channel.joinRef()}static syncState(e,i,a,l){let c=this.clone(e),u={},d={};return this.map(c,(m,p)=>{i[m]||(d[m]=p)}),this.map(i,(m,p)=>{let y=c[m];if(y){let v=p.metas.map(T=>T.phx_ref),x=y.metas.map(T=>T.phx_ref),_=p.metas.filter(T=>x.indexOf(T.phx_ref)<0),S=y.metas.filter(T=>v.indexOf(T.phx_ref)<0);_.length>0&&(u[m]=p,u[m].metas=_),S.length>0&&(d[m]=this.clone(y),d[m].metas=S)}else u[m]=p}),this.syncDiff(c,{joins:u,leaves:d},a,l)}static syncDiff(e,i,a,l){let{joins:c,leaves:u}=this.clone(i);return a||(a=function(){}),l||(l=function(){}),this.map(c,(d,m)=>{let p=e[d];if(e[d]=this.clone(m),p){let y=e[d].metas.map(x=>x.phx_ref),v=p.metas.filter(x=>y.indexOf(x.phx_ref)<0);e[d].metas.unshift(...v)}a(d,p,m)}),this.map(u,(d,m)=>{let p=e[d];if(!p)return;let y=m.metas.map(v=>v.phx_ref);p.metas=p.metas.filter(v=>y.indexOf(v.phx_ref)<0),l(d,p,m),p.metas.length===0&&delete e[d]}),e}static list(e,i){return i||(i=function(a,l){return l}),this.map(e,(a,l)=>i(a,l))}static map(e,i){return Object.getOwnPropertyNames(e).map(a=>i(a,e[a]))}static clone(e){return JSON.parse(JSON.stringify(e))}},nc={HEADER_LENGTH:1,META_LENGTH:4,KINDS:{push:0,reply:1,broadcast:2},encode(n,e){if(n.payload.constructor===ArrayBuffer)return e(this.binaryEncode(n));{let i=[n.join_ref,n.ref,n.topic,n.event,n.payload];return e(JSON.stringify(i))}},decode(n,e){if(n.constructor===ArrayBuffer)return e(this.binaryDecode(n));{let[i,a,l,c,u]=JSON.parse(n);return e({join_ref:i,ref:a,topic:l,event:c,payload:u})}},binaryEncode(n){let{join_ref:e,ref:i,event:a,topic:l,payload:c}=n,u=this.META_LENGTH+e.length+i.length+l.length+a.length,d=new ArrayBuffer(this.HEADER_LENGTH+u),m=new DataView(d),p=0;m.setUint8(p++,this.KINDS.push),m.setUint8(p++,e.length),m.setUint8(p++,i.length),m.setUint8(p++,l.length),m.setUint8(p++,a.length),Array.from(e,v=>m.setUint8(p++,v.charCodeAt(0))),Array.from(i,v=>m.setUint8(p++,v.charCodeAt(0))),Array.from(l,v=>m.setUint8(p++,v.charCodeAt(0))),Array.from(a,v=>m.setUint8(p++,v.charCodeAt(0)));var y=new Uint8Array(d.byteLength+c.byteLength);return y.set(new Uint8Array(d),0),y.set(new Uint8Array(c),d.byteLength),y.buffer},binaryDecode(n){let e=new DataView(n),i=e.getUint8(0),a=new TextDecoder;switch(i){case this.KINDS.push:return this.decodePush(n,e,a);case this.KINDS.reply:return this.decodeReply(n,e,a);case this.KINDS.broadcast:return this.decodeBroadcast(n,e,a)}},decodePush(n,e,i){let a=e.getUint8(1),l=e.getUint8(2),c=e.getUint8(3),u=this.HEADER_LENGTH+this.META_LENGTH-1,d=i.decode(n.slice(u,u+a));u=u+a;let m=i.decode(n.slice(u,u+l));u=u+l;let p=i.decode(n.slice(u,u+c));u=u+c;let y=n.slice(u,n.byteLength);return{join_ref:d,ref:null,topic:m,event:p,payload:y}},decodeReply(n,e,i){let a=e.getUint8(1),l=e.getUint8(2),c=e.getUint8(3),u=e.getUint8(4),d=this.HEADER_LENGTH+this.META_LENGTH,m=i.decode(n.slice(d,d+a));d=d+a;let p=i.decode(n.slice(d,d+l));d=d+l;let y=i.decode(n.slice(d,d+c));d=d+c;let v=i.decode(n.slice(d,d+u));d=d+u;let x=n.slice(d,n.byteLength),_={status:v,response:x};return{join_ref:m,ref:p,topic:y,event:js.reply,payload:_}},decodeBroadcast(n,e,i){let a=e.getUint8(1),l=e.getUint8(2),c=this.HEADER_LENGTH+2,u=i.decode(n.slice(c,c+a));c=c+a;let d=i.decode(n.slice(c,c+l));c=c+l;let m=n.slice(c,n.byteLength);return{join_ref:null,ref:null,topic:u,event:d,payload:m}}},FN=class{constructor(n,e={}){this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.fallbackRef=null,this.timeout=e.timeout||zN,this.transport=e.transport||Qn.WebSocket||Aa,this.conn=void 0,this.primaryPassedHealthCheck=!1,this.longPollFallbackMs=e.longPollFallbackMs,this.fallbackTimer=null;let i=null;try{i=Qn&&Qn.sessionStorage}catch{}this.sessionStore=e.sessionStorage||i,this.establishedConnections=0,this.defaultEncoder=nc.encode.bind(nc),this.defaultDecoder=nc.decode.bind(nc),this.closeWasClean=!0,this.disconnecting=!1,this.binaryType=e.binaryType||"arraybuffer",this.connectClock=1,this.pageHidden=!1,this.encode=void 0,this.decode=void 0,this.transport!==Aa?(this.encode=e.encode||this.defaultEncoder,this.decode=e.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder);let a=null;Ma&&Ma.addEventListener&&(Ma.addEventListener("pagehide",l=>{this.conn&&(this.disconnect(),a=this.connectClock)}),Ma.addEventListener("pageshow",l=>{a===this.connectClock&&(a=null,this.connect())}),Ma.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?this.pageHidden=!0:(this.pageHidden=!1,!this.isConnected()&&!this.closeWasClean&&this.teardown(()=>this.connect()))})),this.heartbeatIntervalMs=e.heartbeatIntervalMs||3e4,this.autoSendHeartbeat=e.autoSendHeartbeat??!0,this.heartbeatCallback=e.heartbeatCallback??(()=>{}),this.rejoinAfterMs=l=>e.rejoinAfterMs?e.rejoinAfterMs(l):[1e3,2e3,5e3][l-1]||1e4,this.reconnectAfterMs=l=>e.reconnectAfterMs?e.reconnectAfterMs(l):[10,50,100,150,200,250,500,1e3,2e3][l-1]||5e3,this.logger=e.logger||null,!this.logger&&e.debug&&(this.logger=(l,c,u)=>{console.log(`${l}: ${c}`,u)}),this.longpollerTimeout=e.longpollerTimeout||2e4,this.params=io(e.params||{}),this.endPoint=`${n}/${df.websocket}`,this.vsn=e.vsn||LN,this.heartbeatTimeoutTimer=null,this.heartbeatTimer=null,this.heartbeatSentAt=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new ww(()=>{if(this.pageHidden){this.log("Not reconnecting as page is hidden!"),this.teardown();return}this.teardown(async()=>{e.beforeReconnect&&await e.beforeReconnect(),this.connect()})},this.reconnectAfterMs),this.authToken=e.authToken}getLongPollTransport(){return Aa}replaceTransport(n){this.connectClock++,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.conn&&(this.conn.close(),this.conn=null),this.transport=n}protocol(){return location.protocol.match(/^https/)?"wss":"ws"}endPointURL(){let n=Rc.appendParams(Rc.appendParams(this.endPoint,this.params()),{vsn:this.vsn});return n.charAt(0)!=="/"?n:n.charAt(1)==="/"?`${this.protocol()}:${n}`:`${this.protocol()}://${location.host}${n}`}disconnect(n,e,i){this.connectClock++,this.disconnecting=!0,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.teardown(()=>{this.disconnecting=!1,n&&n()},e,i)}connect(n){n&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=io(n)),!(this.conn&&!this.disconnecting)&&(this.longPollFallbackMs&&this.transport!==Aa?this.connectWithFallback(Aa,this.longPollFallbackMs):this.transportConnect())}log(n,e,i){this.logger&&this.logger(n,e,i)}hasLogger(){return this.logger!==null}onOpen(n){let e=this.makeRef();return this.stateChangeCallbacks.open.push([e,n]),e}onClose(n){let e=this.makeRef();return this.stateChangeCallbacks.close.push([e,n]),e}onError(n){let e=this.makeRef();return this.stateChangeCallbacks.error.push([e,n]),e}onMessage(n){let e=this.makeRef();return this.stateChangeCallbacks.message.push([e,n]),e}onHeartbeat(n){this.heartbeatCallback=n}ping(n){if(!this.isConnected())return!1;let e=this.makeRef(),i=Date.now();this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:e});let a=this.onMessage(l=>{l.ref===e&&(this.off([a]),n(Date.now()-i))});return!0}transportName(n){switch(n){case Aa:return"LongPoll";default:return n.name}}transportConnect(){this.connectClock++,this.closeWasClean=!1;let n;this.authToken&&(n=["phoenix",`${ff}${btoa(this.authToken).replace(/=/g,"")}`]),this.conn=new this.transport(this.endPointURL(),n),this.conn.binaryType=this.binaryType,this.conn.timeout=this.longpollerTimeout,this.conn.onopen=()=>this.onConnOpen(),this.conn.onerror=e=>this.onConnError(e),this.conn.onmessage=e=>this.onConnMessage(e),this.conn.onclose=e=>this.onConnClose(e)}getSession(n){return this.sessionStore&&this.sessionStore.getItem(n)}storeSession(n,e){this.sessionStore&&this.sessionStore.setItem(n,e)}connectWithFallback(n,e=2500){clearTimeout(this.fallbackTimer);let i=!1,a=!0,l,c,u=this.transportName(n),d=m=>{this.log("transport",`falling back to ${u}...`,m),this.off([l,c]),a=!1,this.replaceTransport(n),this.transportConnect()};if(this.getSession(`phx:fallback:${u}`))return d("memorized");this.fallbackTimer=setTimeout(d,e),c=this.onError(m=>{this.log("transport","error",m),a&&!i&&(clearTimeout(this.fallbackTimer),d(m))}),this.fallbackRef&&this.off([this.fallbackRef]),this.fallbackRef=this.onOpen(()=>{if(i=!0,!a){let m=this.transportName(n);return this.primaryPassedHealthCheck||this.storeSession(`phx:fallback:${m}`,"true"),this.log("transport",`established ${m} fallback`)}clearTimeout(this.fallbackTimer),this.fallbackTimer=setTimeout(d,e),this.ping(m=>{this.log("transport","connected to primary after",m),this.primaryPassedHealthCheck=!0,clearTimeout(this.fallbackTimer)})}),this.transportConnect()}clearHeartbeats(){clearTimeout(this.heartbeatTimer),clearTimeout(this.heartbeatTimeoutTimer)}onConnOpen(){this.hasLogger()&&this.log("transport",`connected to ${this.endPointURL()}`),this.closeWasClean=!1,this.disconnecting=!1,this.establishedConnections++,this.flushSendBuffer(),this.reconnectTimer.reset(),this.autoSendHeartbeat&&this.resetHeartbeat(),this.triggerStateCallbacks("open")}heartbeatTimeout(){if(this.pendingHeartbeatRef){this.pendingHeartbeatRef=null,this.heartbeatSentAt=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection");try{this.heartbeatCallback("timeout")}catch(n){this.log("error","error in heartbeat callback",n)}this.triggerChanError(new Error("heartbeat timeout")),this.closeWasClean=!1,this.teardown(()=>this.reconnectTimer.scheduleTimeout(),PN,"heartbeat timeout")}}resetHeartbeat(){this.conn&&this.conn.skipHeartbeat||(this.pendingHeartbeatRef=null,this.clearHeartbeats(),this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}teardown(n,e,i){if(!this.conn)return n&&n();const a=this.conn;this.waitForBufferDone(a,()=>{e?a.close(e,i||""):a.close(),this.waitForSocketClosed(a,()=>{this.conn===a&&(this.conn.onopen=function(){},this.conn.onerror=function(){},this.conn.onmessage=function(){},this.conn.onclose=function(){},this.conn=null),n&&n()})})}waitForBufferDone(n,e,i=1){if(i===5||!n.bufferedAmount){e();return}setTimeout(()=>{this.waitForBufferDone(n,e,i+1)},150*i)}waitForSocketClosed(n,e,i=1){if(i===5||n.readyState===Wn.closed){e();return}setTimeout(()=>{this.waitForSocketClosed(n,e,i+1)},150*i)}onConnClose(n){this.conn&&(this.conn.onclose=()=>{}),this.hasLogger()&&this.log("transport","close",n),this.triggerChanError(n),this.clearHeartbeats(),this.closeWasClean||this.reconnectTimer.scheduleTimeout(),this.triggerStateCallbacks("close",n)}onConnError(n){this.hasLogger()&&this.log("transport","error",n);let e=this.transport,i=this.establishedConnections;this.triggerStateCallbacks("error",n,e,i),(e===this.transport||i>0)&&this.triggerChanError(n)}triggerChanError(n){this.channels.forEach(e=>{e.isErrored()||e.isLeaving()||e.isClosed()||e.trigger(js.error,n)})}connectionState(){switch(this.conn&&this.conn.readyState){case Wn.connecting:return"connecting";case Wn.open:return"open";case Wn.closing:return"closing";default:return"closed"}}isConnected(){return this.connectionState()==="open"}remove(n){this.off(n.stateChangeRefs),this.channels=this.channels.filter(e=>e!==n)}off(n){for(let e in this.stateChangeCallbacks)this.stateChangeCallbacks[e]=this.stateChangeCallbacks[e].filter(([i])=>n.indexOf(i)===-1)}channel(n,e={}){let i=new HN(n,e,this);return this.channels.push(i),i}push(n){if(this.hasLogger()){let{topic:e,event:i,payload:a,ref:l,join_ref:c}=n;this.log("push",`${e} ${i} (${c}, ${l})`,a)}this.isConnected()?this.encode(n,e=>this.conn.send(e)):this.sendBuffer.push(()=>this.encode(n,e=>this.conn.send(e)))}makeRef(){let n=this.ref+1;return n===this.ref?this.ref=0:this.ref=n,this.ref.toString()}sendHeartbeat(){if(!this.isConnected()){try{this.heartbeatCallback("disconnected")}catch(n){this.log("error","error in heartbeat callback",n)}return}if(this.pendingHeartbeatRef){this.heartbeatTimeout();return}this.pendingHeartbeatRef=this.makeRef(),this.heartbeatSentAt=Date.now(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef});try{this.heartbeatCallback("sent")}catch(n){this.log("error","error in heartbeat callback",n)}this.heartbeatTimeoutTimer=setTimeout(()=>this.heartbeatTimeout(),this.heartbeatIntervalMs)}flushSendBuffer(){this.isConnected()&&this.sendBuffer.length>0&&(this.sendBuffer.forEach(n=>n()),this.sendBuffer=[])}onConnMessage(n){this.decode(n.data,e=>{let{topic:i,event:a,payload:l,ref:c,join_ref:u}=e;if(c&&c===this.pendingHeartbeatRef){const d=this.heartbeatSentAt?Date.now()-this.heartbeatSentAt:void 0;this.clearHeartbeats();try{this.heartbeatCallback(l.status==="ok"?"ok":"error",d)}catch(m){this.log("error","error in heartbeat callback",m)}this.pendingHeartbeatRef=null,this.heartbeatSentAt=null,this.autoSendHeartbeat&&(this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}this.hasLogger()&&this.log("receive",`${l.status||""} ${i} ${a} ${c&&"("+c+")"||""}`.trim(),l);for(let d=0;d{try{a(...e)}catch(l){this.log("error",`error in ${n} callback`,l)}})}catch(i){this.log("error",`error triggering ${n} callbacks`,i)}}leaveOpenTopic(n){let e=this.channels.find(i=>i.topic===n&&(i.isJoined()||i.isJoining()));e&&(this.hasLogger()&&this.log("transport",`leaving duplicate topic "${n}"`),e.leave())}};class ao{constructor(e,i){const a=GN(i);this.presence=new qN(e.getChannel(),a),this.presence.onJoin((l,c,u)=>{const d=ao.onJoinPayload(l,c,u);e.getChannel().trigger("presence",d)}),this.presence.onLeave((l,c,u)=>{const d=ao.onLeavePayload(l,c,u);e.getChannel().trigger("presence",d)}),this.presence.onSync(()=>{e.getChannel().trigger("presence",{event:"sync"})})}get state(){return ao.transformState(this.presence.state)}static transformState(e){return e=IN(e),Object.getOwnPropertyNames(e).reduce((i,a)=>{const l=e[a];return i[a]=bc(l),i},{})}static onJoinPayload(e,i,a){const l=Cb(i),c=bc(a);return{event:"join",key:e,currentPresences:l,newPresences:c}}static onLeavePayload(e,i,a){const l=Cb(i),c=bc(a);return{event:"leave",key:e,currentPresences:l,leftPresences:c}}}function bc(n){return n.metas.map(e=>(e.presence_ref=e.phx_ref,delete e.phx_ref,delete e.phx_ref_prev,e))}function IN(n){return JSON.parse(JSON.stringify(n))}function GN(n){return(n==null?void 0:n.events)&&{events:n.events}}function Cb(n){return n!=null&&n.metas?bc(n):[]}var Ob;(function(n){n.SYNC="sync",n.JOIN="join",n.LEAVE="leave"})(Ob||(Ob={}));class KN{get state(){return this.presenceAdapter.state}constructor(e,i){this.channel=e,this.presenceAdapter=new ao(this.channel.channelAdapter,i)}}function YN(n){if(n instanceof Error)return n;if(typeof n=="string")return new Error(n);if(n&&typeof n=="object"){const e=n;if(typeof e.code=="number"){const i=typeof e.reason=="string"&&e.reason?` (${e.reason})`:"";return new Error(`socket closed: ${e.code}${i}`,{cause:n})}return new Error("channel error: transport failure",{cause:n})}return new Error("channel error: connection lost")}class XN{constructor(e,i,a){const l=JN(a);this.channel=e.getSocket().channel(i,l),this.socket=e}get state(){return this.channel.state}set state(e){this.channel.state=e}get joinedOnce(){return this.channel.joinedOnce}get joinPush(){return this.channel.joinPush}get rejoinTimer(){return this.channel.rejoinTimer}on(e,i){return this.channel.on(e,i)}off(e,i){this.channel.off(e,i)}subscribe(e){return this.channel.join(e)}unsubscribe(e){return this.channel.leave(e)}teardown(){this.channel.teardown()}onClose(e){this.channel.onClose(e)}onError(e){return this.channel.onError(e)}push(e,i,a){let l;try{l=this.channel.push(e,i,a)}catch{throw new Error(`tried to push '${e}' to '${this.channel.topic}' before joining. Use channel.subscribe() before pushing events`)}if(this.channel.pushBuffer.length>NN){const c=this.channel.pushBuffer.shift();c.cancelTimeout(),this.socket.log("channel",`discarded push due to buffer overflow: ${c.event}`,c.payload())}return l}updateJoinPayload(e){const i=this.channel.joinPush.payload();this.channel.joinPush.payload=()=>Object.assign(Object.assign({},i),e)}canPush(){return this.socket.isConnected()&&this.state===ii.joined}isJoined(){return this.state===ii.joined}isJoining(){return this.state===ii.joining}isClosed(){return this.state===ii.closed}isLeaving(){return this.state===ii.leaving}updateFilterBindings(e){this.channel.filterBindings=e}updatePayloadTransform(e){this.channel.onMessage=e}getChannel(){return this.channel}}function JN(n){return{config:Object.assign({broadcast:{ack:!1,self:!1},presence:{key:"",enabled:!1},private:!1},n.config)}}const QN=/[,()"\\]/,ZN=n=>QN.test(n)||n!==n.trim(),WN=n=>`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`,Db=n=>{const e=n===null?"null":String(n);return ZN(e)?WN(e):e},ek=n=>n===null?"null":String(n),tk=(n,e)=>{if(n==="in"){const i=Array.isArray(e)?e:[e];if(i.length===0)throw new Error("Realtime `in` filter requires at least one value.");return`in.(${Array.from(new Set(i)).map(l=>Db(l)).join(",")})`}return n==="is"?`is.${ek(e)}`:`${n}.${Db(e)}`};class nk{constructor(){this.filters=[]}add(e,i,a,l=!1){const c=l?"not.":"";return this.filters.push(`${e}=${c}${tk(i,a)}`),this}eq(e,i){return this.add(e,"eq",i)}neq(e,i){return this.add(e,"neq",i)}gt(e,i){return this.add(e,"gt",i)}gte(e,i){return this.add(e,"gte",i)}lt(e,i){return this.add(e,"lt",i)}lte(e,i){return this.add(e,"lte",i)}in(e,i){return this.add(e,"in",i)}like(e,i){return this.add(e,"like",i)}ilike(e,i){return this.add(e,"ilike",i)}match(e,i){return this.add(e,"match",i)}imatch(e,i){return this.add(e,"imatch",i)}is(e,i){return this.add(e,"is",i)}isDistinct(e,i){return this.add(e,"isdistinct",i)}not(e,i,a){return this.add(e,i,a,!0)}build(){return this.filters.join(",")}toString(){return this.build()}}var Mb;(function(n){n.ALL="*",n.INSERT="INSERT",n.UPDATE="UPDATE",n.DELETE="DELETE"})(Mb||(Mb={}));var Va;(function(n){n.BROADCAST="broadcast",n.PRESENCE="presence",n.POSTGRES_CHANGES="postgres_changes",n.SYSTEM="system"})(Va||(Va={}));var Ns;(function(n){n.SUBSCRIBED="SUBSCRIBED",n.TIMED_OUT="TIMED_OUT",n.CLOSED="CLOSED",n.CHANNEL_ERROR="CHANNEL_ERROR"})(Ns||(Ns={}));class ro{get state(){return this.channelAdapter.state}set state(e){this.channelAdapter.state=e}get joinedOnce(){return this.channelAdapter.joinedOnce}get timeout(){return this.socket.timeout}get joinPush(){return this.channelAdapter.joinPush}get rejoinTimer(){return this.channelAdapter.rejoinTimer}constructor(e,i={config:{}},a){var l,c;if(this.topic=e,this.params=i,this.socket=a,this.bindings={},this.subTopic=e.replace(/^realtime:/i,""),this.params.config=Object.assign({broadcast:{ack:!1,self:!1},presence:{key:"",enabled:!1},private:!1},i.config),this.channelAdapter=new XN(this.socket.socketAdapter,e,this.params),this.presence=new KN(this),this._onClose(()=>{this.socket._remove(this)}),this._updateFilterTransform(),this.broadcastEndpointURL=xw(this.socket.socketAdapter.endPointURL()),this.private=this.params.config.private||!1,!this.private&&(!((c=(l=this.params.config)===null||l===void 0?void 0:l.broadcast)===null||c===void 0)&&c.replay))throw new Error(`tried to use replay on public channel '${this.topic}'. It must be a private channel.`)}subscribe(e,i=this.timeout){var a,l,c;if(this.socket.isConnected()||this.socket.connect(),this.channelAdapter.isClosed()){const{config:{broadcast:u,presence:d,private:m}}=this.params,p=(l=(a=this.bindings.postgres_changes)===null||a===void 0?void 0:a.map(_=>_.filter))!==null&&l!==void 0?l:[],y=!!this.bindings[Va.PRESENCE]&&this.bindings[Va.PRESENCE].length>0||((c=this.params.config.presence)===null||c===void 0?void 0:c.enabled)===!0,v={},x={broadcast:u,presence:Object.assign(Object.assign({},d),{enabled:y}),postgres_changes:p,private:m};this.socket.accessTokenValue&&(v.access_token=this.socket.accessTokenValue),this._onError(_=>{e==null||e(Ns.CHANNEL_ERROR,YN(_))}),this._onClose(()=>e==null?void 0:e(Ns.CLOSED)),this.updateJoinPayload(Object.assign({config:x},v)),this._updateFilterMessage(),this.channelAdapter.subscribe(i).receive("ok",async({postgres_changes:_})=>{if(this.socket._isManualToken()||this.socket.setAuth(),_===void 0){e==null||e(Ns.SUBSCRIBED);return}this._updatePostgresBindings(_,e)}).receive("error",_=>{this.state=ii.errored;const S=Object.values(_).join(", ")||"error";e==null||e(Ns.CHANNEL_ERROR,new Error(S,{cause:_}))}).receive("timeout",()=>{e==null||e(Ns.TIMED_OUT)})}return this}_updatePostgresBindings(e,i){var a;const l=this.bindings.postgres_changes,c=(a=l==null?void 0:l.length)!==null&&a!==void 0?a:0,u=[];for(let d=0;d{var u,d,m;const p=this.channelAdapter.push(e.type,e,i.timeout||this.timeout);e.type==="broadcast"&&!(!((m=(d=(u=this.params)===null||u===void 0?void 0:u.config)===null||d===void 0?void 0:d.broadcast)===null||m===void 0)&&m.ack)&&c("ok"),p.receive("ok",()=>c("ok")),p.receive("error",()=>c("error")),p.receive("timeout",()=>c("timed out"))})}updateJoinPayload(e){this.channelAdapter.updateJoinPayload(e)}async unsubscribe(e=this.timeout){return new Promise(i=>{this.channelAdapter.unsubscribe(e).receive("ok",()=>i("ok")).receive("timeout",()=>i("timed out")).receive("error",()=>i("error"))})}teardown(){this.channelAdapter.teardown()}async _fetchWithTimeout(e,i,a){const l=new AbortController,c=setTimeout(()=>l.abort(),a),u=await this.socket.fetch(e,Object.assign(Object.assign({},i),{signal:l.signal}));return clearTimeout(c),u}_on(e,i,a){const l=e.toLocaleLowerCase(),c=i==null?void 0:i.filter;(c instanceof nk||typeof c=="object"&&c!==null&&typeof c.build=="function")&&(i=Object.assign(Object.assign({},i),{filter:c.build()}));const u=this.channelAdapter.on(e,a),d={type:l,filter:i,callback:a,ref:u};return this.bindings[l]?this.bindings[l].push(d):this.bindings[l]=[d],this._updateFilterMessage(),this}_onClose(e){this.channelAdapter.onClose(e)}_onError(e){this.channelAdapter.onError(e)}_updateFilterMessage(){this.channelAdapter.updateFilterBindings((e,i,a)=>{var l,c,u,d,m,p,y;const v=e.event.toLocaleLowerCase();if(this._notThisChannelEvent(v,a))return!1;const x=(l=this.bindings[v])===null||l===void 0?void 0:l.find(_=>_.ref===e.ref);if(!x)return!0;if(["broadcast","presence","postgres_changes"].includes(v))if("id"in x){const _=x.id,S=(c=x.filter)===null||c===void 0?void 0:c.event;return _&&((u=i.ids)===null||u===void 0?void 0:u.includes(_))&&(S==="*"||(S==null?void 0:S.toLocaleLowerCase())===((d=i.data)===null||d===void 0?void 0:d.type.toLocaleLowerCase()))}else{const _=(p=(m=x==null?void 0:x.filter)===null||m===void 0?void 0:m.event)===null||p===void 0?void 0:p.toLocaleLowerCase();return _==="*"||_===((y=i==null?void 0:i.event)===null||y===void 0?void 0:y.toLocaleLowerCase())}else return x.type.toLocaleLowerCase()===v})}_notThisChannelEvent(e,i){const{close:a,error:l,leave:c,join:u}=bw;return i&&[a,l,c,u].includes(e)&&i!==this.joinPush.ref}_updateFilterTransform(){this.channelAdapter.updatePayloadTransform((e,i,a)=>{if(typeof i=="object"&&"ids"in i){const l=i.data,{schema:c,table:u,commit_timestamp:d,type:m,errors:p}=l;return Object.assign(Object.assign({},{schema:c,table:u,commit_timestamp:d,eventType:m,new:{},old:{},errors:p}),this._getPayloadRecords(l))}return i})}copyBindings(e){if(this.joinedOnce)throw new Error("cannot copy bindings into joined channel");for(const i in e.bindings)for(const a of e.bindings[i])this._on(a.type,a.filter,a.callback)}static isFilterValueEqual(e,i){return(e??void 0)===(i??void 0)}_getPayloadRecords(e){const i={new:{},old:{}};return(e.type==="INSERT"||e.type==="UPDATE")&&(i.new=Rb(e.columns,e.record)),(e.type==="UPDATE"||e.type==="DELETE")&&(i.old=Rb(e.columns,e.old_record)),i}}class sk{constructor(e,i){this.socket=new FN(e,i)}get timeout(){return this.socket.timeout}get endPoint(){return this.socket.endPoint}get transport(){return this.socket.transport}get heartbeatIntervalMs(){return this.socket.heartbeatIntervalMs}get heartbeatCallback(){return this.socket.heartbeatCallback}set heartbeatCallback(e){this.socket.heartbeatCallback=e}get heartbeatTimer(){return this.socket.heartbeatTimer}get pendingHeartbeatRef(){return this.socket.pendingHeartbeatRef}get reconnectTimer(){return this.socket.reconnectTimer}get vsn(){return this.socket.vsn}get encode(){return this.socket.encode}get decode(){return this.socket.decode}get reconnectAfterMs(){return this.socket.reconnectAfterMs}get sendBuffer(){return this.socket.sendBuffer}get stateChangeCallbacks(){return this.socket.stateChangeCallbacks}connect(){this.socket.connect()}disconnect(e,i,a,l=1e4){return new Promise(c=>{setTimeout(()=>c("timeout"),l),this.socket.disconnect(()=>{e(),c("ok")},i,a)})}push(e){this.socket.push(e)}log(e,i,a){this.socket.log(e,i,a)}makeRef(){return this.socket.makeRef()}onOpen(e){this.socket.onOpen(e)}onClose(e){this.socket.onClose(e)}onError(e){this.socket.onError(e)}onMessage(e){this.socket.onMessage(e)}isConnected(){return this.socket.isConnected()}isConnecting(){return this.socket.connectionState()==uf.connecting}isDisconnecting(){return this.socket.connectionState()==uf.closing}connectionState(){return this.socket.connectionState()}endPointURL(){return this.socket.endPointURL()}sendHeartbeat(){this.socket.sendHeartbeat()}getSocket(){return this.socket}}const Bb={HEARTBEAT_INTERVAL:25e3},ik=[1e3,2e3,5e3,1e4],ak=1e4;function rk(){const n=new Map;return{get length(){return n.size},clear(){n.clear()},getItem(e){return n.has(e)?n.get(e):null},key(e){var i;return(i=Array.from(n.keys())[e])!==null&&i!==void 0?i:null},removeItem(e){n.delete(e)},setItem(e,i){n.set(e,String(i))}}}function ok(){try{if(typeof globalThis<"u"&&globalThis.sessionStorage)return globalThis.sessionStorage}catch{}return rk()}const lk=` - addEventListener("message", (e) => { - if (e.data.event === "start") { - setInterval(() => postMessage({ event: "keepAlive" }), e.data.interval); - } - });`;class ck{get endPoint(){return this.socketAdapter.endPoint}get timeout(){return this.socketAdapter.timeout}get transport(){return this.socketAdapter.transport}get heartbeatCallback(){return this.socketAdapter.heartbeatCallback}get heartbeatIntervalMs(){return this.socketAdapter.heartbeatIntervalMs}get heartbeatTimer(){return this.worker?this._workerHeartbeatTimer:this.socketAdapter.heartbeatTimer}get pendingHeartbeatRef(){return this.worker?this._pendingWorkerHeartbeatRef:this.socketAdapter.pendingHeartbeatRef}get reconnectTimer(){return this.socketAdapter.reconnectTimer}get vsn(){return this.socketAdapter.vsn}get encode(){return this.socketAdapter.encode}get decode(){return this.socketAdapter.decode}get reconnectAfterMs(){return this.socketAdapter.reconnectAfterMs}get sendBuffer(){return this.socketAdapter.sendBuffer}get stateChangeCallbacks(){return this.socketAdapter.stateChangeCallbacks}constructor(e,i){var a;if(this.channels=new Array,this.accessTokenValue=null,this.accessToken=null,this.apiKey=null,this.httpEndpoint="",this.headers={},this.params={},this.ref=0,this.serializer=new kN,this._manuallySetToken=!1,this._authPromise=null,this._workerHeartbeatTimer=void 0,this._pendingWorkerHeartbeatRef=null,this._pendingDisconnectTimer=null,this._disconnectOnEmptyChannelsAfterMs=0,this._resolveFetch=c=>c?(...u)=>c(...u):(...u)=>fetch(...u),!(!((a=i==null?void 0:i.params)===null||a===void 0)&&a.apikey))throw new Error("API key is required to connect to Realtime");this.apiKey=i.params.apikey;const l=this._initializeOptions(i);this.socketAdapter=new sk(e,l),this.httpEndpoint=xw(e),this.fetch=this._resolveFetch(i==null?void 0:i.fetch)}connect(){if(!(this.isConnecting()||this.isDisconnecting()||this.isConnected())){this.accessToken&&!this._authPromise&&this._setAuthSafely("connect"),this._setupConnectionHandlers();try{this.socketAdapter.connect()}catch(e){const i=e.message;throw new Error(`WebSocket not available: ${i}`)}this._handleNodeJsRaceCondition()}}endpointURL(){return this.socketAdapter.endPointURL()}async disconnect(e,i){return this._cancelPendingDisconnect(),this.isDisconnecting()?"ok":await this.socketAdapter.disconnect(()=>{clearInterval(this._workerHeartbeatTimer),this._terminateWorker()},e,i)}getChannels(){return this.channels}async removeChannel(e){const i=await e.unsubscribe();return i==="ok"&&e.teardown(),i}async removeAllChannels(){const e=this.channels.map(async a=>{const l=await a.unsubscribe();return a.teardown(),l}),i=await Promise.all(e);return await this.disconnect(),i}log(e,i,a){this.socketAdapter.log(e,i,a)}connectionState(){return this.socketAdapter.connectionState()||uf.closed}isConnected(){return this.socketAdapter.isConnected()}isConnecting(){return this.socketAdapter.isConnecting()}isDisconnecting(){return this.socketAdapter.isDisconnecting()}channel(e,i={config:{}}){const a=`realtime:${e}`,l=this.getChannels().find(c=>c.topic===a);if(l)return l;{const c=new ro(`realtime:${e}`,i,this);return this._cancelPendingDisconnect(),this.channels.push(c),c}}push(e){this.socketAdapter.push(e)}async setAuth(e=null){this._authPromise=this._performAuth(e);try{await this._authPromise}finally{this._authPromise=null}}_isManualToken(){return this._manuallySetToken}async sendHeartbeat(){this.socketAdapter.sendHeartbeat()}onHeartbeat(e){this.socketAdapter.heartbeatCallback=this._wrapHeartbeatCallback(e)}_makeRef(){return this.socketAdapter.makeRef()}_remove(e){this.channels=this.channels.filter(i=>i.topic!==e.topic),this.channels.length===0&&(this.log("transport","no channels remaining, scheduling disconnect"),this._schedulePendingDisconnect())}_schedulePendingDisconnect(){if(this._cancelPendingDisconnect(),this._disconnectOnEmptyChannelsAfterMs===0){this.log("transport","disconnecting immediately - no channels"),this.disconnect();return}this._pendingDisconnectTimer=setTimeout(()=>{this._pendingDisconnectTimer=null,this.channels.length===0&&(this.log("transport","deferred disconnect fired - no channels, disconnecting"),this.disconnect())},this._disconnectOnEmptyChannelsAfterMs),this.log("transport",`deferred disconnect scheduled in ${this._disconnectOnEmptyChannelsAfterMs}ms`)}_cancelPendingDisconnect(){this._pendingDisconnectTimer!==null&&(this.log("transport","pending disconnect cancelled - channel activity detected"),clearTimeout(this._pendingDisconnectTimer),this._pendingDisconnectTimer=null)}async _performAuth(e=null){let i,a=!1;if(e)i=e,a=!0;else if(this.accessToken)try{i=await this.accessToken()}catch(l){this.log("error","Error fetching access token from callback",l),i=this.accessTokenValue}else i=this.accessTokenValue;a?this._manuallySetToken=!0:this.accessToken&&(this._manuallySetToken=!1),this.accessTokenValue!=i&&(this.accessTokenValue=i,this.channels.forEach(l=>{const c={access_token:i,version:TN};i&&l.updateJoinPayload(c),l.joinedOnce&&l.channelAdapter.isJoined()&&l.channelAdapter.push(bw.access_token,{access_token:i})}))}async _waitForAuthIfNeeded(){this._authPromise&&await this._authPromise}_setAuthSafely(e="general"){this._isManualToken()||this.setAuth().catch(i=>{this.log("error",`Error setting auth in ${e}`,i)})}_setupConnectionHandlers(){this.socketAdapter.onOpen(()=>{(this._authPromise||(this.accessToken&&!this.accessTokenValue?this.setAuth():Promise.resolve())).catch(i=>{this.log("error","error waiting for auth on connect",i)}),this.worker&&!this.workerRef&&this._startWorkerHeartbeat()}),this.socketAdapter.onClose(()=>{this.worker&&this.workerRef&&this._terminateWorker()}),this.socketAdapter.onMessage(e=>{e.ref&&e.ref===this._pendingWorkerHeartbeatRef&&(this._pendingWorkerHeartbeatRef=null)})}_handleNodeJsRaceCondition(){this.socketAdapter.isConnected()&&this.socketAdapter.getSocket().onConnOpen()}_wrapHeartbeatCallback(e){return(i,a)=>{i!=="disconnected"&&(i=="sent"&&this._setAuthSafely(),e&&e(i,a))}}_startWorkerHeartbeat(){this.workerUrl?this.log("worker",`starting worker for from ${this.workerUrl}`):this.log("worker","starting default worker");const e=this._workerObjectUrl(this.workerUrl);this.workerRef=new Worker(e),this.workerRef.onerror=i=>{this.log("worker","worker error",i.message),this._terminateWorker(),this.disconnect()},this.workerRef.onmessage=i=>{i.data.event==="keepAlive"&&this.sendHeartbeat()},this.workerRef.postMessage({event:"start",interval:this.heartbeatIntervalMs})}_terminateWorker(){this.workerRef&&(this.log("worker","terminating worker"),this.workerRef.terminate(),this.workerRef=void 0)}_workerObjectUrl(e){let i;if(e)i=e;else{const a=new Blob([lk],{type:"application/javascript"});i=URL.createObjectURL(a)}return i}_initializeOptions(e){var i,a,l,c,u,d,m,p,y,v,x,_;this.worker=(i=e==null?void 0:e.worker)!==null&&i!==void 0?i:!1,this.accessToken=(a=e==null?void 0:e.accessToken)!==null&&a!==void 0?a:null;const S={};S.timeout=(l=e==null?void 0:e.timeout)!==null&&l!==void 0?l:jN,S.heartbeatIntervalMs=(c=e==null?void 0:e.heartbeatIntervalMs)!==null&&c!==void 0?c:Bb.HEARTBEAT_INTERVAL,this._disconnectOnEmptyChannelsAfterMs=(u=e==null?void 0:e.disconnectOnEmptyChannelsAfterMs)!==null&&u!==void 0?u:2*((d=e==null?void 0:e.heartbeatIntervalMs)!==null&&d!==void 0?d:Bb.HEARTBEAT_INTERVAL),S.transport=(m=e==null?void 0:e.transport)!==null&&m!==void 0?m:_N.getWebSocketConstructor(),S.params=e==null?void 0:e.params,S.logger=e==null?void 0:e.logger,S.heartbeatCallback=this._wrapHeartbeatCallback(e==null?void 0:e.heartbeatCallback),S.sessionStorage=(p=e==null?void 0:e.sessionStorage)!==null&&p!==void 0?p:ok(),S.reconnectAfterMs=(y=e==null?void 0:e.reconnectAfterMs)!==null&&y!==void 0?y:(M=>ik[M-1]||ak);let T,k;const R=(v=e==null?void 0:e.vsn)!==null&&v!==void 0?v:AN;switch(R){case EN:T=(M,N)=>N(JSON.stringify(M)),k=(M,N)=>N(JSON.parse(M));break;case yw:T=this.serializer.encode.bind(this.serializer),k=this.serializer.decode.bind(this.serializer);break;default:throw new Error(`Unsupported serializer version: ${S.vsn}`)}if(S.vsn=R,S.encode=(x=e==null?void 0:e.encode)!==null&&x!==void 0?x:T,S.decode=(_=e==null?void 0:e.decode)!==null&&_!==void 0?_:k,S.beforeReconnect=this._reconnectAuth.bind(this),(e!=null&&e.logLevel||e!=null&&e.log_level)&&(this.logLevel=e.logLevel||e.log_level,S.params=Object.assign(Object.assign({},S.params),{log_level:this.logLevel})),this.worker){if(typeof window<"u"&&!window.Worker)throw new Error("Web Worker is not supported");this.workerUrl=e==null?void 0:e.workerUrl,S.autoSendHeartbeat=!this.worker}return S}async _reconnectAuth(){await this._waitForAuthIfNeeded(),this.isConnected()||this.connect()}}var go=class extends Error{constructor(n,e){var i;super(n),this.name="IcebergError",this.status=e.status,this.icebergType=e.icebergType,this.icebergCode=e.icebergCode,this.details=e.details,this.isCommitStateUnknown=e.icebergType==="CommitStateUnknownException"||[500,502,504].includes(e.status)&&((i=e.icebergType)==null?void 0:i.includes("CommitState"))===!0}isNotFound(){return this.status===404}isConflict(){return this.status===409}isAuthenticationTimeout(){return this.status===419}};function uk(n,e,i){const a=new URL(e,n);if(i)for(const[l,c]of Object.entries(i))c!==void 0&&a.searchParams.set(l,c);return a.toString()}async function hk(n){return!n||n.type==="none"?{}:n.type==="bearer"?{Authorization:`Bearer ${n.token}`}:n.type==="header"?{[n.name]:n.value}:n.type==="custom"?await n.getHeaders():{}}function dk(n){const e=n.fetchImpl??globalThis.fetch;return{async request({method:i,path:a,query:l,body:c,headers:u}){const d=uk(n.baseUrl,a,l),m=await hk(n.auth),p=await e(d,{method:i,headers:{...c?{"Content-Type":"application/json"}:{},...m,...u},body:c?JSON.stringify(c):void 0}),y=await p.text(),v=(p.headers.get("content-type")||"").includes("application/json"),x=v&&y?JSON.parse(y):y;if(!p.ok){const _=v?x:void 0,S=_==null?void 0:_.error;throw new go((S==null?void 0:S.message)??`Request failed with status ${p.status}`,{status:p.status,icebergType:S==null?void 0:S.type,icebergCode:S==null?void 0:S.code,details:_})}return{status:p.status,headers:p.headers,data:x}}}}function sc(n){return n.join("")}var fk=class{constructor(n,e=""){this.client=n,this.prefix=e}async listNamespaces(n){const e=n?{parent:sc(n.namespace)}:void 0;return(await this.client.request({method:"GET",path:`${this.prefix}/namespaces`,query:e})).data.namespaces.map(a=>({namespace:a}))}async createNamespace(n,e){const i={namespace:n.namespace,properties:e==null?void 0:e.properties};return(await this.client.request({method:"POST",path:`${this.prefix}/namespaces`,body:i})).data}async dropNamespace(n){await this.client.request({method:"DELETE",path:`${this.prefix}/namespaces/${sc(n.namespace)}`})}async loadNamespaceMetadata(n){return{properties:(await this.client.request({method:"GET",path:`${this.prefix}/namespaces/${sc(n.namespace)}`})).data.properties}}async namespaceExists(n){try{return await this.client.request({method:"HEAD",path:`${this.prefix}/namespaces/${sc(n.namespace)}`}),!0}catch(e){if(e instanceof go&&e.status===404)return!1;throw e}}async createNamespaceIfNotExists(n,e){try{return await this.createNamespace(n,e)}catch(i){if(i instanceof go&&i.status===409)return;throw i}}};function ja(n){return n.join("")}var mk=class{constructor(n,e="",i){this.client=n,this.prefix=e,this.accessDelegation=i}async listTables(n){return(await this.client.request({method:"GET",path:`${this.prefix}/namespaces/${ja(n.namespace)}/tables`})).data.identifiers}async createTable(n,e){const i={};return this.accessDelegation&&(i["X-Iceberg-Access-Delegation"]=this.accessDelegation),(await this.client.request({method:"POST",path:`${this.prefix}/namespaces/${ja(n.namespace)}/tables`,body:e,headers:i})).data.metadata}async updateTable(n,e){const i=await this.client.request({method:"POST",path:`${this.prefix}/namespaces/${ja(n.namespace)}/tables/${n.name}`,body:e});return{"metadata-location":i.data["metadata-location"],metadata:i.data.metadata}}async dropTable(n,e){await this.client.request({method:"DELETE",path:`${this.prefix}/namespaces/${ja(n.namespace)}/tables/${n.name}`,query:{purgeRequested:String((e==null?void 0:e.purge)??!1)}})}async loadTable(n){const e={};return this.accessDelegation&&(e["X-Iceberg-Access-Delegation"]=this.accessDelegation),(await this.client.request({method:"GET",path:`${this.prefix}/namespaces/${ja(n.namespace)}/tables/${n.name}`,headers:e})).data.metadata}async tableExists(n){const e={};this.accessDelegation&&(e["X-Iceberg-Access-Delegation"]=this.accessDelegation);try{return await this.client.request({method:"HEAD",path:`${this.prefix}/namespaces/${ja(n.namespace)}/tables/${n.name}`,headers:e}),!0}catch(i){if(i instanceof go&&i.status===404)return!1;throw i}}async createTableIfNotExists(n,e){try{return await this.createTable(n,e)}catch(i){if(i instanceof go&&i.status===409)return await this.loadTable({namespace:n.namespace,name:e.name});throw i}}},pk=class{constructor(n){var a;let e="v1";n.catalogName&&(e+=`/${n.catalogName}`);const i=n.baseUrl.endsWith("/")?n.baseUrl:`${n.baseUrl}/`;this.client=dk({baseUrl:i,auth:n.auth,fetchImpl:n.fetch}),this.accessDelegation=(a=n.accessDelegation)==null?void 0:a.join(","),this.namespaceOps=new fk(this.client,e),this.tableOps=new mk(this.client,e,this.accessDelegation)}async listNamespaces(n){return this.namespaceOps.listNamespaces(n)}async createNamespace(n,e){return this.namespaceOps.createNamespace(n,e)}async dropNamespace(n){await this.namespaceOps.dropNamespace(n)}async loadNamespaceMetadata(n){return this.namespaceOps.loadNamespaceMetadata(n)}async listTables(n){return this.tableOps.listTables(n)}async createTable(n,e){return this.tableOps.createTable(n,e)}async updateTable(n,e){return this.tableOps.updateTable(n,e)}async dropTable(n,e){await this.tableOps.dropTable(n,e)}async loadTable(n){return this.tableOps.loadTable(n)}async namespaceExists(n){return this.namespaceOps.namespaceExists(n)}async tableExists(n){return this.tableOps.tableExists(n)}async createNamespaceIfNotExists(n,e){return this.namespaceOps.createNamespaceIfNotExists(n,e)}async createTableIfNotExists(n,e){return this.tableOps.createTableIfNotExists(n,e)}};function yo(n){"@babel/helpers - typeof";return yo=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},yo(n)}function gk(n,e){if(yo(n)!="object"||!n)return n;var i=n[Symbol.toPrimitive];if(i!==void 0){var a=i.call(n,e);if(yo(a)!="object")return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(n)}function yk(n){var e=gk(n,"string");return yo(e)=="symbol"?e:e+""}function bk(n,e,i){return(e=yk(e))in n?Object.defineProperty(n,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):n[e]=i,n}function Ub(n,e){var i=Object.keys(n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(n);e&&(a=a.filter(function(l){return Object.getOwnPropertyDescriptor(n,l).enumerable})),i.push.apply(i,a)}return i}function ge(n){for(var e=1;en?(...e)=>n(...e):(...e)=>fetch(...e),wk=n=>{if(typeof n!="object"||n===null)return!1;const e=Object.getPrototypeOf(n);return(e===null||e===Object.prototype||Object.getPrototypeOf(e)===null)&&!(Symbol.toStringTag in n)&&!(Symbol.iterator in n)},pf=n=>{if(Array.isArray(n))return n.map(i=>pf(i));if(typeof n=="function"||n!==Object(n))return n;const e={};return Object.entries(n).forEach(([i,a])=>{const l=i.replace(/([-_][a-z])/gi,c=>c.toUpperCase().replace(/[-_]/g,""));e[l]=pf(a)}),e},_k=n=>!n||typeof n!="string"||n.length===0||n.length>100||n.trim()!==n||n.includes("/")||n.includes("\\")?!1:/^[\w!.\*'() &$@=;:+,?-]+$/.test(n),Lb=n=>{if(typeof n=="object"&&n!==null){const e=n;if(typeof e.msg=="string")return e.msg;if(typeof e.message=="string")return e.message;if(typeof e.error_description=="string")return e.error_description;if(typeof e.error=="string")return e.error;if(typeof e.error=="object"&&e.error!==null){const i=e.error;if(typeof i.message=="string")return i.message}}return JSON.stringify(n)},Sk=async(n,e,i,a)=>{if(n!==null&&typeof n=="object"&&"json"in n&&typeof n.json=="function"){const l=n;let c=parseInt(String(l.status),10);Number.isFinite(c)||(c=500),l.json().then(u=>{const d=(u==null?void 0:u.statusCode)||(u==null?void 0:u.code)||c+"";e(new mf(Lb(u),c,d,a))}).catch(()=>{const u=c+"";e(new mf(l.statusText||`HTTP ${c} error`,c,u,a))})}else e(new _w(Lb(n),n,a))},Tk=(n,e,i,a)=>{const l={method:n,headers:(e==null?void 0:e.headers)||{}};if(n==="GET"||n==="HEAD"||!a)return ge(ge({},l),i);if(wk(a)){var c;const u=(e==null?void 0:e.headers)||{};let d;for(const[m,p]of Object.entries(u))m.toLowerCase()==="content-type"&&(d=p);l.headers=Cc(u,"Content-Type",(c=d)!==null&&c!==void 0?c:"application/json"),l.body=JSON.stringify(a)}else l.body=a;return e!=null&&e.duplex&&(l.duplex=e.duplex),ge(ge({},l),i)};async function Kr(n,e,i,a,l,c,u){return new Promise((d,m)=>{n(i,Tk(e,a,l,c)).then(p=>{if(!p.ok)throw p;if(a!=null&&a.noResolveJson)return p;if(u==="vectors"){const y=p.headers.get("content-type");if(p.headers.get("content-length")==="0"||p.status===204)return{};if(!y||!y.includes("application/json"))return{}}return p.json()}).then(p=>d(p)).catch(p=>Sk(p,m,a,u))})}function Sw(n="storage"){return{get:async(e,i,a,l)=>Kr(e,"GET",i,a,l,void 0,n),post:async(e,i,a,l,c)=>Kr(e,"POST",i,l,c,a,n),put:async(e,i,a,l,c)=>Kr(e,"PUT",i,l,c,a,n),head:async(e,i,a,l)=>Kr(e,"HEAD",i,ge(ge({},a),{},{noResolveJson:!0}),l,void 0,n),remove:async(e,i,a,l,c)=>Kr(e,"DELETE",i,l,c,a,n)}}const Ek=Sw("storage"),{get:bo,post:Vn,put:gf,head:Ak,remove:vo}=Ek,hn=Sw("vectors");var Qa=class{constructor(n,e={},i,a="storage"){this.shouldThrowOnError=!1,this.url=n,this.headers=vk(e),this.fetch=xk(i),this.namespace=a}throwOnError(){return this.shouldThrowOnError=!0,this}setHeader(n,e){return this.headers=Cc(this.headers,n,e),this}async handleOperation(n){var e=this;try{return{data:await n(),error:null}}catch(i){if(e.shouldThrowOnError)throw i;if(Gc(i))return{data:null,error:i};throw i}}};let Tw;Tw=Symbol.toStringTag;var jk=class{constructor(n,e){this.downloadFn=n,this.shouldThrowOnError=e,this[Tw]="StreamDownloadBuilder",this.promise=null}then(n,e){return this.getPromise().then(n,e)}catch(n){return this.getPromise().catch(n)}finally(n){return this.getPromise().finally(n)}getPromise(){return this.promise||(this.promise=this.execute()),this.promise}async execute(){var n=this;try{return{data:(await n.downloadFn()).body,error:null}}catch(e){if(n.shouldThrowOnError)throw e;if(Gc(e))return{data:null,error:e};throw e}}};let Ew;Ew=Symbol.toStringTag;var Nk=class{constructor(n,e){this.downloadFn=n,this.shouldThrowOnError=e,this[Ew]="BlobDownloadBuilder",this.promise=null}asStream(){return new jk(this.downloadFn,this.shouldThrowOnError)}then(n,e){return this.getPromise().then(n,e)}catch(n){return this.getPromise().catch(n)}finally(n){return this.getPromise().finally(n)}getPromise(){return this.promise||(this.promise=this.execute()),this.promise}async execute(){var n=this;try{return{data:await(await n.downloadFn()).blob(),error:null}}catch(e){if(n.shouldThrowOnError)throw e;if(Gc(e))return{data:null,error:e};throw e}}};const Ed={limit:100,offset:0,sortBy:{column:"name",order:"asc"}},zb={cacheControl:"3600",contentType:"text/plain;charset=UTF-8",upsert:!1};var kk=class extends Qa{constructor(n,e={},i,a){super(n,e,a,"storage"),this.bucketId=i}async uploadOrUpdate(n,e,i,a){var l=this;return l.handleOperation(async()=>{let c;const u=ge(ge({},zb),a);let d=ge(ge({},l.headers),n==="POST"&&{"x-upsert":String(u.upsert)});const m=u.metadata;if(typeof Blob<"u"&&i instanceof Blob?(c=new FormData,c.append("cacheControl",u.cacheControl),m&&c.append("metadata",l.encodeMetadata(m)),c.append("",i)):typeof FormData<"u"&&i instanceof FormData?(c=i,c.has("cacheControl")||c.append("cacheControl",u.cacheControl),m&&!c.has("metadata")&&c.append("metadata",l.encodeMetadata(m))):(c=i,d["cache-control"]=`max-age=${u.cacheControl}`,d["content-type"]=u.contentType,m&&(d["x-metadata"]=l.toBase64(l.encodeMetadata(m))),(typeof ReadableStream<"u"&&c instanceof ReadableStream||c&&typeof c=="object"&&"pipe"in c&&typeof c.pipe=="function")&&!u.duplex&&(u.duplex="half")),a!=null&&a.headers)for(const[x,_]of Object.entries(a.headers))d=Cc(d,x,_);const p=l._removeEmptyFolders(e),y=l._getFinalPath(p),v=await(n=="PUT"?gf:Vn)(l.fetch,`${l.url}/object/${y}`,c,ge({headers:d},u!=null&&u.duplex?{duplex:u.duplex}:{}));return{path:p,id:v.Id,fullPath:v.Key}})}async upload(n,e,i){return this.uploadOrUpdate("POST",n,e,i)}async uploadToSignedUrl(n,e,i,a){var l=this;const c=l._removeEmptyFolders(n),u=l._getFinalPath(c),d=new URL(l.url+`/object/upload/sign/${u}`);return d.searchParams.set("token",e),l.handleOperation(async()=>{let m;const p=ge(ge({},zb),a);let y=ge(ge({},l.headers),{"x-upsert":String(p.upsert)});const v=p.metadata;if(typeof Blob<"u"&&i instanceof Blob?(m=new FormData,m.append("cacheControl",p.cacheControl),v&&m.append("metadata",l.encodeMetadata(v)),m.append("",i)):typeof FormData<"u"&&i instanceof FormData?(m=i,m.has("cacheControl")||m.append("cacheControl",p.cacheControl),v&&!m.has("metadata")&&m.append("metadata",l.encodeMetadata(v))):(m=i,y["cache-control"]=`max-age=${p.cacheControl}`,y["content-type"]=p.contentType,v&&(y["x-metadata"]=l.toBase64(l.encodeMetadata(v))),(typeof ReadableStream<"u"&&m instanceof ReadableStream||m&&typeof m=="object"&&"pipe"in m&&typeof m.pipe=="function")&&!p.duplex&&(p.duplex="half")),a!=null&&a.headers)for(const[x,_]of Object.entries(a.headers))y=Cc(y,x,_);return{path:c,fullPath:(await gf(l.fetch,d.toString(),m,ge({headers:y},p!=null&&p.duplex?{duplex:p.duplex}:{}))).Key}})}async createSignedUploadUrl(n,e){var i=this;return i.handleOperation(async()=>{let a=i._getFinalPath(n);const l=ge({},i.headers);e!=null&&e.upsert&&(l["x-upsert"]="true");const c=await Vn(i.fetch,`${i.url}/object/upload/sign/${a}`,{},{headers:l}),u=new URL(i.url+c.url),d=u.searchParams.get("token");if(!d)throw new Ic("No token returned by API");return{signedUrl:u.toString(),path:n,token:d}})}async update(n,e,i){return this.uploadOrUpdate("PUT",n,e,i)}async move(n,e,i){var a=this;return a.handleOperation(async()=>await Vn(a.fetch,`${a.url}/object/move`,{bucketId:a.bucketId,sourceKey:n,destinationKey:e,destinationBucket:i==null?void 0:i.destinationBucket},{headers:a.headers}))}async copy(n,e,i){var a=this;return a.handleOperation(async()=>({path:(await Vn(a.fetch,`${a.url}/object/copy`,{bucketId:a.bucketId,sourceKey:n,destinationKey:e,destinationBucket:i==null?void 0:i.destinationBucket},{headers:a.headers})).Key}))}async createSignedUrl(n,e,i){var a=this;return a.handleOperation(async()=>{let l=a._getFinalPath(n);const c=typeof(i==null?void 0:i.transform)=="object"&&i.transform!==null&&Object.keys(i.transform).length>0;let u=await Vn(a.fetch,`${a.url}/object/sign/${l}`,ge({expiresIn:e},c?{transform:i.transform}:{}),{headers:a.headers});const d=new URLSearchParams;i!=null&&i.download&&d.set("download",i.download===!0?"":i.download),(i==null?void 0:i.cacheNonce)!=null&&d.set("cacheNonce",String(i.cacheNonce));const m=d.toString();return{signedUrl:encodeURI(`${a.url}${u.signedURL}${m?`&${m}`:""}`)}})}async createSignedUrls(n,e,i){var a=this;return a.handleOperation(async()=>{const l=await Vn(a.fetch,`${a.url}/object/sign/${a.bucketId}`,{expiresIn:e,paths:n},{headers:a.headers}),c=new URLSearchParams;i!=null&&i.download&&c.set("download",i.download===!0?"":i.download),(i==null?void 0:i.cacheNonce)!=null&&c.set("cacheNonce",String(i.cacheNonce));const u=c.toString();return l.map(d=>ge(ge({},d),{},{signedUrl:d.signedURL?encodeURI(`${a.url}${d.signedURL}${u?`&${u}`:""}`):null}))})}download(n,e,i){const a=typeof(e==null?void 0:e.transform)=="object"&&e.transform!==null&&Object.keys(e.transform).length>0?"render/image/authenticated":"object",l=new URLSearchParams;e!=null&&e.transform&&this.applyTransformOptsToQuery(l,e.transform),(e==null?void 0:e.cacheNonce)!=null&&l.set("cacheNonce",String(e.cacheNonce));const c=l.toString(),u=this._getFinalPath(n),d=()=>bo(this.fetch,`${this.url}/${a}/${u}${c?`?${c}`:""}`,{headers:this.headers,noResolveJson:!0},i);return new Nk(d,this.shouldThrowOnError)}async info(n){var e=this;const i=e._getFinalPath(n);return e.handleOperation(async()=>pf(await bo(e.fetch,`${e.url}/object/info/${i}`,{headers:e.headers})))}async exists(n){var e=this;const i=e._getFinalPath(n);try{return await Ak(e.fetch,`${e.url}/object/${i}`,{headers:e.headers}),{data:!0,error:null}}catch(l){if(e.shouldThrowOnError)throw l;if(Gc(l)){var a;const c=l instanceof mf?l.status:l instanceof _w?(a=l.originalError)===null||a===void 0?void 0:a.status:void 0;if(c!==void 0&&[400,404].includes(c))return{data:!1,error:l}}throw l}}getPublicUrl(n,e){const i=this._getFinalPath(n),a=new URLSearchParams;e!=null&&e.download&&a.set("download",e.download===!0?"":e.download),e!=null&&e.transform&&this.applyTransformOptsToQuery(a,e.transform),(e==null?void 0:e.cacheNonce)!=null&&a.set("cacheNonce",String(e.cacheNonce));const l=a.toString(),c=typeof(e==null?void 0:e.transform)=="object"&&e.transform!==null&&Object.keys(e.transform).length>0?"render/image":"object";return{data:{publicUrl:encodeURI(`${this.url}/${c}/public/${i}`)+(l?`?${l}`:"")}}}async remove(n){var e=this;return e.handleOperation(async()=>await vo(e.fetch,`${e.url}/object/${e.bucketId}`,{prefixes:n},{headers:e.headers}))}async purgeCache(n,e,i){var a=this;return a.handleOperation(async()=>{const l=a._getFinalPath(n),c=new URLSearchParams;e!=null&&e.transformations&&c.set("transformations","true");const u=c.toString();return await vo(a.fetch,`${a.url}/cdn/${l}${u?`?${u}`:""}`,{},{headers:a.headers},i)})}async list(n,e,i){var a=this;return a.handleOperation(async()=>{const l=e!=null&&e.sortBy?ge(ge({},Ed.sortBy),e.sortBy):Ed.sortBy,c=ge(ge(ge({},Ed),e),{},{sortBy:l,prefix:n||""});return await Vn(a.fetch,`${a.url}/object/list/${a.bucketId}`,c,{headers:a.headers},i)})}async listV2(n,e){var i=this;return i.handleOperation(async()=>{const a=ge({},n);return await Vn(i.fetch,`${i.url}/object/list-v2/${i.bucketId}`,a,{headers:i.headers},e)})}encodeMetadata(n){return JSON.stringify(n)}toBase64(n){return typeof Buffer<"u"?Buffer.from(n).toString("base64"):btoa(n)}_getFinalPath(n){return`${this.bucketId}/${n.replace(/^\/+/,"")}`}_removeEmptyFolders(n){return n.replace(/^\/|\/$/g,"").replace(/\/+/g,"/")}applyTransformOptsToQuery(n,e){return e.width&&n.set("width",e.width.toString()),e.height&&n.set("height",e.height.toString()),e.resize&&n.set("resize",e.resize),e.format&&n.set("format",e.format),e.quality&&n.set("quality",e.quality.toString()),n}};const Rk="2.110.2",No={"X-Client-Info":`storage-js/${Rk}`};var Ck=class extends Qa{constructor(n,e={},i,a){const l=new URL(n);a!=null&&a.useNewHostname&&/supabase\.(co|in|red)$/.test(l.hostname)&&!l.hostname.includes("storage.supabase.")&&(l.hostname=l.hostname.replace("supabase.","storage.supabase."));const c=l.href.replace(/\/$/,""),u=ge(ge({},No),e);super(c,u,i,"storage")}async listBuckets(n){var e=this;return e.handleOperation(async()=>{const i=e.listBucketOptionsToQueryString(n);return await bo(e.fetch,`${e.url}/bucket${i}`,{headers:e.headers})})}async getBucket(n){var e=this;return e.handleOperation(async()=>await bo(e.fetch,`${e.url}/bucket/${n}`,{headers:e.headers}))}async createBucket(n,e={public:!1}){var i=this;return i.handleOperation(async()=>await Vn(i.fetch,`${i.url}/bucket`,{id:n,name:n,type:e.type,public:e.public,file_size_limit:e.fileSizeLimit,allowed_mime_types:e.allowedMimeTypes},{headers:i.headers}))}async updateBucket(n,e){var i=this;return i.handleOperation(async()=>await gf(i.fetch,`${i.url}/bucket/${n}`,{id:n,name:n,public:e.public,file_size_limit:e.fileSizeLimit,allowed_mime_types:e.allowedMimeTypes},{headers:i.headers}))}async emptyBucket(n){var e=this;return e.handleOperation(async()=>await Vn(e.fetch,`${e.url}/bucket/${n}/empty`,{},{headers:e.headers}))}async deleteBucket(n){var e=this;return e.handleOperation(async()=>await vo(e.fetch,`${e.url}/bucket/${n}`,{},{headers:e.headers}))}async purgeBucketCache(n,e,i){var a=this;return a.handleOperation(async()=>{const l=new URLSearchParams;e!=null&&e.transformations&&l.set("transformations","true");const c=l.toString();return await vo(a.fetch,`${a.url}/cdn/${n}${c?`?${c}`:""}`,{},{headers:a.headers},i)})}listBucketOptionsToQueryString(n){const e={};return n&&("limit"in n&&(e.limit=String(n.limit)),"offset"in n&&(e.offset=String(n.offset)),n.search&&(e.search=n.search),n.sortColumn&&(e.sortColumn=n.sortColumn),n.sortOrder&&(e.sortOrder=n.sortOrder)),Object.keys(e).length>0?"?"+new URLSearchParams(e).toString():""}},Ok=class extends Qa{constructor(n,e={},i){const a=n.replace(/\/$/,""),l=ge(ge({},No),e);super(a,l,i,"storage")}async createBucket(n){var e=this;return e.handleOperation(async()=>await Vn(e.fetch,`${e.url}/bucket`,{name:n},{headers:e.headers}))}async listBuckets(n){var e=this;return e.handleOperation(async()=>{const i=new URLSearchParams;(n==null?void 0:n.limit)!==void 0&&i.set("limit",n.limit.toString()),(n==null?void 0:n.offset)!==void 0&&i.set("offset",n.offset.toString()),n!=null&&n.sortColumn&&i.set("sortColumn",n.sortColumn),n!=null&&n.sortOrder&&i.set("sortOrder",n.sortOrder),n!=null&&n.search&&i.set("search",n.search);const a=i.toString(),l=a?`${e.url}/bucket?${a}`:`${e.url}/bucket`;return await bo(e.fetch,l,{headers:e.headers})})}async deleteBucket(n){var e=this;return e.handleOperation(async()=>await vo(e.fetch,`${e.url}/bucket/${n}`,{},{headers:e.headers}))}from(n){var e=this;if(!_k(n))throw new Ic("Invalid bucket name: File, folder, and bucket names must follow AWS object key naming guidelines and should avoid the use of any other characters.");const i=new pk({baseUrl:this.url,catalogName:n,auth:{type:"custom",getHeaders:async()=>e.headers},fetch:this.fetch}),a=this.shouldThrowOnError;return new Proxy(i,{get(l,c){const u=l[c];return typeof u!="function"?u:async(...d)=>{try{return{data:await u.apply(l,d),error:null}}catch(m){if(a)throw m;return{data:null,error:m}}}}})}},Dk=class extends Qa{constructor(n,e={},i){const a=n.replace(/\/$/,""),l=ge(ge({},No),{},{"Content-Type":"application/json"},e);super(a,l,i,"vectors")}async createIndex(n){var e=this;return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/CreateIndex`,n,{headers:e.headers})||{})}async getIndex(n,e){var i=this;return i.handleOperation(async()=>await hn.post(i.fetch,`${i.url}/GetIndex`,{vectorBucketName:n,indexName:e},{headers:i.headers}))}async listIndexes(n){var e=this;return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/ListIndexes`,n,{headers:e.headers}))}async deleteIndex(n,e){var i=this;return i.handleOperation(async()=>await hn.post(i.fetch,`${i.url}/DeleteIndex`,{vectorBucketName:n,indexName:e},{headers:i.headers})||{})}},Mk=class extends Qa{constructor(n,e={},i){const a=n.replace(/\/$/,""),l=ge(ge({},No),{},{"Content-Type":"application/json"},e);super(a,l,i,"vectors")}async putVectors(n){var e=this;if(n.vectors.length<1||n.vectors.length>500)throw new Error("Vector batch size must be between 1 and 500 items");return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/PutVectors`,n,{headers:e.headers})||{})}async getVectors(n){var e=this;return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/GetVectors`,n,{headers:e.headers}))}async listVectors(n){var e=this;if(n.segmentCount!==void 0){if(n.segmentCount<1||n.segmentCount>16)throw new Error("segmentCount must be between 1 and 16");if(n.segmentIndex!==void 0&&(n.segmentIndex<0||n.segmentIndex>=n.segmentCount))throw new Error(`segmentIndex must be between 0 and ${n.segmentCount-1}`)}return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/ListVectors`,n,{headers:e.headers}))}async queryVectors(n){var e=this;return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/QueryVectors`,n,{headers:e.headers}))}async deleteVectors(n){var e=this;if(n.keys.length<1||n.keys.length>500)throw new Error("Keys batch size must be between 1 and 500 items");return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/DeleteVectors`,n,{headers:e.headers})||{})}},Bk=class extends Qa{constructor(n,e={},i){const a=n.replace(/\/$/,""),l=ge(ge({},No),{},{"Content-Type":"application/json"},e);super(a,l,i,"vectors")}async createBucket(n){var e=this;return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/CreateVectorBucket`,{vectorBucketName:n},{headers:e.headers})||{})}async getBucket(n){var e=this;return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/GetVectorBucket`,{vectorBucketName:n},{headers:e.headers}))}async listBuckets(n={}){var e=this;return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/ListVectorBuckets`,n,{headers:e.headers}))}async deleteBucket(n){var e=this;return e.handleOperation(async()=>await hn.post(e.fetch,`${e.url}/DeleteVectorBucket`,{vectorBucketName:n},{headers:e.headers})||{})}},Uk=class extends Bk{constructor(n,e={}){super(n,e.headers||{},e.fetch)}from(n){return new Lk(this.url,this.headers,n,this.fetch)}async createBucket(n){var e=()=>super.createBucket,i=this;return e().call(i,n)}async getBucket(n){var e=()=>super.getBucket,i=this;return e().call(i,n)}async listBuckets(n={}){var e=()=>super.listBuckets,i=this;return e().call(i,n)}async deleteBucket(n){var e=()=>super.deleteBucket,i=this;return e().call(i,n)}},Lk=class extends Dk{constructor(n,e,i,a){super(n,e,a),this.vectorBucketName=i}async createIndex(n){var e=()=>super.createIndex,i=this;return e().call(i,ge(ge({},n),{},{vectorBucketName:i.vectorBucketName}))}async listIndexes(n={}){var e=()=>super.listIndexes,i=this;return e().call(i,ge(ge({},n),{},{vectorBucketName:i.vectorBucketName}))}async getIndex(n){var e=()=>super.getIndex,i=this;return e().call(i,i.vectorBucketName,n)}async deleteIndex(n){var e=()=>super.deleteIndex,i=this;return e().call(i,i.vectorBucketName,n)}index(n){return new zk(this.url,this.headers,this.vectorBucketName,n,this.fetch)}},zk=class extends Mk{constructor(n,e,i,a,l){super(n,e,l),this.vectorBucketName=i,this.indexName=a}async putVectors(n){var e=()=>super.putVectors,i=this;return e().call(i,ge(ge({},n),{},{vectorBucketName:i.vectorBucketName,indexName:i.indexName}))}async getVectors(n){var e=()=>super.getVectors,i=this;return e().call(i,ge(ge({},n),{},{vectorBucketName:i.vectorBucketName,indexName:i.indexName}))}async listVectors(n={}){var e=()=>super.listVectors,i=this;return e().call(i,ge(ge({},n),{},{vectorBucketName:i.vectorBucketName,indexName:i.indexName}))}async queryVectors(n){var e=()=>super.queryVectors,i=this;return e().call(i,ge(ge({},n),{},{vectorBucketName:i.vectorBucketName,indexName:i.indexName}))}async deleteVectors(n){var e=()=>super.deleteVectors,i=this;return e().call(i,ge(ge({},n),{},{vectorBucketName:i.vectorBucketName,indexName:i.indexName}))}},Pk=class extends Ck{constructor(n,e={},i,a){super(n,e,i,a)}from(n){return new kk(this.url,this.headers,n,this.fetch)}get vectors(){return new Uk(this.url+"/vector",{headers:this.headers,fetch:this.fetch})}get analytics(){return new Ok(this.url+"/iceberg",this.headers,this.fetch)}};const Aw="2.110.2",ks=30*1e3,Zr=3,Ad=Zr*ks,Vk=2*ks,Hk="http://localhost:9999",$k="supabase.auth.token",qk={"X-Client-Info":`gotrue-js/${Aw}`},yf="X-Supabase-Api-Version",jw={"2024-01-01":{timestamp:Date.parse("2024-01-01T00:00:00.0Z"),name:"2024-01-01"}},Fk=/^([a-z0-9_-]{4})*($|[a-z0-9_-]{3}$|[a-z0-9_-]{2}$)$/i,Ik=600*1e3;class xo extends Error{constructor(e,i,a){super(e),this.__isAuthError=!0,this.name="AuthError",this.status=i,this.code=a}toJSON(){return{name:this.name,message:this.message,status:this.status,code:this.code}}}function ne(n){return typeof n=="object"&&n!==null&&"__isAuthError"in n}class Gk extends xo{constructor(e,i,a){super(e,i,a),this.name="AuthApiError",this.status=i,this.code=a}}function Kk(n){return ne(n)&&n.name==="AuthApiError"}class Hn extends xo{constructor(e,i){super(e),this.name="AuthUnknownError",this.originalError=i}}class ss extends xo{constructor(e,i,a,l){super(e,a,l),this.name=i,this.status=a}}class Nt extends ss{constructor(){super("Auth session missing!","AuthSessionMissingError",400,void 0)}}function ic(n){return ne(n)&&n.name==="AuthSessionMissingError"}class Na extends ss{constructor(){super("Auth session or user missing","AuthInvalidTokenResponseError",500,void 0)}}class ac extends ss{constructor(e){super(e,"AuthInvalidCredentialsError",400,void 0)}}class rc extends ss{constructor(e,i=null){super(e,"AuthImplicitGrantRedirectError",500,void 0),this.details=null,this.details=i}toJSON(){return Object.assign(Object.assign({},super.toJSON()),{details:this.details})}}function Yk(n){return ne(n)&&n.name==="AuthImplicitGrantRedirectError"}class Pb extends ss{constructor(e,i=null){super(e,"AuthPKCEGrantCodeExchangeError",500,void 0),this.details=null,this.details=i}toJSON(){return Object.assign(Object.assign({},super.toJSON()),{details:this.details})}}class Xk extends ss{constructor(){super("PKCE code verifier not found in storage. This can happen if the auth flow was initiated in a different browser or device, or if the storage was cleared. For SSR frameworks (Next.js, SvelteKit, etc.), use @supabase/ssr on both the server and client to store the code verifier in cookies.","AuthPKCECodeVerifierMissingError",400,"pkce_code_verifier_not_found")}}class bf extends ss{constructor(e,i){super(e,"AuthRetryableFetchError",i,void 0)}}function Vb(n){return ne(n)&&n.name==="AuthRetryableFetchError"}class Hb extends ss{constructor(e="Refresh result discarded: session state changed mid-flight (e.g., concurrent signOut)"){super(e,"AuthRefreshDiscardedError",409,void 0)}}function Jk(n){return ne(n)&&n.name==="AuthRefreshDiscardedError"}class $b extends ss{constructor(e,i,a){super(e,"AuthWeakPasswordError",i,"weak_password"),this.reasons=a}toJSON(){return Object.assign(Object.assign({},super.toJSON()),{reasons:this.reasons})}}class Oc extends ss{constructor(e){super(e,"AuthInvalidJwtError",400,"invalid_jwt")}}const Dc="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".split(""),qb=` -\r=`.split(""),Qk=(()=>{const n=new Array(128);for(let e=0;e=6;){const a=e.queue>>e.queuedBits-6&63;i(Dc[a]),e.queuedBits-=6}else if(e.queuedBits>0)for(e.queue=e.queue<<6-e.queuedBits,e.queuedBits=6;e.queuedBits>=6;){const a=e.queue>>e.queuedBits-6&63;i(Dc[a]),e.queuedBits-=6}}function Nw(n,e,i){const a=Qk[n];if(a>-1)for(e.queue=e.queue<<6|a,e.queuedBits+=6;e.queuedBits>=8;)i(e.queue>>e.queuedBits-8&255),e.queuedBits-=8;else{if(a===-2)return;throw new Error(`Invalid Base64-URL character "${String.fromCharCode(n)}"`)}}function Ib(n){const e=[],i=u=>{e.push(String.fromCodePoint(u))},a={utf8seq:0,codepoint:0},l={queue:0,queuedBits:0},c=u=>{eR(u,a,i)};for(let u=0;u>6),e(128|n&63);return}else if(n<=65535){e(224|n>>12),e(128|n>>6&63),e(128|n&63);return}else if(n<=1114111){e(240|n>>18),e(128|n>>12&63),e(128|n>>6&63),e(128|n&63);return}throw new Error(`Unrecognized Unicode codepoint: ${n.toString(16)}`)}function Wk(n,e){for(let i=0;i55295&&a<=56319){const l=(a-55296)*1024&65535;a=(n.charCodeAt(i+1)-56320&65535|l)+65536,i+=1}Zk(a,e)}}function eR(n,e,i){if(e.utf8seq===0){if(n<=127){i(n);return}for(let a=1;a<6;a+=1)if((n>>7-a&1)===0){e.utf8seq=a;break}if(e.utf8seq===2)e.codepoint=n&31;else if(e.utf8seq===3)e.codepoint=n&15;else if(e.utf8seq===4)e.codepoint=n&7;else throw new Error("Invalid UTF-8 sequence");e.utf8seq-=1}else if(e.utf8seq>0){if(n<=127)throw new Error("Invalid UTF-8 sequence");e.codepoint=e.codepoint<<6|n&63,e.utf8seq-=1,e.utf8seq===0&&i(e.codepoint)}}function qa(n){const e=[],i={queue:0,queuedBits:0},a=l=>{e.push(l)};for(let l=0;le.push(i)),new Uint8Array(e)}function zi(n){const e=[],i={queue:0,queuedBits:0},a=l=>{e.push(l)};return n.forEach(l=>Fb(l,i,a)),Fb(null,i,a),e.join("")}function nR(n){return Math.round(Date.now()/1e3)+n}function sR(){return Symbol("auth-callback")}const Vt=()=>typeof window<"u"&&typeof document<"u",Oi={tested:!1,writable:!1},kw=()=>{if(!Vt())return!1;try{if(typeof globalThis.localStorage!="object")return!1}catch{return!1}if(Oi.tested)return Oi.writable;const n=`lswt-${Math.random()}${Math.random()}`;try{globalThis.localStorage.setItem(n,n),globalThis.localStorage.removeItem(n),Oi.tested=!0,Oi.writable=!0}catch{Oi.tested=!0,Oi.writable=!1}return Oi.writable};function iR(n){const e={},i=new URL(n);if(i.hash&&i.hash[0]==="#")try{new URLSearchParams(i.hash.substring(1)).forEach((l,c)=>{e[c]=l})}catch{}return i.searchParams.forEach((a,l)=>{e[l]=a}),e}const Rw=n=>n?(...e)=>n(...e):(...e)=>fetch(...e),aR=n=>typeof n=="object"&&n!==null&&"status"in n&&"ok"in n&&"json"in n&&typeof n.json=="function",Ba=async(n,e,i)=>{await n.setItem(e,JSON.stringify(i))},Un=async(n,e)=>{const i=await n.getItem(e);if(!i)return null;try{return JSON.parse(i)}catch{return null}},ft=async(n,e)=>{await n.removeItem(e)};class Kc{constructor(){this.promise=new Kc.promiseConstructor((e,i)=>{this.resolve=e,this.reject=i})}}Kc.promiseConstructor=Promise;function oc(n){const e=n.split(".");if(e.length!==3)throw new Oc("Invalid JWT structure");for(let a=0;a{setTimeout(()=>e(null),n)})}function oR(n,e){return new Promise((a,l)=>{(async()=>{for(let c=0;c<1/0;c++)try{const u=await n(c);if(!e(c,null,u)){a(u);return}}catch(u){if(!e(c,u)){l(u);return}}})()})}function lR(n){return("0"+n.toString(16)).substr(-2)}function cR(){const e=new Uint32Array(56);if(typeof crypto>"u"){const i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",a=i.length;let l="";for(let c=0;c<56;c++)l+=i.charAt(Math.floor(Math.random()*a));return l}return crypto.getRandomValues(e),Array.from(e,lR).join("")}async function uR(n){const i=new TextEncoder().encode(n),a=await crypto.subtle.digest("SHA-256",i),l=new Uint8Array(a);return Array.from(l).map(c=>String.fromCharCode(c)).join("")}async function hR(n){if(!(typeof crypto<"u"&&typeof crypto.subtle<"u"&&typeof TextEncoder<"u"))return console.warn("WebCrypto API is not supported. Code challenge method will default to use plain instead of sha256."),n;const i=await uR(n);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function Di(n,e,i=!1){const a=cR();let l=a;i&&(l+="/recovery"),await Ba(n,`${e}-code-verifier`,l);const c=await hR(a);return[c,a===c?"plain":"s256"]}const dR=/^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[0-1])$/i;function fR(n){const e=n.headers.get(yf);if(!e||!e.match(dR))return null;try{return new Date(`${e}T00:00:00.0Z`)}catch{return null}}function mR(n){if(!n)throw new Error("Missing exp claim");const e=Math.floor(Date.now()/1e3);if(n<=e)throw new Error("JWT has expired")}function pR(n){switch(n){case"RS256":return{name:"RSASSA-PKCS1-v1_5",hash:{name:"SHA-256"}};case"ES256":return{name:"ECDSA",namedCurve:"P-256",hash:{name:"SHA-256"}};default:throw new Error("Invalid alg claim")}}const gR=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;function Es(n){if(!gR.test(n))throw new Error("@supabase/auth-js: Expected parameter to be UUID but is not")}function zn(n){if(!n.passkey)throw new Error("@supabase/auth-js: the passkey API is experimental and disabled by default. Enable it by passing `auth: { experimental: { passkey: true } }` to createClient (or to the GoTrueClient constructor).")}function jd(){const n={};return new Proxy(n,{get:(e,i)=>{if(i==="__isUserNotAvailableProxy")return!0;if(typeof i=="symbol"){const a=i.toString();if(a==="Symbol(Symbol.toPrimitive)"||a==="Symbol(Symbol.toStringTag)"||a==="Symbol(util.inspect.custom)")return}throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Accessing the "${i}" property of the session object is not supported. Please use getUser() instead.`)},set:(e,i)=>{throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Setting the "${i}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`)},deleteProperty:(e,i)=>{throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Deleting the "${i}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`)}})}function yR(n,e){return new Proxy(n,{get:(i,a,l)=>{if(a==="__isInsecureUserWarningProxy")return!0;if(typeof a=="symbol"){const c=a.toString();if(c==="Symbol(Symbol.toPrimitive)"||c==="Symbol(Symbol.toStringTag)"||c==="Symbol(util.inspect.custom)"||c==="Symbol(nodejs.util.inspect.custom)")return Reflect.get(i,a,l)}return!e.value&&typeof a=="string"&&(console.warn("Using the user object as returned from supabase.auth.getSession() or from some supabase.auth.onAuthStateChange() events could be insecure! This value comes directly from the storage medium (usually cookies on the server) and may not be authentic. Use supabase.auth.getUser() instead which authenticates the data by contacting the Supabase Auth server."),e.value=!0),Reflect.get(i,a,l)}})}function Gb(n){return JSON.parse(JSON.stringify(n))}const Bi=n=>{if(typeof n=="object"&&n!==null){const e=n;if(typeof e.msg=="string")return e.msg;if(typeof e.message=="string")return e.message;if(typeof e.error_description=="string")return e.error_description;if(typeof e.error=="string")return e.error}return JSON.stringify(n)},bR=[500,501,502,503,504,520,521,522,523,524,525,526,527,528,529,530];async function Kb(n){var e;if(!aR(n))throw new bf(Bi(n),0);if(bR.includes(n.status))throw new bf(Bi(n),n.status);let i;try{i=await n.json()}catch(c){throw new Hn(Bi(c),c)}let a;const l=fR(n);if(l&&l.getTime()>=jw["2024-01-01"].timestamp&&typeof i=="object"&&i&&typeof i.code=="string"?a=i.code:typeof i=="object"&&i&&typeof i.error_code=="string"&&(a=i.error_code),a){if(a==="weak_password")throw new $b(Bi(i),n.status,((e=i.weak_password)===null||e===void 0?void 0:e.reasons)||[]);if(a==="session_not_found")throw new Nt}else if(typeof i=="object"&&i&&typeof i.weak_password=="object"&&i.weak_password&&Array.isArray(i.weak_password.reasons)&&i.weak_password.reasons.length&&i.weak_password.reasons.reduce((c,u)=>c&&typeof u=="string",!0))throw new $b(Bi(i),n.status,i.weak_password.reasons);throw new Gk(Bi(i),n.status||500,a)}const vR=(n,e,i,a)=>{const l={method:n,headers:(e==null?void 0:e.headers)||{}};return n==="GET"?l:(l.headers=Object.assign({"Content-Type":"application/json;charset=UTF-8"},e==null?void 0:e.headers),l.body=JSON.stringify(a),Object.assign(Object.assign({},l),i))};async function ue(n,e,i,a){var l;const c=Object.assign({},a==null?void 0:a.headers);c[yf]||(c[yf]=jw["2024-01-01"].name),a!=null&&a.jwt&&(c.Authorization=`Bearer ${a.jwt}`);const u=(l=a==null?void 0:a.query)!==null&&l!==void 0?l:{};a!=null&&a.redirectTo&&(u.redirect_to=a.redirectTo);const d=Object.keys(u).length?"?"+new URLSearchParams(u).toString():"",m=await xR(n,e,i+d,{headers:c,noResolveJson:a==null?void 0:a.noResolveJson},{},a==null?void 0:a.body);return a!=null&&a.xform?a==null?void 0:a.xform(m):{data:Object.assign({},m),error:null}}async function xR(n,e,i,a,l,c){const u=vR(e,a,l,c);let d;try{d=await n(i,Object.assign({},u))}catch(m){throw console.error(m),new bf(Bi(m),0)}if(d.ok||await Kb(d),a!=null&&a.noResolveJson)return d;try{return await d.json()}catch(m){await Kb(m)}}function Tn(n){var e;let i=null;SR(n)&&(i=Object.assign({},n),n.expires_at||(i.expires_at=nR(n.expires_in)));const a=(e=n.user)!==null&&e!==void 0?e:typeof(n==null?void 0:n.id)=="string"?n:null;return{data:{session:i,user:a},error:null}}function Yb(n){const e=Tn(n);return!e.error&&n.weak_password&&typeof n.weak_password=="object"&&Array.isArray(n.weak_password.reasons)&&n.weak_password.reasons.length&&n.weak_password.message&&typeof n.weak_password.message=="string"&&n.weak_password.reasons.reduce((i,a)=>i&&typeof a=="string",!0)&&(e.data.weak_password=n.weak_password),e}function ai(n){var e;return{data:{user:(e=n.user)!==null&&e!==void 0?e:n},error:null}}function wR(n){return{data:n,error:null}}function _R(n){const{action_link:e,email_otp:i,hashed_token:a,redirect_to:l,verification_type:c}=n,u=Fc(n,["action_link","email_otp","hashed_token","redirect_to","verification_type"]),d={action_link:e,email_otp:i,hashed_token:a,redirect_to:l,verification_type:c},m=Object.assign({},u);return{data:{properties:d,user:m},error:null}}function Xb(n){return n}function SR(n){return!!n.access_token&&!!n.refresh_token&&!!n.expires_in}const Nd=["global","local","others"];class TR{constructor({url:e="",headers:i={},fetch:a,experimental:l}){this.url=e,this.headers=i,this.fetch=Rw(a),this.experimental=l??{},this.mfa={listFactors:this._listFactors.bind(this),deleteFactor:this._deleteFactor.bind(this)},this.oauth={listClients:this._listOAuthClients.bind(this),createClient:this._createOAuthClient.bind(this),getClient:this._getOAuthClient.bind(this),updateClient:this._updateOAuthClient.bind(this),deleteClient:this._deleteOAuthClient.bind(this),regenerateClientSecret:this._regenerateOAuthClientSecret.bind(this)},this.customProviders={listProviders:this._listCustomProviders.bind(this),createProvider:this._createCustomProvider.bind(this),getProvider:this._getCustomProvider.bind(this),updateProvider:this._updateCustomProvider.bind(this),deleteProvider:this._deleteCustomProvider.bind(this)},this.passkey={listPasskeys:this._adminListPasskeys.bind(this),deletePasskey:this._adminDeletePasskey.bind(this)}}async signOut(e,i=Nd[0]){if(Nd.indexOf(i)<0)throw new Error(`@supabase/auth-js: Parameter scope must be one of ${Nd.join(", ")}`);try{return await ue(this.fetch,"POST",`${this.url}/logout?scope=${i}`,{headers:this.headers,jwt:e,noResolveJson:!0}),{data:null,error:null}}catch(a){if(ne(a))return{data:null,error:a};throw a}}async inviteUserByEmail(e,i={}){try{return await ue(this.fetch,"POST",`${this.url}/invite`,{body:{email:e,data:i.data},headers:this.headers,redirectTo:i.redirectTo,xform:ai})}catch(a){if(ne(a))return{data:{user:null},error:a};throw a}}async generateLink(e){try{const{options:i}=e,a=Fc(e,["options"]),l=Object.assign(Object.assign({},a),i);return"newEmail"in a&&(l.new_email=a==null?void 0:a.newEmail,delete l.newEmail),await ue(this.fetch,"POST",`${this.url}/admin/generate_link`,{body:l,headers:this.headers,xform:_R,redirectTo:i==null?void 0:i.redirectTo})}catch(i){if(ne(i))return{data:{properties:null,user:null},error:i};throw i}}async createUser(e){try{return await ue(this.fetch,"POST",`${this.url}/admin/users`,{body:e,headers:this.headers,xform:ai})}catch(i){if(ne(i))return{data:{user:null},error:i};throw i}}async listUsers(e){var i,a,l,c,u,d,m;try{const p={nextPage:null,lastPage:0,total:0},y=await ue(this.fetch,"GET",`${this.url}/admin/users`,{headers:this.headers,noResolveJson:!0,query:{page:(a=(i=e==null?void 0:e.page)===null||i===void 0?void 0:i.toString())!==null&&a!==void 0?a:"",per_page:(c=(l=e==null?void 0:e.perPage)===null||l===void 0?void 0:l.toString())!==null&&c!==void 0?c:""},xform:Xb});if(y.error)throw y.error;const v=await y.json(),x=(u=y.headers.get("x-total-count"))!==null&&u!==void 0?u:0,_=(m=(d=y.headers.get("link"))===null||d===void 0?void 0:d.split(","))!==null&&m!==void 0?m:[];return _.length>0&&(_.forEach(S=>{const T=parseInt(S.split(";")[0].split("=")[1].substring(0,1)),k=JSON.parse(S.split(";")[1].split("=")[1]);p[`${k}Page`]=T}),p.total=parseInt(x)),{data:Object.assign(Object.assign({},v),p),error:null}}catch(p){if(ne(p))return{data:{users:[]},error:p};throw p}}async getUserById(e){Es(e);try{return await ue(this.fetch,"GET",`${this.url}/admin/users/${e}`,{headers:this.headers,xform:ai})}catch(i){if(ne(i))return{data:{user:null},error:i};throw i}}async updateUserById(e,i){Es(e);try{return await ue(this.fetch,"PUT",`${this.url}/admin/users/${e}`,{body:i,headers:this.headers,xform:ai})}catch(a){if(ne(a))return{data:{user:null},error:a};throw a}}async deleteUser(e,i=!1){Es(e);try{return await ue(this.fetch,"DELETE",`${this.url}/admin/users/${e}`,{headers:this.headers,body:{should_soft_delete:i},xform:ai})}catch(a){if(ne(a))return{data:{user:null},error:a};throw a}}async _listFactors(e){Es(e.userId);try{const{data:i,error:a}=await ue(this.fetch,"GET",`${this.url}/admin/users/${e.userId}/factors`,{headers:this.headers,xform:l=>({data:{factors:l},error:null})});return{data:i,error:a}}catch(i){if(ne(i))return{data:null,error:i};throw i}}async _deleteFactor(e){Es(e.userId),Es(e.id);try{return{data:await ue(this.fetch,"DELETE",`${this.url}/admin/users/${e.userId}/factors/${e.id}`,{headers:this.headers}),error:null}}catch(i){if(ne(i))return{data:null,error:i};throw i}}async _listOAuthClients(e){var i,a,l,c,u,d,m;try{const p={nextPage:null,lastPage:0,total:0},y=await ue(this.fetch,"GET",`${this.url}/admin/oauth/clients`,{headers:this.headers,noResolveJson:!0,query:{page:(a=(i=e==null?void 0:e.page)===null||i===void 0?void 0:i.toString())!==null&&a!==void 0?a:"",per_page:(c=(l=e==null?void 0:e.perPage)===null||l===void 0?void 0:l.toString())!==null&&c!==void 0?c:""},xform:Xb});if(y.error)throw y.error;const v=await y.json(),x=(u=y.headers.get("x-total-count"))!==null&&u!==void 0?u:0,_=(m=(d=y.headers.get("link"))===null||d===void 0?void 0:d.split(","))!==null&&m!==void 0?m:[];return _.length>0&&(_.forEach(S=>{const T=parseInt(S.split(";")[0].split("=")[1].substring(0,1)),k=JSON.parse(S.split(";")[1].split("=")[1]);p[`${k}Page`]=T}),p.total=parseInt(x)),{data:Object.assign(Object.assign({},v),p),error:null}}catch(p){if(ne(p))return{data:{clients:[]},error:p};throw p}}async _createOAuthClient(e){try{return await ue(this.fetch,"POST",`${this.url}/admin/oauth/clients`,{body:e,headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(ne(i))return{data:null,error:i};throw i}}async _getOAuthClient(e){try{return await ue(this.fetch,"GET",`${this.url}/admin/oauth/clients/${e}`,{headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(ne(i))return{data:null,error:i};throw i}}async _updateOAuthClient(e,i){try{return await ue(this.fetch,"PUT",`${this.url}/admin/oauth/clients/${e}`,{body:i,headers:this.headers,xform:a=>({data:a,error:null})})}catch(a){if(ne(a))return{data:null,error:a};throw a}}async _deleteOAuthClient(e){try{return await ue(this.fetch,"DELETE",`${this.url}/admin/oauth/clients/${e}`,{headers:this.headers,noResolveJson:!0}),{data:null,error:null}}catch(i){if(ne(i))return{data:null,error:i};throw i}}async _regenerateOAuthClientSecret(e){try{return await ue(this.fetch,"POST",`${this.url}/admin/oauth/clients/${e}/regenerate_secret`,{headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(ne(i))return{data:null,error:i};throw i}}async _listCustomProviders(e){try{const i={};return e!=null&&e.type&&(i.type=e.type),await ue(this.fetch,"GET",`${this.url}/admin/custom-providers`,{headers:this.headers,query:i,xform:a=>{var l;return{data:{providers:(l=a==null?void 0:a.providers)!==null&&l!==void 0?l:[]},error:null}}})}catch(i){if(ne(i))return{data:{providers:[]},error:i};throw i}}async _createCustomProvider(e){try{return await ue(this.fetch,"POST",`${this.url}/admin/custom-providers`,{body:e,headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(ne(i))return{data:null,error:i};throw i}}async _getCustomProvider(e){try{return await ue(this.fetch,"GET",`${this.url}/admin/custom-providers/${e}`,{headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(ne(i))return{data:null,error:i};throw i}}async _updateCustomProvider(e,i){try{return await ue(this.fetch,"PUT",`${this.url}/admin/custom-providers/${e}`,{body:i,headers:this.headers,xform:a=>({data:a,error:null})})}catch(a){if(ne(a))return{data:null,error:a};throw a}}async _deleteCustomProvider(e){try{return await ue(this.fetch,"DELETE",`${this.url}/admin/custom-providers/${e}`,{headers:this.headers,noResolveJson:!0}),{data:null,error:null}}catch(i){if(ne(i))return{data:null,error:i};throw i}}async _adminListPasskeys(e){zn(this.experimental),Es(e.userId);try{return await ue(this.fetch,"GET",`${this.url}/admin/users/${e.userId}/passkeys`,{headers:this.headers,xform:i=>({data:i,error:null})})}catch(i){if(ne(i))return{data:null,error:i};throw i}}async _adminDeletePasskey(e){zn(this.experimental),Es(e.userId),Es(e.passkeyId);try{return await ue(this.fetch,"DELETE",`${this.url}/admin/users/${e.userId}/passkeys/${e.passkeyId}`,{headers:this.headers,noResolveJson:!0}),{data:null,error:null}}catch(i){if(ne(i))return{data:null,error:i};throw i}}}function Jb(n={}){return{getItem:e=>n[e]||null,setItem:(e,i)=>{n[e]=i},removeItem:e=>{delete n[e]}}}globalThis&&kw()&&globalThis.localStorage&&globalThis.localStorage.getItem("supabase.gotrue-js.locks.debug");class ER extends Error{constructor(e){super(e),this.isAcquireTimeout=!0}}function AR(){if(typeof globalThis!="object")try{Object.defineProperty(Object.prototype,"__magic__",{get:function(){return this},configurable:!0}),__magic__.globalThis=__magic__,delete Object.prototype.__magic__}catch{typeof self<"u"&&(self.globalThis=self)}}function Cw(n){if(!/^0x[a-fA-F0-9]{40}$/.test(n))throw new Error(`@supabase/auth-js: Address "${n}" is invalid.`);return n.toLowerCase()}function jR(n){return parseInt(n,16)}function NR(n){const e=new TextEncoder().encode(n);return"0x"+Array.from(e,a=>a.toString(16).padStart(2,"0")).join("")}function kR(n){var e;const{chainId:i,domain:a,expirationTime:l,issuedAt:c=new Date,nonce:u,notBefore:d,requestId:m,resources:p,scheme:y,uri:v,version:x}=n;{if(!Number.isInteger(i))throw new Error(`@supabase/auth-js: Invalid SIWE message field "chainId". Chain ID must be a EIP-155 chain ID. Provided value: ${i}`);if(!a)throw new Error('@supabase/auth-js: Invalid SIWE message field "domain". Domain must be provided.');if(u&&u.length<8)throw new Error(`@supabase/auth-js: Invalid SIWE message field "nonce". Nonce must be at least 8 characters. Provided value: ${u}`);if(!v)throw new Error('@supabase/auth-js: Invalid SIWE message field "uri". URI must be provided.');if(x!=="1")throw new Error(`@supabase/auth-js: Invalid SIWE message field "version". Version must be '1'. Provided value: ${x}`);if(!((e=n.statement)===null||e===void 0)&&e.includes(` -`))throw new Error(`@supabase/auth-js: Invalid SIWE message field "statement". Statement must not include '\\n'. Provided value: ${n.statement}`)}const _=Cw(n.address),S=y?`${y}://${a}`:a,T=n.statement?`${n.statement} -`:"",k=`${S} wants you to sign in with your Ethereum account: -${_} - -${T}`;let R=`URI: ${v} -Version: ${x} -Chain ID: ${i}${u?` -Nonce: ${u}`:""} -Issued At: ${c.toISOString()}`;if(l&&(R+=` -Expiration Time: ${l.toISOString()}`),d&&(R+=` -Not Before: ${d.toISOString()}`),m&&(R+=` -Request ID: ${m}`),p){let M=` -Resources:`;for(const N of p){if(!N||typeof N!="string")throw new Error(`@supabase/auth-js: Invalid SIWE message field "resources". Every resource must be a valid string. Provided value: ${N}`);M+=` -- ${N}`}R+=M}return`${k} -${R}`}class bt extends Error{constructor({message:e,code:i,cause:a,name:l}){var c;super(e,{cause:a}),this.__isWebAuthnError=!0,this.name=(c=l??(a instanceof Error?a.name:void 0))!==null&&c!==void 0?c:"Unknown Error",this.code=i}toJSON(){return{name:this.name,message:this.message,code:this.code}}}class Mc extends bt{constructor(e,i){super({code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:i,message:e}),this.name="WebAuthnUnknownError",this.originalError=i}}function RR({error:n,options:e}){var i,a,l;const{publicKey:c}=e;if(!c)throw Error("options was missing required publicKey property");if(n.name==="AbortError"){if(e.signal instanceof AbortSignal)return new bt({message:"Registration ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:n})}else if(n.name==="ConstraintError"){if(((i=c.authenticatorSelection)===null||i===void 0?void 0:i.requireResidentKey)===!0)return new bt({message:"Discoverable credentials were required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",cause:n});if(e.mediation==="conditional"&&((a=c.authenticatorSelection)===null||a===void 0?void 0:a.userVerification)==="required")return new bt({message:"User verification was required during automatic registration but it could not be performed",code:"ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE",cause:n});if(((l=c.authenticatorSelection)===null||l===void 0?void 0:l.userVerification)==="required")return new bt({message:"User verification was required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",cause:n})}else{if(n.name==="InvalidStateError")return new bt({message:"The authenticator was previously registered",code:"ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",cause:n});if(n.name==="NotAllowedError")return new bt({message:n.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:n});if(n.name==="NotSupportedError")return c.pubKeyCredParams.filter(d=>d.type==="public-key").length===0?new bt({message:'No entry in pubKeyCredParams was of type "public-key"',code:"ERROR_MALFORMED_PUBKEYCREDPARAMS",cause:n}):new bt({message:"No available authenticator supported any of the specified pubKeyCredParams algorithms",code:"ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",cause:n});if(n.name==="SecurityError"){const u=window.location.hostname;if(Ow(u)){if(c.rp.id!==u)return new bt({message:`The RP ID "${c.rp.id}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:n})}else return new bt({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:n})}else if(n.name==="TypeError"){if(c.user.id.byteLength<1||c.user.id.byteLength>64)return new bt({message:"User ID was not between 1 and 64 characters",code:"ERROR_INVALID_USER_ID_LENGTH",cause:n})}else if(n.name==="UnknownError")return new bt({message:"The authenticator was unable to process the specified options, or could not create a new credential",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:n})}return new bt({message:"a Non-Webauthn related error has occurred",code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:n})}function CR({error:n,options:e}){const{publicKey:i}=e;if(!i)throw Error("options was missing required publicKey property");if(n.name==="AbortError"){if(e.signal instanceof AbortSignal)return new bt({message:"Authentication ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:n})}else{if(n.name==="NotAllowedError")return new bt({message:n.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:n});if(n.name==="SecurityError"){const a=window.location.hostname;if(Ow(a)){if(i.rpId!==a)return new bt({message:`The RP ID "${i.rpId}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:n})}else return new bt({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:n})}else if(n.name==="UnknownError")return new bt({message:"The authenticator was unable to process the specified options, or could not create a new assertion signature",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:n})}return new bt({message:"a Non-Webauthn related error has occurred",code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:n})}class OR{createNewAbortSignal(){if(this.controller){const i=new Error("Cancelling existing WebAuthn API call for new one");i.name="AbortError",this.controller.abort(i)}const e=new AbortController;return this.controller=e,e.signal}cancelCeremony(){if(this.controller){const e=new Error("Manually cancelling existing WebAuthn API call");e.name="AbortError",this.controller.abort(e),this.controller=void 0}}}const vf=new OR;function Qb(n){if(!n)throw new Error("Credential creation options are required");if(typeof PublicKeyCredential<"u"&&"parseCreationOptionsFromJSON"in PublicKeyCredential&&typeof PublicKeyCredential.parseCreationOptionsFromJSON=="function")return PublicKeyCredential.parseCreationOptionsFromJSON(n);const{challenge:e,user:i,excludeCredentials:a}=n,l=Fc(n,["challenge","user","excludeCredentials"]),c=qa(e).buffer,u=Object.assign(Object.assign({},i),{id:qa(i.id).buffer}),d=Object.assign(Object.assign({},l),{challenge:c,user:u});if(a&&a.length>0){d.excludeCredentials=new Array(a.length);for(let m=0;m0){c.allowCredentials=new Array(i.length);for(let u=0;ul!==null&&typeof l=="object"&&!Array.isArray(l),i=l=>l instanceof ArrayBuffer||ArrayBuffer.isView(l),a={};for(const l of n)if(l)for(const c in l){const u=l[c];if(u!==void 0)if(Array.isArray(u))a[c]=u;else if(i(u))a[c]=u;else if(e(u)){const d=a[c];e(d)?a[c]=Uc(d,u):a[c]=Uc(u)}else a[c]=u}return a}function BR(n,e){return Uc(DR,n,e||{})}function UR(n,e){return Uc(MR,n,e||{})}class LR{constructor(e){this.client=e,this.enroll=this._enroll.bind(this),this.challenge=this._challenge.bind(this),this.verify=this._verify.bind(this),this.authenticate=this._authenticate.bind(this),this.register=this._register.bind(this)}async _enroll(e){return this.client.mfa.enroll(Object.assign(Object.assign({},e),{factorType:"webauthn"}))}async _challenge({factorId:e,webauthn:i,friendlyName:a,signal:l},c){var u;try{const{data:d,error:m}=await this.client.mfa.challenge({factorId:e,webauthn:i});if(!d)return{data:null,error:m};const p=l??vf.createNewAbortSignal();if(d.webauthn.type==="create"){const{user:y}=d.webauthn.credential_options.publicKey;if(!y.name){const v=a;if(v)y.name=`${y.id}:${v}`;else{const _=(await this.client.getUser()).data.user,S=((u=_==null?void 0:_.user_metadata)===null||u===void 0?void 0:u.name)||(_==null?void 0:_.email)||(_==null?void 0:_.id)||"User";y.name=`${y.id}:${S}`}}y.displayName||(y.displayName=y.name)}switch(d.webauthn.type){case"create":{const y=BR(d.webauthn.credential_options.publicKey,c==null?void 0:c.create),{data:v,error:x}=await Dw({publicKey:y,signal:p});return v?{data:{factorId:e,challengeId:d.id,webauthn:{type:d.webauthn.type,credential_response:v}},error:null}:{data:null,error:x}}case"request":{const y=UR(d.webauthn.credential_options.publicKey,c==null?void 0:c.request),{data:v,error:x}=await Mw(Object.assign(Object.assign({},d.webauthn.credential_options),{publicKey:y,signal:p}));return v?{data:{factorId:e,challengeId:d.id,webauthn:{type:d.webauthn.type,credential_response:v}},error:null}:{data:null,error:x}}}}catch(d){return ne(d)?{data:null,error:d}:{data:null,error:new Hn("Unexpected error in challenge",d)}}}async _verify({challengeId:e,factorId:i,webauthn:a}){return this.client.mfa.verify({factorId:i,challengeId:e,webauthn:a})}async _authenticate({factorId:e,webauthn:{rpId:i=typeof window<"u"?window.location.hostname:void 0,rpOrigins:a=typeof window<"u"?[window.location.origin]:void 0,signal:l}={}},c){if(!i)return{data:null,error:new xo("rpId is required for WebAuthn authentication")};try{if(!Bc())return{data:null,error:new Hn("Browser does not support WebAuthn",null)};const{data:u,error:d}=await this.challenge({factorId:e,webauthn:{rpId:i,rpOrigins:a},signal:l},{request:c});if(!u)return{data:null,error:d};const{webauthn:m}=u;return this._verify({factorId:e,challengeId:u.challengeId,webauthn:{type:m.type,rpId:i,rpOrigins:a,credential_response:m.credential_response}})}catch(u){return ne(u)?{data:null,error:u}:{data:null,error:new Hn("Unexpected error in authenticate",u)}}}async _register({friendlyName:e,webauthn:{rpId:i=typeof window<"u"?window.location.hostname:void 0,rpOrigins:a=typeof window<"u"?[window.location.origin]:void 0,signal:l}={}},c){if(!i)return{data:null,error:new xo("rpId is required for WebAuthn registration")};try{if(!Bc())return{data:null,error:new Hn("Browser does not support WebAuthn",null)};const{data:u,error:d}=await this._enroll({friendlyName:e});if(!u)return await this.client.mfa.listFactors().then(y=>{var v;return(v=y.data)===null||v===void 0?void 0:v.all.find(x=>x.factor_type==="webauthn"&&x.friendly_name===e&&x.status!=="unverified")}).then(y=>y?this.client.mfa.unenroll({factorId:y==null?void 0:y.id}):void 0),{data:null,error:d};const{data:m,error:p}=await this._challenge({factorId:u.id,friendlyName:u.friendly_name,webauthn:{rpId:i,rpOrigins:a},signal:l},{create:c});return m?this._verify({factorId:u.id,challengeId:m.challengeId,webauthn:{rpId:i,rpOrigins:a,type:m.webauthn.type,credential_response:m.webauthn.credential_response}}):{data:null,error:p}}catch(u){return ne(u)?{data:null,error:u}:{data:null,error:new Hn("Unexpected error in register",u)}}}}AR();const zR={url:Hk,storageKey:$k,autoRefreshToken:!0,persistSession:!0,detectSessionInUrl:!0,headers:qk,flowType:"implicit",debug:!1,hasCustomAuthorizationHeader:!1,throwOnError:!1,lockAcquireTimeout:5e3,skipAutoInitialize:!1,experimental:{}},ka={};class wo{get jwks(){var e,i;return(i=(e=ka[this.storageKey])===null||e===void 0?void 0:e.jwks)!==null&&i!==void 0?i:{keys:[]}}set jwks(e){ka[this.storageKey]=Object.assign(Object.assign({},ka[this.storageKey]),{jwks:e})}get jwks_cached_at(){var e,i;return(i=(e=ka[this.storageKey])===null||e===void 0?void 0:e.cachedAt)!==null&&i!==void 0?i:Number.MIN_SAFE_INTEGER}set jwks_cached_at(e){ka[this.storageKey]=Object.assign(Object.assign({},ka[this.storageKey]),{cachedAt:e})}constructor(e){var i,a,l;this.userStorage=null,this.memoryStorage=null,this.stateChangeEmitters=new Map,this.autoRefreshTicker=null,this.autoRefreshTickTimeout=null,this.visibilityChangedCallback=null,this.refreshingDeferred=null,this.lastRefreshFailure=null,this._sessionRemovalEpoch=0,this.initializePromise=null,this._pendingInitNotifications=null,this.detectSessionInUrl=!0,this.hasCustomAuthorizationHeader=!1,this.suppressGetSessionWarning=!1,this.lock=null,this.lockAcquired=!1,this.pendingInLock=[],this.broadcastChannel=null,this.logger=console.log;const c=Object.assign(Object.assign({},zR),e);if(this.storageKey=c.storageKey,this.instanceID=(i=wo.nextInstanceID[this.storageKey])!==null&&i!==void 0?i:0,wo.nextInstanceID[this.storageKey]=this.instanceID+1,this.logDebugMessages=!!c.debug,typeof c.debug=="function"&&(this.logger=c.debug),this.instanceID>0&&Vt()){const u=`${this._logPrefix()} Multiple GoTrueClient instances detected in the same browser context. It is not an error, but this should be avoided as it may produce undefined behavior when used concurrently under the same storage key.`;console.warn(u),this.logDebugMessages&&console.trace(u)}if(this.persistSession=c.persistSession,this.autoRefreshToken=c.autoRefreshToken,this.experimental=(a=c.experimental)!==null&&a!==void 0?a:{},this.admin=new TR({url:c.url,headers:c.headers,fetch:c.fetch,experimental:this.experimental}),this.url=c.url,this.headers=c.headers,this.fetch=Rw(c.fetch),this.detectSessionInUrl=c.detectSessionInUrl,this.flowType=c.flowType,this.hasCustomAuthorizationHeader=c.hasCustomAuthorizationHeader,this.throwOnError=c.throwOnError,this.lockAcquireTimeout=c.lockAcquireTimeout,c.lock!=null&&(this.lock=c.lock),this.jwks||(this.jwks={keys:[]},this.jwks_cached_at=Number.MIN_SAFE_INTEGER),this.mfa={verify:this._verify.bind(this),enroll:this._enroll.bind(this),unenroll:this._unenroll.bind(this),challenge:this._challenge.bind(this),listFactors:this._listFactors.bind(this),challengeAndVerify:this._challengeAndVerify.bind(this),getAuthenticatorAssuranceLevel:this._getAuthenticatorAssuranceLevel.bind(this),webauthn:new LR(this)},this.oauth={getAuthorizationDetails:this._getAuthorizationDetails.bind(this),approveAuthorization:this._approveAuthorization.bind(this),denyAuthorization:this._denyAuthorization.bind(this),listGrants:this._listOAuthGrants.bind(this),revokeGrant:this._revokeOAuthGrant.bind(this)},this.passkey={startRegistration:this._startPasskeyRegistration.bind(this),verifyRegistration:this._verifyPasskeyRegistration.bind(this),startAuthentication:this._startPasskeyAuthentication.bind(this),verifyAuthentication:this._verifyPasskeyAuthentication.bind(this),list:this._listPasskeys.bind(this),update:this._updatePasskey.bind(this),delete:this._deletePasskey.bind(this)},this.persistSession?(c.storage?this.storage=c.storage:kw()?this.storage=globalThis.localStorage:(this.memoryStorage={},this.storage=Jb(this.memoryStorage)),c.userStorage&&(this.userStorage=c.userStorage)):(this.memoryStorage={},this.storage=Jb(this.memoryStorage)),Vt()&&globalThis.BroadcastChannel&&this.persistSession&&this.storageKey){try{this.broadcastChannel=new globalThis.BroadcastChannel(this.storageKey)}catch(u){console.error("Failed to create a new BroadcastChannel, multi-tab state changes will not be available",u)}(l=this.broadcastChannel)===null||l===void 0||l.addEventListener("message",async u=>{this._debug("received broadcast notification from other tab or client",u),(u.data.event==="TOKEN_REFRESHED"||u.data.event==="SIGNED_IN")&&(this.lastRefreshFailure=null);try{await this._notifyAllSubscribers(u.data.event,u.data.session,!1)}catch(d){this._debug("#broadcastChannel","error",d)}})}c.skipAutoInitialize||this.initialize().catch(u=>{this._debug("#initialize()","error",u)})}isThrowOnErrorEnabled(){return this.throwOnError}_returnResult(e){if(this.throwOnError&&e&&e.error)throw e.error;return e}_logPrefix(){return`GoTrueClient@${this.storageKey}:${this.instanceID} (${Aw}) ${new Date().toISOString()}`}_debug(...e){return this.logDebugMessages&&this.logger(this._logPrefix(),...e),this}async initialize(){var e;if(this.initializePromise)return await this.initializePromise;this._pendingInitNotifications=[],this.initializePromise=(async()=>this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._initialize()):await this._initialize())();const i=await this.initializePromise,a=(e=this._pendingInitNotifications)!==null&&e!==void 0?e:[];this._pendingInitNotifications=null;for(const l of a)await this._notifyAllSubscribers(l.event,l.session,l.broadcast);return i}async _initialize(){var e;try{let i={},a="none";if(Vt()&&(i=iR(window.location.href),this._isImplicitGrantCallback(i)?a="implicit":await this._isPKCECallback(i)&&(a="pkce")),Vt()&&this.detectSessionInUrl&&a!=="none"){const{data:l,error:c}=await this._getSessionFromURL(i,a);if(c){if(this._debug("#_initialize()","error detecting session from URL",c),Yk(c)){const m=(e=c.details)===null||e===void 0?void 0:e.code;if(m==="identity_already_exists"||m==="identity_not_found"||m==="single_identity_not_deletable")return{error:c}}return{error:c}}const{session:u,redirectType:d}=l;return this._debug("#_initialize()","detected session in URL",u,"redirect type",d),await this._saveSession(u),setTimeout(async()=>{d==="recovery"?await this._notifyAllSubscribers("PASSWORD_RECOVERY",u):await this._notifyAllSubscribers("SIGNED_IN",u)},0),{error:null}}return await this._recoverAndRefresh(),{error:null}}catch(i){return ne(i)?this._returnResult({error:i}):this._returnResult({error:new Hn("Unexpected error during initialization",i)})}finally{await this._handleVisibilityChange(),this._debug("#_initialize()","end")}}async signInAnonymously(e){var i,a,l;try{const c=await ue(this.fetch,"POST",`${this.url}/signup`,{headers:this.headers,body:{data:(a=(i=e==null?void 0:e.options)===null||i===void 0?void 0:i.data)!==null&&a!==void 0?a:{},gotrue_meta_security:{captcha_token:(l=e==null?void 0:e.options)===null||l===void 0?void 0:l.captchaToken}},xform:Tn}),{data:u,error:d}=c;if(d||!u)return this._returnResult({data:{user:null,session:null},error:d});const m=u.session,p=u.user;return u.session&&(await this._saveSession(u.session),await this._notifyAllSubscribers("SIGNED_IN",m)),this._returnResult({data:{user:p,session:m},error:null})}catch(c){if(ne(c))return this._returnResult({data:{user:null,session:null},error:c});throw c}}async signUp(e){var i,a,l;try{let c;if("email"in e){const{email:y,password:v,options:x}=e;let _=null,S=null;this.flowType==="pkce"&&([_,S]=await Di(this.storage,this.storageKey)),c=await ue(this.fetch,"POST",`${this.url}/signup`,{headers:this.headers,redirectTo:x==null?void 0:x.emailRedirectTo,body:{email:y,password:v,data:(i=x==null?void 0:x.data)!==null&&i!==void 0?i:{},gotrue_meta_security:{captcha_token:x==null?void 0:x.captchaToken},code_challenge:_,code_challenge_method:S},xform:Tn})}else if("phone"in e){const{phone:y,password:v,options:x}=e;c=await ue(this.fetch,"POST",`${this.url}/signup`,{headers:this.headers,body:{phone:y,password:v,data:(a=x==null?void 0:x.data)!==null&&a!==void 0?a:{},channel:(l=x==null?void 0:x.channel)!==null&&l!==void 0?l:"sms",gotrue_meta_security:{captcha_token:x==null?void 0:x.captchaToken}},xform:Tn})}else throw new ac("You must provide either an email or phone number and a password");const{data:u,error:d}=c;if(d||!u)return await ft(this.storage,`${this.storageKey}-code-verifier`),this._returnResult({data:{user:null,session:null},error:d});const m=u.session,p=u.user;return u.session&&(await this._saveSession(u.session),await this._notifyAllSubscribers("SIGNED_IN",m)),this._returnResult({data:{user:p,session:m},error:null})}catch(c){if(await ft(this.storage,`${this.storageKey}-code-verifier`),ne(c))return this._returnResult({data:{user:null,session:null},error:c});throw c}}async signInWithPassword(e){try{let i;if("email"in e){const{email:c,password:u,options:d}=e;i=await ue(this.fetch,"POST",`${this.url}/token?grant_type=password`,{headers:this.headers,body:{email:c,password:u,gotrue_meta_security:{captcha_token:d==null?void 0:d.captchaToken}},xform:Yb})}else if("phone"in e){const{phone:c,password:u,options:d}=e;i=await ue(this.fetch,"POST",`${this.url}/token?grant_type=password`,{headers:this.headers,body:{phone:c,password:u,gotrue_meta_security:{captcha_token:d==null?void 0:d.captchaToken}},xform:Yb})}else throw new ac("You must provide either an email or phone number and a password");const{data:a,error:l}=i;if(l)return this._returnResult({data:{user:null,session:null},error:l});if(!a||!a.session||!a.user){const c=new Na;return this._returnResult({data:{user:null,session:null},error:c})}return a.session&&(await this._saveSession(a.session),await this._notifyAllSubscribers("SIGNED_IN",a.session)),this._returnResult({data:Object.assign({user:a.user,session:a.session},a.weak_password?{weakPassword:a.weak_password}:null),error:l})}catch(i){if(ne(i))return this._returnResult({data:{user:null,session:null},error:i});throw i}}async signInWithOAuth(e){var i,a,l,c;return await this._handleProviderSignIn(e.provider,{redirectTo:(i=e.options)===null||i===void 0?void 0:i.redirectTo,scopes:(a=e.options)===null||a===void 0?void 0:a.scopes,queryParams:(l=e.options)===null||l===void 0?void 0:l.queryParams,skipBrowserRedirect:(c=e.options)===null||c===void 0?void 0:c.skipBrowserRedirect})}async exchangeCodeForSession(e){return await this.initializePromise,this.lock!=null?this._acquireLock(this.lockAcquireTimeout,async()=>this._exchangeCodeForSession(e)):this._exchangeCodeForSession(e)}async signInWithWeb3(e){const{chain:i}=e;switch(i){case"ethereum":return await this.signInWithEthereum(e);case"solana":return await this.signInWithSolana(e);default:throw new Error(`@supabase/auth-js: Unsupported chain "${i}"`)}}async signInWithEthereum(e){var i,a,l,c,u,d,m,p,y,v,x;let _,S;if("message"in e)_=e.message,S=e.signature;else{const{chain:T,wallet:k,statement:R,options:M}=e;let N;if(Vt())if(typeof k=="object")N=k;else{const se=window;if("ethereum"in se&&typeof se.ethereum=="object"&&"request"in se.ethereum&&typeof se.ethereum.request=="function")N=se.ethereum;else throw new Error("@supabase/auth-js: No compatible Ethereum wallet interface on the window object (window.ethereum) detected. Make sure the user already has a wallet installed and connected for this app. Prefer passing the wallet interface object directly to signInWithWeb3({ chain: 'ethereum', wallet: resolvedUserWallet }) instead.")}else{if(typeof k!="object"||!(M!=null&&M.url))throw new Error("@supabase/auth-js: Both wallet and url must be specified in non-browser environments.");N=k}const P=new URL((i=M==null?void 0:M.url)!==null&&i!==void 0?i:window.location.href),G=await N.request({method:"eth_requestAccounts"}).then(se=>se).catch(()=>{throw new Error("@supabase/auth-js: Wallet method eth_requestAccounts is missing or invalid")});if(!G||G.length===0)throw new Error("@supabase/auth-js: No accounts available. Please ensure the wallet is connected.");const X=Cw(G[0]);let q=(a=M==null?void 0:M.signInWithEthereum)===null||a===void 0?void 0:a.chainId;if(!q){const se=await N.request({method:"eth_chainId"});q=jR(se)}const Y={domain:P.host,address:X,statement:R,uri:P.href,version:"1",chainId:q,nonce:(l=M==null?void 0:M.signInWithEthereum)===null||l===void 0?void 0:l.nonce,issuedAt:(u=(c=M==null?void 0:M.signInWithEthereum)===null||c===void 0?void 0:c.issuedAt)!==null&&u!==void 0?u:new Date,expirationTime:(d=M==null?void 0:M.signInWithEthereum)===null||d===void 0?void 0:d.expirationTime,notBefore:(m=M==null?void 0:M.signInWithEthereum)===null||m===void 0?void 0:m.notBefore,requestId:(p=M==null?void 0:M.signInWithEthereum)===null||p===void 0?void 0:p.requestId,resources:(y=M==null?void 0:M.signInWithEthereum)===null||y===void 0?void 0:y.resources};_=kR(Y),S=await N.request({method:"personal_sign",params:[NR(_),X]})}try{const{data:T,error:k}=await ue(this.fetch,"POST",`${this.url}/token?grant_type=web3`,{headers:this.headers,body:Object.assign({chain:"ethereum",message:_,signature:S},!((v=e.options)===null||v===void 0)&&v.captchaToken?{gotrue_meta_security:{captcha_token:(x=e.options)===null||x===void 0?void 0:x.captchaToken}}:null),xform:Tn});if(k)throw k;if(!T||!T.session||!T.user){const R=new Na;return this._returnResult({data:{user:null,session:null},error:R})}return T.session&&(await this._saveSession(T.session),await this._notifyAllSubscribers("SIGNED_IN",T.session)),this._returnResult({data:Object.assign({},T),error:k})}catch(T){if(ne(T))return this._returnResult({data:{user:null,session:null},error:T});throw T}}async signInWithSolana(e){var i,a,l,c,u,d,m,p,y,v,x,_;let S,T;if("message"in e)S=e.message,T=e.signature;else{const{chain:k,wallet:R,statement:M,options:N}=e;let P;if(Vt())if(typeof R=="object")P=R;else{const X=window;if("solana"in X&&typeof X.solana=="object"&&("signIn"in X.solana&&typeof X.solana.signIn=="function"||"signMessage"in X.solana&&typeof X.solana.signMessage=="function"))P=X.solana;else throw new Error("@supabase/auth-js: No compatible Solana wallet interface on the window object (window.solana) detected. Make sure the user already has a wallet installed and connected for this app. Prefer passing the wallet interface object directly to signInWithWeb3({ chain: 'solana', wallet: resolvedUserWallet }) instead.")}else{if(typeof R!="object"||!(N!=null&&N.url))throw new Error("@supabase/auth-js: Both wallet and url must be specified in non-browser environments.");P=R}const G=new URL((i=N==null?void 0:N.url)!==null&&i!==void 0?i:window.location.href);if("signIn"in P&&P.signIn){const X=await P.signIn(Object.assign(Object.assign(Object.assign({issuedAt:new Date().toISOString()},N==null?void 0:N.signInWithSolana),{version:"1",domain:G.host,uri:G.href}),M?{statement:M}:null));let q;if(Array.isArray(X)&&X[0]&&typeof X[0]=="object")q=X[0];else if(X&&typeof X=="object"&&"signedMessage"in X&&"signature"in X)q=X;else throw new Error("@supabase/auth-js: Wallet method signIn() returned unrecognized value");if("signedMessage"in q&&"signature"in q&&(typeof q.signedMessage=="string"||q.signedMessage instanceof Uint8Array)&&q.signature instanceof Uint8Array)S=typeof q.signedMessage=="string"?q.signedMessage:new TextDecoder().decode(q.signedMessage),T=q.signature;else throw new Error("@supabase/auth-js: Wallet method signIn() API returned object without signedMessage and signature fields")}else{if(!("signMessage"in P)||typeof P.signMessage!="function"||!("publicKey"in P)||typeof P!="object"||!P.publicKey||!("toBase58"in P.publicKey)||typeof P.publicKey.toBase58!="function")throw new Error("@supabase/auth-js: Wallet does not have a compatible signMessage() and publicKey.toBase58() API");S=[`${G.host} wants you to sign in with your Solana account:`,P.publicKey.toBase58(),...M?["",M,""]:[""],"Version: 1",`URI: ${G.href}`,`Issued At: ${(l=(a=N==null?void 0:N.signInWithSolana)===null||a===void 0?void 0:a.issuedAt)!==null&&l!==void 0?l:new Date().toISOString()}`,...!((c=N==null?void 0:N.signInWithSolana)===null||c===void 0)&&c.notBefore?[`Not Before: ${N.signInWithSolana.notBefore}`]:[],...!((u=N==null?void 0:N.signInWithSolana)===null||u===void 0)&&u.expirationTime?[`Expiration Time: ${N.signInWithSolana.expirationTime}`]:[],...!((d=N==null?void 0:N.signInWithSolana)===null||d===void 0)&&d.chainId?[`Chain ID: ${N.signInWithSolana.chainId}`]:[],...!((m=N==null?void 0:N.signInWithSolana)===null||m===void 0)&&m.nonce?[`Nonce: ${N.signInWithSolana.nonce}`]:[],...!((p=N==null?void 0:N.signInWithSolana)===null||p===void 0)&&p.requestId?[`Request ID: ${N.signInWithSolana.requestId}`]:[],...!((v=(y=N==null?void 0:N.signInWithSolana)===null||y===void 0?void 0:y.resources)===null||v===void 0)&&v.length?["Resources",...N.signInWithSolana.resources.map(q=>`- ${q}`)]:[]].join(` -`);const X=await P.signMessage(new TextEncoder().encode(S),"utf8");if(!X||!(X instanceof Uint8Array))throw new Error("@supabase/auth-js: Wallet signMessage() API returned an recognized value");T=X}}try{const{data:k,error:R}=await ue(this.fetch,"POST",`${this.url}/token?grant_type=web3`,{headers:this.headers,body:Object.assign({chain:"solana",message:S,signature:zi(T)},!((x=e.options)===null||x===void 0)&&x.captchaToken?{gotrue_meta_security:{captcha_token:(_=e.options)===null||_===void 0?void 0:_.captchaToken}}:null),xform:Tn});if(R)throw R;if(!k||!k.session||!k.user){const M=new Na;return this._returnResult({data:{user:null,session:null},error:M})}return k.session&&(await this._saveSession(k.session),await this._notifyAllSubscribers("SIGNED_IN",k.session)),this._returnResult({data:Object.assign({},k),error:R})}catch(k){if(ne(k))return this._returnResult({data:{user:null,session:null},error:k});throw k}}async _exchangeCodeForSession(e){const i=await Un(this.storage,`${this.storageKey}-code-verifier`),[a,l]=(i??"").split("/");try{if(!a&&this.flowType==="pkce")throw new Xk;const{data:c,error:u}=await ue(this.fetch,"POST",`${this.url}/token?grant_type=pkce`,{headers:this.headers,body:{auth_code:e,code_verifier:a},xform:Tn});if(await ft(this.storage,`${this.storageKey}-code-verifier`),u)throw u;if(!c||!c.session||!c.user){const d=new Na;return this._returnResult({data:{user:null,session:null,redirectType:null},error:d})}return c.session&&(await this._saveSession(c.session),await this._notifyAllSubscribers(l==="recovery"?"PASSWORD_RECOVERY":"SIGNED_IN",c.session)),this._returnResult({data:Object.assign(Object.assign({},c),{redirectType:l??null}),error:u})}catch(c){if(await ft(this.storage,`${this.storageKey}-code-verifier`),ne(c))return this._returnResult({data:{user:null,session:null,redirectType:null},error:c});throw c}}async signInWithIdToken(e){try{const{options:i,provider:a,token:l,access_token:c,nonce:u}=e,d=await ue(this.fetch,"POST",`${this.url}/token?grant_type=id_token`,{headers:this.headers,body:{provider:a,id_token:l,access_token:c,nonce:u,gotrue_meta_security:{captcha_token:i==null?void 0:i.captchaToken}},xform:Tn}),{data:m,error:p}=d;if(p)return this._returnResult({data:{user:null,session:null},error:p});if(!m||!m.session||!m.user){const y=new Na;return this._returnResult({data:{user:null,session:null},error:y})}return m.session&&(await this._saveSession(m.session),await this._notifyAllSubscribers("SIGNED_IN",m.session)),this._returnResult({data:m,error:p})}catch(i){if(ne(i))return this._returnResult({data:{user:null,session:null},error:i});throw i}}async signInWithOtp(e){var i,a,l,c,u;try{if("email"in e){const{email:d,options:m}=e;let p=null,y=null;this.flowType==="pkce"&&([p,y]=await Di(this.storage,this.storageKey));const{error:v}=await ue(this.fetch,"POST",`${this.url}/otp`,{headers:this.headers,body:{email:d,data:(i=m==null?void 0:m.data)!==null&&i!==void 0?i:{},create_user:(a=m==null?void 0:m.shouldCreateUser)!==null&&a!==void 0?a:!0,gotrue_meta_security:{captcha_token:m==null?void 0:m.captchaToken},code_challenge:p,code_challenge_method:y},redirectTo:m==null?void 0:m.emailRedirectTo});return this._returnResult({data:{user:null,session:null},error:v})}if("phone"in e){const{phone:d,options:m}=e,{data:p,error:y}=await ue(this.fetch,"POST",`${this.url}/otp`,{headers:this.headers,body:{phone:d,data:(l=m==null?void 0:m.data)!==null&&l!==void 0?l:{},create_user:(c=m==null?void 0:m.shouldCreateUser)!==null&&c!==void 0?c:!0,gotrue_meta_security:{captcha_token:m==null?void 0:m.captchaToken},channel:(u=m==null?void 0:m.channel)!==null&&u!==void 0?u:"sms"}});return this._returnResult({data:{user:null,session:null,messageId:p==null?void 0:p.message_id},error:y})}throw new ac("You must provide either an email or phone number.")}catch(d){if(await ft(this.storage,`${this.storageKey}-code-verifier`),ne(d))return this._returnResult({data:{user:null,session:null},error:d});throw d}}async verifyOtp(e){var i,a;try{let l,c;"options"in e&&(l=(i=e.options)===null||i===void 0?void 0:i.redirectTo,c=(a=e.options)===null||a===void 0?void 0:a.captchaToken);const{data:u,error:d}=await ue(this.fetch,"POST",`${this.url}/verify`,{headers:this.headers,body:Object.assign(Object.assign({},e),{gotrue_meta_security:{captcha_token:c}}),redirectTo:l,xform:Tn});if(d)throw d;if(!u)throw new Error("An error occurred on token verification.");const m=u.session,p=u.user;return m!=null&&m.access_token&&(await this._saveSession(m),await this._notifyAllSubscribers(e.type=="recovery"?"PASSWORD_RECOVERY":"SIGNED_IN",m)),this._returnResult({data:{user:p,session:m},error:null})}catch(l){if(ne(l))return this._returnResult({data:{user:null,session:null},error:l});throw l}}async signInWithSSO(e){var i,a,l,c,u;try{let d=null,m=null;this.flowType==="pkce"&&([d,m]=await Di(this.storage,this.storageKey));const p=await ue(this.fetch,"POST",`${this.url}/sso`,{body:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},"providerId"in e?{provider_id:e.providerId}:null),"domain"in e?{domain:e.domain}:null),{redirect_to:(a=(i=e.options)===null||i===void 0?void 0:i.redirectTo)!==null&&a!==void 0?a:void 0}),!((l=e==null?void 0:e.options)===null||l===void 0)&&l.captchaToken?{gotrue_meta_security:{captcha_token:e.options.captchaToken}}:null),{skip_http_redirect:!0,code_challenge:d,code_challenge_method:m}),headers:this.headers,xform:wR});return!((c=p.data)===null||c===void 0)&&c.url&&Vt()&&!(!((u=e.options)===null||u===void 0)&&u.skipBrowserRedirect)&&window.location.assign(p.data.url),this._returnResult(p)}catch(d){if(await ft(this.storage,`${this.storageKey}-code-verifier`),ne(d))return this._returnResult({data:null,error:d});throw d}}async reauthenticate(){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._reauthenticate()):await this._reauthenticate()}async _reauthenticate(){try{return await this._useSession(async e=>{const{data:{session:i},error:a}=e;if(a)throw a;if(!i)throw new Nt;const{error:l}=await ue(this.fetch,"GET",`${this.url}/reauthenticate`,{headers:this.headers,jwt:i.access_token});return this._returnResult({data:{user:null,session:null},error:l})})}catch(e){if(ne(e))return this._returnResult({data:{user:null,session:null},error:e});throw e}}async resend(e){try{const i=`${this.url}/resend`;if("email"in e){const{email:a,type:l,options:c}=e;let u=null,d=null;this.flowType==="pkce"&&([u,d]=await Di(this.storage,this.storageKey));const{error:m}=await ue(this.fetch,"POST",i,{headers:this.headers,body:{email:a,type:l,gotrue_meta_security:{captcha_token:c==null?void 0:c.captchaToken},code_challenge:u,code_challenge_method:d},redirectTo:c==null?void 0:c.emailRedirectTo});return m&&await ft(this.storage,`${this.storageKey}-code-verifier`),this._returnResult({data:{user:null,session:null},error:m})}else if("phone"in e){const{phone:a,type:l,options:c}=e,{data:u,error:d}=await ue(this.fetch,"POST",i,{headers:this.headers,body:{phone:a,type:l,gotrue_meta_security:{captcha_token:c==null?void 0:c.captchaToken}}});return this._returnResult({data:{user:null,session:null,messageId:u==null?void 0:u.message_id},error:d})}throw new ac("You must provide either an email or phone number and a type")}catch(i){if(await ft(this.storage,`${this.storageKey}-code-verifier`),ne(i))return this._returnResult({data:{user:null,session:null},error:i});throw i}}async getSession(){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>this._useSession(async e=>e)):await this._useSession(async e=>e)}async _acquireLock(e,i){this._debug("#_acquireLock","begin",e);try{if(this.lockAcquired){const a=this.pendingInLock.length?this.pendingInLock[this.pendingInLock.length-1]:Promise.resolve(),l=(async()=>(await a,await i()))();return this.pendingInLock.push((async()=>{try{await l}catch{}})()),l}return await this.lock(`lock:${this.storageKey}`,e,async()=>{this._debug("#_acquireLock","lock acquired for storage key",this.storageKey);try{this.lockAcquired=!0;const a=i();for(this.pendingInLock.push((async()=>{try{await a}catch{}})()),await a;this.pendingInLock.length;){const l=[...this.pendingInLock];await Promise.all(l),this.pendingInLock.splice(0,l.length)}return await a}finally{this._debug("#_acquireLock","lock released for storage key",this.storageKey),this.lockAcquired=!1}})}finally{this._debug("#_acquireLock","end")}}async _useSession(e){this._debug("#_useSession","begin");try{const i=await this.__loadSession();return await e(i)}finally{this._debug("#_useSession","end")}}async __loadSession(){this._debug("#__loadSession()","begin"),this.lock!=null&&!this.lockAcquired&&this._debug("#__loadSession()","used outside of an acquired lock!",new Error().stack);try{let e=null;const i=await Un(this.storage,this.storageKey);if(this._debug("#getSession()","session from storage",i),i!==null&&(this._isValidSession(i)?e=i:(this._debug("#getSession()","session from storage is not valid"),await this._removeSession())),!e)return{data:{session:null},error:null};const a=e.expires_at?e.expires_at*1e3-Date.now()Date.now())){const d=await Un(this.storage,this.storageKey);if(d&&d.refresh_token===e.refresh_token)return this._returnResult({data:{session:e},error:null})}return this._returnResult({data:{session:null},error:c})}return this._returnResult({data:{session:l},error:null})}finally{this._debug("#__loadSession()","end")}}async getUser(e){if(e)return await this._getUser(e);await this.initializePromise;let i;return this.lock!=null?i=await this._acquireLock(this.lockAcquireTimeout,async()=>await this._getUser()):i=await this._getUser(),i.data.user&&(this.suppressGetSessionWarning=!0),i}async _getUser(e){try{return e?await ue(this.fetch,"GET",`${this.url}/user`,{headers:this.headers,jwt:e,xform:ai}):await this._useSession(async i=>{var a,l,c;const{data:u,error:d}=i;if(d)throw d;return!(!((a=u.session)===null||a===void 0)&&a.access_token)&&!this.hasCustomAuthorizationHeader?{data:{user:null},error:new Nt}:await ue(this.fetch,"GET",`${this.url}/user`,{headers:this.headers,jwt:(c=(l=u.session)===null||l===void 0?void 0:l.access_token)!==null&&c!==void 0?c:void 0,xform:ai})})}catch(i){if(ne(i))return ic(i)&&(await this._removeSession(),await ft(this.storage,`${this.storageKey}-code-verifier`)),this._returnResult({data:{user:null},error:i});throw i}}async updateUser(e,i={}){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._updateUser(e,i)):await this._updateUser(e,i)}async _updateUser(e,i={}){try{return await this._useSession(async a=>{const{data:l,error:c}=a;if(c)throw c;if(!l.session)throw new Nt;const u=l.session;let d=null,m=null;this.flowType==="pkce"&&e.email!=null&&([d,m]=await Di(this.storage,this.storageKey));const{data:p,error:y}=await ue(this.fetch,"PUT",`${this.url}/user`,{headers:this.headers,redirectTo:i==null?void 0:i.emailRedirectTo,body:Object.assign(Object.assign({},e),{code_challenge:d,code_challenge_method:m}),jwt:u.access_token,xform:ai});if(y)throw y;return u.user=p.user,await this._saveSession(u),await this._notifyAllSubscribers("USER_UPDATED",u),this._returnResult({data:{user:u.user},error:null})})}catch(a){if(await ft(this.storage,`${this.storageKey}-code-verifier`),ne(a))return this._returnResult({data:{user:null},error:a});throw a}}async setSession(e){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._setSession(e)):await this._setSession(e)}async _setSession(e){try{if(!e.access_token||!e.refresh_token)throw new Nt;const i=Date.now()/1e3;let a=i,l=!0,c=null;const{payload:u}=oc(e.access_token);if(u.exp&&(a=u.exp,l=a<=i),l){const{data:d,error:m}=await this._callRefreshToken(e.refresh_token);if(m)return this._returnResult({data:{user:null,session:null},error:m});if(!d)return{data:{user:null,session:null},error:null};c=d}else{const{data:d,error:m}=await this._getUser(e.access_token);if(m)return this._returnResult({data:{user:null,session:null},error:m});c={access_token:e.access_token,refresh_token:e.refresh_token,user:d.user,token_type:"bearer",expires_in:a-i,expires_at:a},await this._saveSession(c),await this._notifyAllSubscribers("SIGNED_IN",c)}return this._returnResult({data:{user:c.user,session:c},error:null})}catch(i){if(ne(i))return this._returnResult({data:{session:null,user:null},error:i});throw i}}async refreshSession(e){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._refreshSession(e)):await this._refreshSession(e)}async _refreshSession(e){try{return await this._useSession(async i=>{var a;if(!e){const{data:u,error:d}=i;if(d)throw d;e=(a=u.session)!==null&&a!==void 0?a:void 0}if(!(e!=null&&e.refresh_token))throw new Nt;const{data:l,error:c}=await this._callRefreshToken(e.refresh_token);return c?this._returnResult({data:{user:null,session:null},error:c}):l?this._returnResult({data:{user:l.user,session:l},error:null}):this._returnResult({data:{user:null,session:null},error:null})})}catch(i){if(ne(i))return this._returnResult({data:{user:null,session:null},error:i});throw i}}async _getSessionFromURL(e,i){var a;try{if(!Vt())throw new rc("No browser detected.");if(e.error||e.error_description||e.error_code)throw new rc(e.error_description||"Error in URL with unspecified error_description",{error:e.error||"unspecified_error",code:e.error_code||"unspecified_code"});switch(i){case"implicit":if(this.flowType==="pkce")throw new Pb("Not a valid PKCE flow url.");break;case"pkce":if(this.flowType==="implicit")throw new rc("Not a valid implicit grant flow url.");break;default:}if(i==="pkce"){if(this._debug("#_initialize()","begin","is PKCE flow",!0),!e.code)throw new Pb("No code detected.");const{data:N,error:P}=await this._exchangeCodeForSession(e.code);if(P)throw P;const G=new URL(window.location.href);return G.searchParams.delete("code"),window.history.replaceState(window.history.state,"",G.toString()),{data:{session:N.session,redirectType:(a=N.redirectType)!==null&&a!==void 0?a:null},error:null}}const{provider_token:l,provider_refresh_token:c,access_token:u,refresh_token:d,expires_in:m,expires_at:p,token_type:y}=e;if(!u||!m||!d||!y)throw new rc("No session defined in URL");const v=Math.round(Date.now()/1e3),x=parseInt(m);let _=v+x;p&&(_=parseInt(p));const S=_-v;S*1e3<=ks&&console.warn(`@supabase/gotrue-js: Session as retrieved from URL expires in ${S}s, should have been closer to ${x}s`);const T=_-x;v-T>=120?console.warn("@supabase/gotrue-js: Session as retrieved from URL was issued over 120s ago, URL could be stale",T,_,v):v-T<0&&console.warn("@supabase/gotrue-js: Session as retrieved from URL was issued in the future? Check the device clock for skew",T,_,v);const{data:k,error:R}=await this._getUser(u);if(R)throw R;const M={provider_token:l,provider_refresh_token:c,access_token:u,expires_in:x,expires_at:_,refresh_token:d,token_type:y,user:k.user};return window.location.hash="",this._debug("#_getSessionFromURL()","clearing window.location.hash"),this._returnResult({data:{session:M,redirectType:e.type},error:null})}catch(l){if(ne(l))return this._returnResult({data:{session:null,redirectType:null},error:l});throw l}}_isImplicitGrantCallback(e){return typeof this.detectSessionInUrl=="function"?this.detectSessionInUrl(new URL(window.location.href),e):!!(e.access_token||e.error||e.error_description||e.error_code)}async _isPKCECallback(e){const i=await Un(this.storage,`${this.storageKey}-code-verifier`);return!!(e.code&&i)}async signOut(e={scope:"global"}){return await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>await this._signOut(e)):await this._signOut(e)}async _signOut({scope:e}={scope:"global"}){return await this._useSession(async i=>{var a;const l=async()=>{await this._removeSession(),await ft(this.storage,`${this.storageKey}-code-verifier`)},{data:c,error:u}=i;if(u&&!ic(u))return this._returnResult({error:u});const d=(a=c.session)===null||a===void 0?void 0:a.access_token;if(d){const{error:m}=await this.admin.signOut(d,e);if(m&&!(Kk(m)&&(m.status===404||m.status===401||m.status===403)||ic(m)))return e!=="others"&&await l(),this._returnResult({error:m})}return e!=="others"&&await l(),this._returnResult({error:null})})}onAuthStateChange(e){const i=sR(),a={id:i,callback:e,unsubscribe:()=>{this._debug("#unsubscribe()","state change callback with id removed",i),this.stateChangeEmitters.delete(i)}};return this._debug("#onAuthStateChange()","registered callback with id",i),this.stateChangeEmitters.set(i,a),(async()=>(await this.initializePromise,this.lock!=null?await this._acquireLock(this.lockAcquireTimeout,async()=>{this._emitInitialSession(i)}):await this._emitInitialSession(i)))(),{data:{subscription:a}}}async _emitInitialSession(e){return await this._useSession(async i=>{var a,l;try{const{data:{session:c},error:u}=i;if(u)throw u;await((a=this.stateChangeEmitters.get(e))===null||a===void 0?void 0:a.callback("INITIAL_SESSION",c)),this._debug("INITIAL_SESSION","callback id",e,"session",c)}catch(c){await((l=this.stateChangeEmitters.get(e))===null||l===void 0?void 0:l.callback("INITIAL_SESSION",null)),this._debug("INITIAL_SESSION","callback id",e,"error",c),ic(c)?console.warn(c):console.error(c)}})}async resetPasswordForEmail(e,i={}){let a=null,l=null;this.flowType==="pkce"&&([a,l]=await Di(this.storage,this.storageKey,!0));try{return await ue(this.fetch,"POST",`${this.url}/recover`,{body:{email:e,code_challenge:a,code_challenge_method:l,gotrue_meta_security:{captcha_token:i.captchaToken}},headers:this.headers,redirectTo:i.redirectTo})}catch(c){if(await ft(this.storage,`${this.storageKey}-code-verifier`),ne(c))return this._returnResult({data:null,error:c});throw c}}async getUserIdentities(){var e;try{const{data:i,error:a}=await this.getUser();if(a)throw a;return this._returnResult({data:{identities:(e=i.user.identities)!==null&&e!==void 0?e:[]},error:null})}catch(i){if(ne(i))return this._returnResult({data:null,error:i});throw i}}async linkIdentity(e){return"token"in e?this.linkIdentityIdToken(e):this.linkIdentityOAuth(e)}async linkIdentityOAuth(e){var i;try{const{data:a,error:l}=await this._useSession(async c=>{var u,d,m,p,y;const{data:v,error:x}=c;if(x)throw x;const _=await this._getUrlForProvider(`${this.url}/user/identities/authorize`,e.provider,{redirectTo:(u=e.options)===null||u===void 0?void 0:u.redirectTo,scopes:(d=e.options)===null||d===void 0?void 0:d.scopes,queryParams:(m=e.options)===null||m===void 0?void 0:m.queryParams,skipBrowserRedirect:!0});return await ue(this.fetch,"GET",_,{headers:this.headers,jwt:(y=(p=v.session)===null||p===void 0?void 0:p.access_token)!==null&&y!==void 0?y:void 0})});if(l)throw l;return Vt()&&!(!((i=e.options)===null||i===void 0)&&i.skipBrowserRedirect)&&window.location.assign(a==null?void 0:a.url),this._returnResult({data:{provider:e.provider,url:a==null?void 0:a.url},error:null})}catch(a){if(ne(a))return this._returnResult({data:{provider:e.provider,url:null},error:a});throw a}}async linkIdentityIdToken(e){return await this._useSession(async i=>{var a;try{const{error:l,data:{session:c}}=i;if(l)throw l;const{options:u,provider:d,token:m,access_token:p,nonce:y}=e,v=await ue(this.fetch,"POST",`${this.url}/token?grant_type=id_token`,{headers:this.headers,jwt:(a=c==null?void 0:c.access_token)!==null&&a!==void 0?a:void 0,body:{provider:d,id_token:m,access_token:p,nonce:y,link_identity:!0,gotrue_meta_security:{captcha_token:u==null?void 0:u.captchaToken}},xform:Tn}),{data:x,error:_}=v;return _?this._returnResult({data:{user:null,session:null},error:_}):!x||!x.session||!x.user?this._returnResult({data:{user:null,session:null},error:new Na}):(x.session&&(await this._saveSession(x.session),await this._notifyAllSubscribers("USER_UPDATED",x.session)),this._returnResult({data:x,error:_}))}catch(l){if(await ft(this.storage,`${this.storageKey}-code-verifier`),ne(l))return this._returnResult({data:{user:null,session:null},error:l});throw l}})}async unlinkIdentity(e){try{return await this._useSession(async i=>{var a,l;const{data:c,error:u}=i;if(u)throw u;return await ue(this.fetch,"DELETE",`${this.url}/user/identities/${e.identity_id}`,{headers:this.headers,jwt:(l=(a=c.session)===null||a===void 0?void 0:a.access_token)!==null&&l!==void 0?l:void 0})})}catch(i){if(ne(i))return this._returnResult({data:null,error:i});throw i}}async _refreshAccessToken(e){const i="#_refreshAccessToken()";this._debug(i,"begin");try{const a=Date.now();return await oR(async l=>(l>0&&await rR(200*Math.pow(2,l-1)),this._debug(i,"refreshing attempt",l),await ue(this.fetch,"POST",`${this.url}/token?grant_type=refresh_token`,{body:{refresh_token:e},headers:this.headers,xform:Tn})),(l,c)=>{const u=200*Math.pow(2,l);return c&&Vb(c)&&Date.now()+u-aDate.now())?this._debug(l,"proactive refresh failed, access token still valid — preserving session"):await this._removeSession()}return this.lastRefreshFailure={refreshToken:e,result:u,expiresAt:Date.now()+Vk},(i=this.refreshingDeferred)===null||i===void 0||i.resolve(u),u}throw(a=this.refreshingDeferred)===null||a===void 0||a.reject(c),c}finally{this.refreshingDeferred=null,this._debug(l,"end")}}async _notifyAllSubscribers(e,i,a=!0){if(this._pendingInitNotifications!==null&&a){this._pendingInitNotifications.push({event:e,session:i,broadcast:a});return}const l=`#_notifyAllSubscribers(${e})`;this._debug(l,"begin",i,`broadcast = ${a}`);try{this.broadcastChannel&&a&&this.broadcastChannel.postMessage({event:e,session:i});const c=[],u=Array.from(this.stateChangeEmitters.values()).map(async d=>{try{await d.callback(e,i)}catch(m){c.push(m)}});if(await Promise.all(u),c.length>0){for(let d=0;dthis._autoRefreshTokenTick(),ks);this.autoRefreshTicker=e,e&&typeof e=="object"&&typeof e.unref=="function"?e.unref():typeof Deno<"u"&&typeof Deno.unrefTimer=="function"&&Deno.unrefTimer(e);const i=setTimeout(async()=>{await this.initializePromise,await this._autoRefreshTokenTick()},0);this.autoRefreshTickTimeout=i,i&&typeof i=="object"&&typeof i.unref=="function"?i.unref():typeof Deno<"u"&&typeof Deno.unrefTimer=="function"&&Deno.unrefTimer(i)}async _stopAutoRefresh(){this._debug("#_stopAutoRefresh()");const e=this.autoRefreshTicker;this.autoRefreshTicker=null,e&&clearInterval(e);const i=this.autoRefreshTickTimeout;this.autoRefreshTickTimeout=null,i&&clearTimeout(i)}async startAutoRefresh(){this._removeVisibilityChangedCallback(),await this._startAutoRefresh()}async stopAutoRefresh(){this._removeVisibilityChangedCallback(),await this._stopAutoRefresh()}async dispose(){var e;this._removeVisibilityChangedCallback(),await this._stopAutoRefresh(),(e=this.broadcastChannel)===null||e===void 0||e.close(),this.broadcastChannel=null,this.stateChangeEmitters.clear()}async _autoRefreshTokenTick(){if(this._debug("#_autoRefreshTokenTick()","begin"),this.lock!=null){try{await this._acquireLock(0,async()=>{try{const e=Date.now();try{return await this._useSession(async i=>{const{data:{session:a}}=i;if(!a||!a.refresh_token||!a.expires_at){this._debug("#_autoRefreshTokenTick()","no session");return}const l=Math.floor((a.expires_at*1e3-e)/ks);this._debug("#_autoRefreshTokenTick()",`access token expires in ${l} ticks, a tick lasts ${ks}ms, refresh threshold is ${Zr} ticks`),l<=Zr&&await this._callRefreshToken(a.refresh_token)})}catch(i){console.error("Auto refresh tick failed with error. This is likely a transient error.",i)}}finally{this._debug("#_autoRefreshTokenTick()","end")}})}catch(e){if(e instanceof ER)this._debug("auto refresh token tick lock not available");else throw e}return}if(this.refreshingDeferred!==null){this._debug("#_autoRefreshTokenTick()","refresh already in flight, skipping");return}try{const e=Date.now();try{await this._useSession(async i=>{const{data:{session:a}}=i;if(!a||!a.refresh_token||!a.expires_at){this._debug("#_autoRefreshTokenTick()","no session");return}const l=Math.floor((a.expires_at*1e3-e)/ks);this._debug("#_autoRefreshTokenTick()",`access token expires in ${l} ticks, a tick lasts ${ks}ms, refresh threshold is ${Zr} ticks`),l<=Zr&&await this._callRefreshToken(a.refresh_token)})}catch(i){console.error("Auto refresh tick failed with error. This is likely a transient error.",i)}}finally{this._debug("#_autoRefreshTokenTick()","end")}}async _handleVisibilityChange(){if(this._debug("#_handleVisibilityChange()"),!Vt()||!(window!=null&&window.addEventListener))return this.autoRefreshToken&&this.startAutoRefresh(),!1;try{this.visibilityChangedCallback=async()=>{try{await this._onVisibilityChanged(!1)}catch(e){this._debug("#visibilityChangedCallback","error",e)}},window==null||window.addEventListener("visibilitychange",this.visibilityChangedCallback),await this._onVisibilityChanged(!0)}catch(e){console.error("_handleVisibilityChange",e)}}async _onVisibilityChanged(e){const i=`#_onVisibilityChanged(${e})`;if(this._debug(i,"visibilityState",document.visibilityState),document.visibilityState==="visible"){if(this.autoRefreshToken&&this._startAutoRefresh(),!e)if(await this.initializePromise,this.lock!=null)await this._acquireLock(this.lockAcquireTimeout,async()=>{if(document.visibilityState!=="visible"){this._debug(i,"acquired the lock to recover the session, but the browser visibilityState is no longer visible, aborting");return}await this._recoverAndRefresh()});else{if(document.visibilityState!=="visible"){this._debug(i,"visibilityState is no longer visible, skipping recovery");return}await this._recoverAndRefresh()}}else document.visibilityState==="hidden"&&this.autoRefreshToken&&this._stopAutoRefresh()}async _getUrlForProvider(e,i,a){const l=[`provider=${encodeURIComponent(i)}`];if(a!=null&&a.redirectTo&&l.push(`redirect_to=${encodeURIComponent(a.redirectTo)}`),a!=null&&a.scopes&&l.push(`scopes=${encodeURIComponent(a.scopes)}`),this.flowType==="pkce"){const[c,u]=await Di(this.storage,this.storageKey),d=new URLSearchParams({code_challenge:`${encodeURIComponent(c)}`,code_challenge_method:`${encodeURIComponent(u)}`});l.push(d.toString())}if(a!=null&&a.queryParams){const c=new URLSearchParams(a.queryParams);l.push(c.toString())}return a!=null&&a.skipBrowserRedirect&&l.push(`skip_http_redirect=${a.skipBrowserRedirect}`),`${e}?${l.join("&")}`}async _unenroll(e){try{return await this._useSession(async i=>{var a;const{data:l,error:c}=i;return c?this._returnResult({data:null,error:c}):await ue(this.fetch,"DELETE",`${this.url}/factors/${e.factorId}`,{headers:this.headers,jwt:(a=l==null?void 0:l.session)===null||a===void 0?void 0:a.access_token})})}catch(i){if(ne(i))return this._returnResult({data:null,error:i});throw i}}async _enroll(e){try{return await this._useSession(async i=>{var a,l;const{data:c,error:u}=i;if(u)return this._returnResult({data:null,error:u});const d=Object.assign({friendly_name:e.friendlyName,factor_type:e.factorType},e.factorType==="phone"?{phone:e.phone}:e.factorType==="totp"?{issuer:e.issuer}:{}),{data:m,error:p}=await ue(this.fetch,"POST",`${this.url}/factors`,{body:d,headers:this.headers,jwt:(a=c==null?void 0:c.session)===null||a===void 0?void 0:a.access_token});return p?this._returnResult({data:null,error:p}):(e.factorType==="totp"&&m.type==="totp"&&(!((l=m==null?void 0:m.totp)===null||l===void 0)&&l.qr_code)&&(m.totp.qr_code=`data:image/svg+xml;utf-8,${m.totp.qr_code}`),this._returnResult({data:m,error:null}))})}catch(i){if(ne(i))return this._returnResult({data:null,error:i});throw i}}async _verify(e){const i=async()=>{try{return await this._useSession(async a=>{var l;const{data:c,error:u}=a;if(u)return this._returnResult({data:null,error:u});const d=Object.assign({challenge_id:e.challengeId},"webauthn"in e?{webauthn:Object.assign(Object.assign({},e.webauthn),{credential_response:e.webauthn.type==="create"?Wb(e.webauthn.credential_response):ev(e.webauthn.credential_response)})}:{code:e.code}),{data:m,error:p}=await ue(this.fetch,"POST",`${this.url}/factors/${e.factorId}/verify`,{body:d,headers:this.headers,jwt:(l=c==null?void 0:c.session)===null||l===void 0?void 0:l.access_token});return p?this._returnResult({data:null,error:p}):(await this._saveSession(Object.assign({expires_at:Math.round(Date.now()/1e3)+m.expires_in},m)),await this._notifyAllSubscribers("MFA_CHALLENGE_VERIFIED",m),this._returnResult({data:m,error:p}))})}catch(a){if(ne(a))return this._returnResult({data:null,error:a});throw a}};return this.lock!=null?this._acquireLock(this.lockAcquireTimeout,i):i()}async _challenge(e){const i=async()=>{try{return await this._useSession(async a=>{var l;const{data:c,error:u}=a;if(u)return this._returnResult({data:null,error:u});const d=await ue(this.fetch,"POST",`${this.url}/factors/${e.factorId}/challenge`,{body:e,headers:this.headers,jwt:(l=c==null?void 0:c.session)===null||l===void 0?void 0:l.access_token});if(d.error)return d;const{data:m}=d;if(m.type!=="webauthn")return{data:m,error:null};switch(m.webauthn.type){case"create":return{data:Object.assign(Object.assign({},m),{webauthn:Object.assign(Object.assign({},m.webauthn),{credential_options:Object.assign(Object.assign({},m.webauthn.credential_options),{publicKey:Qb(m.webauthn.credential_options.publicKey)})})}),error:null};case"request":return{data:Object.assign(Object.assign({},m),{webauthn:Object.assign(Object.assign({},m.webauthn),{credential_options:Object.assign(Object.assign({},m.webauthn.credential_options),{publicKey:Zb(m.webauthn.credential_options.publicKey)})})}),error:null}}})}catch(a){if(ne(a))return this._returnResult({data:null,error:a});throw a}};return this.lock!=null?this._acquireLock(this.lockAcquireTimeout,i):i()}async _challengeAndVerify(e){const{data:i,error:a}=await this._challenge({factorId:e.factorId});return a?this._returnResult({data:null,error:a}):await this._verify({factorId:e.factorId,challengeId:i.id,code:e.code})}async _listFactors(){var e;const{data:{user:i},error:a}=await this.getUser();if(a)return{data:null,error:a};const l={all:[],phone:[],totp:[],webauthn:[]};for(const c of(e=i==null?void 0:i.factors)!==null&&e!==void 0?e:[])l.all.push(c),c.status==="verified"&&l[c.factor_type].push(c);return{data:l,error:null}}async _getAuthenticatorAssuranceLevel(e){var i,a,l,c;if(e)try{const{payload:_}=oc(e);let S=null;_.aal&&(S=_.aal);let T=S;const{data:{user:k},error:R}=await this.getUser(e);if(R)return this._returnResult({data:null,error:R});((a=(i=k==null?void 0:k.factors)===null||i===void 0?void 0:i.filter(P=>P.status==="verified"))!==null&&a!==void 0?a:[]).length>0&&(T="aal2");const N=_.amr||[];return{data:{currentLevel:S,nextLevel:T,currentAuthenticationMethods:N},error:null}}catch(_){if(ne(_))return this._returnResult({data:null,error:_});throw _}const{data:{session:u},error:d}=await this.getSession();if(d)return this._returnResult({data:null,error:d});if(!u)return{data:{currentLevel:null,nextLevel:null,currentAuthenticationMethods:[]},error:null};const{payload:m}=oc(u.access_token);let p=null;m.aal&&(p=m.aal);let y=p;((c=(l=u.user.factors)===null||l===void 0?void 0:l.filter(_=>_.status==="verified"))!==null&&c!==void 0?c:[]).length>0&&(y="aal2");const x=m.amr||[];return{data:{currentLevel:p,nextLevel:y,currentAuthenticationMethods:x},error:null}}async _getAuthorizationDetails(e){try{return await this._useSession(async i=>{const{data:{session:a},error:l}=i;return l?this._returnResult({data:null,error:l}):a?await ue(this.fetch,"GET",`${this.url}/oauth/authorizations/${e}`,{headers:this.headers,jwt:a.access_token,xform:c=>({data:c,error:null})}):this._returnResult({data:null,error:new Nt})})}catch(i){if(ne(i))return this._returnResult({data:null,error:i});throw i}}async _approveAuthorization(e,i){try{return await this._useSession(async a=>{const{data:{session:l},error:c}=a;if(c)return this._returnResult({data:null,error:c});if(!l)return this._returnResult({data:null,error:new Nt});const u=await ue(this.fetch,"POST",`${this.url}/oauth/authorizations/${e}/consent`,{headers:this.headers,jwt:l.access_token,body:{action:"approve"},xform:d=>({data:d,error:null})});return u.data&&u.data.redirect_url&&Vt()&&!(i!=null&&i.skipBrowserRedirect)&&window.location.assign(u.data.redirect_url),u})}catch(a){if(ne(a))return this._returnResult({data:null,error:a});throw a}}async _denyAuthorization(e,i){try{return await this._useSession(async a=>{const{data:{session:l},error:c}=a;if(c)return this._returnResult({data:null,error:c});if(!l)return this._returnResult({data:null,error:new Nt});const u=await ue(this.fetch,"POST",`${this.url}/oauth/authorizations/${e}/consent`,{headers:this.headers,jwt:l.access_token,body:{action:"deny"},xform:d=>({data:d,error:null})});return u.data&&u.data.redirect_url&&Vt()&&!(i!=null&&i.skipBrowserRedirect)&&window.location.assign(u.data.redirect_url),u})}catch(a){if(ne(a))return this._returnResult({data:null,error:a});throw a}}async _listOAuthGrants(){try{return await this._useSession(async e=>{const{data:{session:i},error:a}=e;return a?this._returnResult({data:null,error:a}):i?await ue(this.fetch,"GET",`${this.url}/user/oauth/grants`,{headers:this.headers,jwt:i.access_token,xform:l=>({data:l,error:null})}):this._returnResult({data:null,error:new Nt})})}catch(e){if(ne(e))return this._returnResult({data:null,error:e});throw e}}async _revokeOAuthGrant(e){try{return await this._useSession(async i=>{const{data:{session:a},error:l}=i;return l?this._returnResult({data:null,error:l}):a?(await ue(this.fetch,"DELETE",`${this.url}/user/oauth/grants`,{headers:this.headers,jwt:a.access_token,query:{client_id:e.clientId},noResolveJson:!0}),{data:{},error:null}):this._returnResult({data:null,error:new Nt})})}catch(i){if(ne(i))return this._returnResult({data:null,error:i});throw i}}async fetchJwk(e,i={keys:[]}){let a=i.keys.find(d=>d.kid===e);if(a)return a;const l=Date.now();if(a=this.jwks.keys.find(d=>d.kid===e),a&&this.jwks_cached_at+Ik>l)return a;const{data:c,error:u}=await ue(this.fetch,"GET",`${this.url}/.well-known/jwks.json`,{headers:this.headers});if(u)throw u;return!c.keys||c.keys.length===0||(this.jwks=c,this.jwks_cached_at=l,a=c.keys.find(d=>d.kid===e),!a)?null:a}async getClaims(e,i={}){try{let a=e;if(!a){const{data:_,error:S}=await this.getSession();if(S||!_.session)return this._returnResult({data:null,error:S});a=_.session.access_token}const{header:l,payload:c,signature:u,raw:{header:d,payload:m}}=oc(a);if(!(i!=null&&i.allowExpired))try{mR(c.exp)}catch(_){throw new Oc(_ instanceof Error?_.message:"JWT validation failed")}const p=!l.alg||l.alg.startsWith("HS")||!l.kid||!("crypto"in globalThis&&"subtle"in globalThis.crypto)?null:await this.fetchJwk(l.kid,i!=null&&i.keys?{keys:i.keys}:i==null?void 0:i.jwks);if(!p){const{error:_}=await this.getUser(a);if(_)throw _;return{data:{claims:c,header:l,signature:u},error:null}}const y=pR(l.alg),v=await crypto.subtle.importKey("jwk",p,y,!0,["verify"]);if(!await crypto.subtle.verify(y,v,u,tR(`${d}.${m}`)))throw new Oc("Invalid JWT signature");return{data:{claims:c,header:l,signature:u},error:null}}catch(a){if(ne(a))return this._returnResult({data:null,error:a});throw a}}async signInWithPasskey(e){var i,a,l;zn(this.experimental);try{if(!Bc())return this._returnResult({data:null,error:new Hn("Browser does not support WebAuthn",null)});const{data:c,error:u}=await this._startPasskeyAuthentication({options:{captchaToken:(i=e==null?void 0:e.options)===null||i===void 0?void 0:i.captchaToken}});if(u||!c)return this._returnResult({data:null,error:u});const d=Zb(c.options),m=(l=(a=e==null?void 0:e.options)===null||a===void 0?void 0:a.signal)!==null&&l!==void 0?l:vf.createNewAbortSignal(),{data:p,error:y}=await Mw({publicKey:d,signal:m});if(y||!p)return this._returnResult({data:null,error:y??new Hn("WebAuthn ceremony failed",null)});const v=ev(p);return this._verifyPasskeyAuthentication({challengeId:c.challenge_id,credential:v})}catch(c){if(ne(c))return this._returnResult({data:null,error:c});throw c}}async registerPasskey(e){var i,a;zn(this.experimental);try{if(!Bc())return this._returnResult({data:null,error:new Hn("Browser does not support WebAuthn",null)});const{data:l,error:c}=await this._startPasskeyRegistration();if(c||!l)return this._returnResult({data:null,error:c});const u=Qb(l.options),d=(a=(i=e==null?void 0:e.options)===null||i===void 0?void 0:i.signal)!==null&&a!==void 0?a:vf.createNewAbortSignal(),{data:m,error:p}=await Dw({publicKey:u,signal:d});if(p||!m)return this._returnResult({data:null,error:p??new Hn("WebAuthn ceremony failed",null)});const y=Wb(m);return this._verifyPasskeyRegistration({challengeId:l.challenge_id,credential:y})}catch(l){if(ne(l))return this._returnResult({data:null,error:l});throw l}}async _startPasskeyRegistration(){zn(this.experimental);try{return await this._useSession(async e=>{const{data:{session:i},error:a}=e;if(a)return this._returnResult({data:null,error:a});if(!i)return this._returnResult({data:null,error:new Nt});const{data:l,error:c}=await ue(this.fetch,"POST",`${this.url}/passkeys/registration/options`,{headers:this.headers,jwt:i.access_token,body:{}});return c?this._returnResult({data:null,error:c}):this._returnResult({data:l,error:null})})}catch(e){if(ne(e))return this._returnResult({data:null,error:e});throw e}}async _verifyPasskeyRegistration(e){zn(this.experimental);try{return await this._useSession(async i=>{const{data:{session:a},error:l}=i;if(l)return this._returnResult({data:null,error:l});if(!a)return this._returnResult({data:null,error:new Nt});const{data:c,error:u}=await ue(this.fetch,"POST",`${this.url}/passkeys/registration/verify`,{headers:this.headers,jwt:a.access_token,body:{challenge_id:e.challengeId,credential:e.credential}});return u?this._returnResult({data:null,error:u}):this._returnResult({data:c,error:null})})}catch(i){if(ne(i))return this._returnResult({data:null,error:i});throw i}}async _startPasskeyAuthentication(e){var i;zn(this.experimental);try{const{data:a,error:l}=await ue(this.fetch,"POST",`${this.url}/passkeys/authentication/options`,{headers:this.headers,body:{gotrue_meta_security:{captcha_token:(i=e==null?void 0:e.options)===null||i===void 0?void 0:i.captchaToken}}});return l?this._returnResult({data:null,error:l}):this._returnResult({data:a,error:null})}catch(a){if(ne(a))return this._returnResult({data:null,error:a});throw a}}async _verifyPasskeyAuthentication(e){zn(this.experimental);try{const{data:i,error:a}=await ue(this.fetch,"POST",`${this.url}/passkeys/authentication/verify`,{headers:this.headers,body:{challenge_id:e.challengeId,credential:e.credential},xform:Tn});return a?this._returnResult({data:null,error:a}):(i.session&&(await this._saveSession(i.session),await this._notifyAllSubscribers("SIGNED_IN",i.session)),this._returnResult({data:i,error:null}))}catch(i){if(ne(i))return this._returnResult({data:null,error:i});throw i}}async _listPasskeys(){zn(this.experimental);try{return await this._useSession(async e=>{const{data:{session:i},error:a}=e;if(a)return this._returnResult({data:null,error:a});if(!i)return this._returnResult({data:null,error:new Nt});const{data:l,error:c}=await ue(this.fetch,"GET",`${this.url}/passkeys`,{headers:this.headers,jwt:i.access_token,xform:u=>({data:u,error:null})});return c?this._returnResult({data:null,error:c}):this._returnResult({data:l,error:null})})}catch(e){if(ne(e))return this._returnResult({data:null,error:e});throw e}}async _updatePasskey(e){zn(this.experimental);try{return await this._useSession(async i=>{const{data:{session:a},error:l}=i;if(l)return this._returnResult({data:null,error:l});if(!a)return this._returnResult({data:null,error:new Nt});const{data:c,error:u}=await ue(this.fetch,"PATCH",`${this.url}/passkeys/${e.passkeyId}`,{headers:this.headers,jwt:a.access_token,body:{friendly_name:e.friendlyName}});return u?this._returnResult({data:null,error:u}):this._returnResult({data:c,error:null})})}catch(i){if(ne(i))return this._returnResult({data:null,error:i});throw i}}async _deletePasskey(e){zn(this.experimental);try{return await this._useSession(async i=>{const{data:{session:a},error:l}=i;if(l)return this._returnResult({data:null,error:l});if(!a)return this._returnResult({data:null,error:new Nt});const{error:c}=await ue(this.fetch,"DELETE",`${this.url}/passkeys/${e.passkeyId}`,{headers:this.headers,jwt:a.access_token,noResolveJson:!0});return c?this._returnResult({data:null,error:c}):this._returnResult({data:null,error:null})})}catch(i){if(ne(i))return this._returnResult({data:null,error:i});throw i}}}wo.nextInstanceID={};const PR=wo,VR="2.110.2";let Wr="",Lc;if(typeof Deno<"u"){var kd;Wr="deno",Lc=(kd=Deno.version)===null||kd===void 0?void 0:kd.deno}else if(typeof document<"u")Wr="web";else if(typeof navigator<"u"&&navigator.product==="ReactNative")Wr="react-native";else{var Rd;Wr="node",Lc=typeof process<"u"?(Rd=process.version)===null||Rd===void 0?void 0:Rd.replace(/^v/,""):void 0}const Bw=[`runtime=${Wr}`];Lc&&Bw.push(`runtime-version=${Lc}`);const HR={"X-Client-Info":`supabase-js/${VR}; ${Bw.join("; ")}`},$R={headers:HR},qR={schema:"public"},FR={autoRefreshToken:!0,persistSession:!0,detectSessionInUrl:!0,flowType:"implicit"},IR={},GR={enabled:!1,respectSamplingDecision:!0};function KR(n,e,i,a){function l(c){return c instanceof i?c:new i(function(u){u(c)})}return new(i||(i=Promise))(function(c,u){function d(y){try{p(a.next(y))}catch(v){u(v)}}function m(y){try{p(a.throw(y))}catch(v){u(v)}}function p(y){y.done?c(y.value):l(y.value).then(d,m)}p((a=a.apply(n,[])).next())})}let Cd=null;const YR="@opentelemetry/api";function XR(){return Cd===null&&(Cd=import(YR).catch(()=>null)),Cd}function JR(){return KR(this,void 0,void 0,function*(){try{const n=yield XR();if(!n||!n.propagation||!n.context)return null;const e={};n.propagation.inject(n.context.active(),e);const i=e.traceparent;return i?{traceparent:i,tracestate:e.tracestate,baggage:e.baggage}:null}catch{return null}})}function QR(n){if(!n||typeof n!="string")return null;const e=n.split("-");if(e.length!==4)return null;const[i,a,l,c]=e;if(i.length!==2||a.length!==32||l.length!==16||c.length!==2)return null;const u=/^[0-9a-f]+$/i;return!u.test(i)||!u.test(a)||!u.test(l)||!u.test(c)||a==="00000000000000000000000000000000"||l==="0000000000000000"?null:{version:i,traceId:a,parentId:l,traceFlags:c,isSampled:(parseInt(c,16)&1)===1}}function ZR(n,e){if(!n||!e||e.length===0)return!1;let i;if(n instanceof URL)i=n;else try{i=new URL(n)}catch{return!1}for(const a of e)try{if(typeof a=="string"){if(WR(i.hostname,a))return!0}else if(a instanceof RegExp){if(a.test(i.hostname))return!0}else if(typeof a=="function"&&a(i))return!0}catch{continue}return!1}function WR(n,e){if(e===n)return!0;if(e.startsWith("*.")){const i=e.slice(2);if(n.endsWith(i)&&(n===i||n.endsWith("."+i)))return!0}return!1}function eC(n){const e=[];try{const i=new URL(n);e.push(i.hostname)}catch{}return e.push("*.supabase.co","*.supabase.in"),e.push("localhost","127.0.0.1","[::1]"),e}function _o(n){"@babel/helpers - typeof";return _o=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_o(n)}function tC(n,e){if(_o(n)!="object"||!n)return n;var i=n[Symbol.toPrimitive];if(i!==void 0){var a=i.call(n,e);if(_o(a)!="object")return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(n)}function nC(n){var e=tC(n,"string");return _o(e)=="symbol"?e:e+""}function sC(n,e,i){return(e=nC(e))in n?Object.defineProperty(n,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):n[e]=i,n}function tv(n,e){var i=Object.keys(n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(n);e&&(a=a.filter(function(l){return Object.getOwnPropertyDescriptor(n,l).enumerable})),i.push.apply(i,a)}return i}function lt(n){for(var e=1;en?(...e)=>n(...e):(...e)=>fetch(...e),aC=()=>Headers,rC=(n,e,i,a,l)=>{const c=iC(a),u=aC(),d=(l==null?void 0:l.enabled)===!0,m=(l==null?void 0:l.respectSamplingDecision)!==!1,p=d?eC(e):null;return async(y,v)=>{var x;const _=(x=await i())!==null&&x!==void 0?x:n;let S=new u(v==null?void 0:v.headers);if(S.has("apikey")||S.set("apikey",n),S.has("Authorization")||S.set("Authorization",`Bearer ${_}`),p){const T=await oC(y,p,m);T&&(T.traceparent&&!S.has("traceparent")&&S.set("traceparent",T.traceparent),T.tracestate&&!S.has("tracestate")&&S.set("tracestate",T.tracestate),T.baggage&&!S.has("baggage")&&S.set("baggage",T.baggage))}return c(y,lt(lt({},v),{},{headers:S}))}};async function oC(n,e,i){if(!ZR(typeof n=="string"||n instanceof URL?n:n.url,e))return null;const a=await JR();if(!a||!a.traceparent)return null;if(i){const l=QR(a.traceparent);if(l&&!l.isSampled)return null}return a}function nv(n){return typeof n=="boolean"?{enabled:n}:n}function lC(n){return n.endsWith("/")?n:n+"/"}function cC(n,e){var i,a,l,c,u,d;const{db:m,auth:p,realtime:y,global:v}=n,{db:x,auth:_,realtime:S,global:T}=e,k=nv(n.tracePropagation),R=nv(e.tracePropagation),M={db:lt(lt({},x),m),auth:lt(lt({},_),p),realtime:lt(lt({},S),y),storage:{},global:lt(lt(lt({},T),v),{},{headers:lt(lt({},(i=T==null?void 0:T.headers)!==null&&i!==void 0?i:{}),(a=v==null?void 0:v.headers)!==null&&a!==void 0?a:{})}),tracePropagation:{enabled:(l=(c=k==null?void 0:k.enabled)!==null&&c!==void 0?c:R==null?void 0:R.enabled)!==null&&l!==void 0?l:!1,respectSamplingDecision:(u=(d=k==null?void 0:k.respectSamplingDecision)!==null&&d!==void 0?d:R==null?void 0:R.respectSamplingDecision)!==null&&u!==void 0?u:!0},accessToken:async()=>""};return n.accessToken?M.accessToken=n.accessToken:delete M.accessToken,M}function uC(n){const e=n==null?void 0:n.trim();if(!e)throw new Error("supabaseUrl is required.");if(!e.match(/^https?:\/\//i))throw new Error("Invalid supabaseUrl: Must be a valid HTTP or HTTPS URL.");try{return new URL(lC(e))}catch{throw Error("Invalid supabaseUrl: Provided URL is malformed.")}}var hC=class extends PR{constructor(n){super(n)}},dC=class{constructor(n,e,i){var a,l;this.supabaseUrl=n,this.supabaseKey=e;const c=uC(n);if(!e)throw new Error("supabaseKey is required.");this.realtimeUrl=new URL("realtime/v1",c),this.realtimeUrl.protocol=this.realtimeUrl.protocol.replace("http","ws"),this.authUrl=new URL("auth/v1",c),this.storageUrl=new URL("storage/v1",c),this.functionsUrl=new URL("functions/v1",c);const u=`sb-${c.hostname.split(".")[0]}-auth-token`,d={db:qR,realtime:IR,auth:lt(lt({},FR),{},{storageKey:u}),global:$R,tracePropagation:GR},m=cC(i??{},d);if(this.settings=m,this.storageKey=(a=m.auth.storageKey)!==null&&a!==void 0?a:"",this.headers=(l=m.global.headers)!==null&&l!==void 0?l:{},m.accessToken)this.accessToken=m.accessToken,this.auth=new Proxy({},{get:(y,v)=>{throw new Error(`@supabase/supabase-js: Supabase Client is configured with the accessToken option, accessing supabase.auth.${String(v)} is not possible`)}});else{var p;this.auth=this._initSupabaseAuthClient((p=m.auth)!==null&&p!==void 0?p:{},this.headers,m.global.fetch)}this.fetch=rC(e,n,this._getAccessToken.bind(this),m.global.fetch,m.tracePropagation),this.realtime=this._initRealtimeClient(lt({headers:this.headers,accessToken:this._getAccessToken.bind(this),fetch:this.fetch},m.realtime)),this.accessToken&&Promise.resolve(this.accessToken()).then(y=>this.realtime.setAuth(y)).catch(y=>console.warn("Failed to set initial Realtime auth token:",y)),this.rest=new wN(new URL("rest/v1",c).href,{headers:this.headers,schema:m.db.schema,fetch:this.fetch,timeout:m.db.timeout,urlLengthLimit:m.db.urlLengthLimit}),this.storage=new Pk(this.storageUrl.href,this.headers,this.fetch,i==null?void 0:i.storage),m.accessToken||this._listenForAuthEvents()}get functions(){return new dN(this.functionsUrl.href,{headers:this.headers,customFetch:this.fetch})}from(n){return this.rest.from(n)}schema(n){return this.rest.schema(n)}rpc(n,e={},i={head:!1,get:!1,count:void 0}){return this.rest.rpc(n,e,i)}channel(n,e={config:{}}){return this.realtime.channel(n,e)}getChannels(){return this.realtime.getChannels()}removeChannel(n){return this.realtime.removeChannel(n)}removeAllChannels(){return this.realtime.removeAllChannels()}async _getAccessToken(){var n=this,e,i;if(n.accessToken)return await n.accessToken();const{data:a}=await n.auth.getSession();return(e=(i=a.session)===null||i===void 0?void 0:i.access_token)!==null&&e!==void 0?e:n.supabaseKey}_initSupabaseAuthClient({autoRefreshToken:n,persistSession:e,detectSessionInUrl:i,storage:a,userStorage:l,storageKey:c,flowType:u,lock:d,debug:m,throwOnError:p,experimental:y,lockAcquireTimeout:v,skipAutoInitialize:x},_,S){const T={Authorization:`Bearer ${this.supabaseKey}`,apikey:`${this.supabaseKey}`};return new hC({url:this.authUrl.href,headers:lt(lt({},T),_),storageKey:c,autoRefreshToken:n,persistSession:e,detectSessionInUrl:i,storage:a,userStorage:l,flowType:u,lock:d,debug:m,throwOnError:p,experimental:y,fetch:S,lockAcquireTimeout:v,skipAutoInitialize:x,hasCustomAuthorizationHeader:Object.keys(this.headers).some(k=>k.toLowerCase()==="authorization")})}_initRealtimeClient(n){return new ck(this.realtimeUrl.href,lt(lt({},n),{},{params:lt(lt({},{apikey:this.supabaseKey}),n==null?void 0:n.params)}))}_listenForAuthEvents(){return this.auth.onAuthStateChange((n,e)=>{this._handleTokenChanged(n,"CLIENT",e==null?void 0:e.access_token)})}_handleTokenChanged(n,e,i){(n==="TOKEN_REFRESHED"||n==="SIGNED_IN")&&this.changedAccessToken!==i?(this.changedAccessToken=i,this.realtime.setAuth(i)):n==="SIGNED_OUT"&&(this.realtime.setAuth(),e=="STORAGE"&&this.auth.signOut(),this.changedAccessToken=void 0)}};const fC=(n,e,i)=>new dC(n,e,i);function mC(){if(typeof window<"u")return!1;const n=globalThis.process;if(!n)return!1;const e=n.version;if(e==null)return!1;const i=e.match(/^v(\d+)\./);return i?parseInt(i[1],10)<=20:!1}mC()&&console.warn("⚠️ Node.js 20 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 22 or later. For more information, visit: https://github.com/orgs/supabase/discussions/45715");const pC="https://dbit.digitalcompass.agency",Uw="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE",oo=!!Uw,ut=oo?fC(pC,Uw,{auth:{persistSession:!0,autoRefreshToken:!0,detectSessionInUrl:!0}}):null;function Lw(){return new URL("/cruce-cuentas/",window.location.origin).toString()}async function gC(){if(typeof window>"u"||typeof fetch>"u")return;const n=Lw(),e=new AbortController,i=window.setTimeout(()=>e.abort(),8e3);try{await(await fetch(n,{method:"GET",cache:"reload",credentials:"same-origin",redirect:"follow",headers:{Accept:"text/html,application/xhtml+xml"},signal:e.signal})).text()}catch(a){console.warn("No se pudo refrescar preventivamente la entrada de la app:",a)}finally{window.clearTimeout(i)}}const yC=180,bC=8e3;async function So(n=yC){if(!ut)return null;const{data:e,error:i}=await ut.auth.getSession();if(i)throw i;let a=e.session;if(!a)throw new Error("Tu sesión expiró. Inicia sesión nuevamente antes de continuar.");const l=Number(a.expires_at||0)*1e3;if(!l||l-Date.now()<=n*1e3){const u=await ut.auth.refreshSession();if(u.error)throw u.error;if(a=u.data.session,!a)throw new Error("Tu sesión expiró. Inicia sesión nuevamente antes de continuar.")}return a}async function sv(n){if(typeof window>"u"||typeof fetch>"u")return;if(typeof navigator<"u"&&navigator.onLine===!1)throw new Error("No hay conexión a Internet. Verifica tu conexión e intenta nuevamente.");let e;try{e=new URL(n,window.location.origin)}catch{return}if(e.origin===window.location.origin)return;const i=new URL("/favicon.ico",e.origin);i.searchParams.set("_glm_resume",String(Date.now()));const a=new AbortController,l=window.setTimeout(()=>a.abort(),bC);try{await fetch(i.toString(),{method:"GET",mode:"no-cors",cache:"no-store",credentials:"omit",signal:a.signal})}catch(c){if(typeof navigator<"u"&&navigator.onLine===!1)throw new Error("No hay conexión a Internet. Verifica tu conexión e intenta nuevamente.");console.warn("No se pudo precalentar la conexión con n8n:",c)}finally{window.clearTimeout(l)}}function iv(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`glm-${Date.now()}-${Math.random().toString(36).slice(2,12)}`}function av(n,e){try{const i=new URL(n,window.location.origin);return i.searchParams.set("client_request_id",e),i.searchParams.set("_ts",String(Date.now())),i.toString()}catch{return n}}const vC="https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-bamboo-correccion",Od=["Nombre mal escrito en BambooHR","Apodo o nombre de uso","Nombre incompleto / nombres adicionales","Otro"];function xC(n){try{return n?JSON.parse(n):null}catch{return null}}function zw({row:n,country:e,periodRange:i,operatorName:a,operatorEmail:l,executionId:c,reportUrl:u,onClose:d,onSuccess:m,onShowToast:p}){const y=n.bestBambooCandidate,[v,x]=D.useState((y==null?void 0:y.employeeName)||""),[_,S]=D.useState((y==null?void 0:y.employeeNumber)||""),[T,k]=D.useState(Od[0]),[R,M]=D.useState(""),[N,P]=D.useState(!1),[G,X]=D.useState(!1);D.useEffect(()=>{x((y==null?void 0:y.employeeName)||""),S((y==null?void 0:y.employeeNumber)||""),k(Od[0]),M(""),P(!1)},[n.id,y==null?void 0:y.employeeName,y==null?void 0:y.employeeNumber]);const q=D.useMemo(()=>e.code==="TT"?"Laurele Nicome-Jack":e.code==="PA"?"Delarys Peñalba":e.code==="SV"?"Carlos Antonio Malta Méndez":e.code==="HN"?"Melody Chang Blandin":e.code==="PR"?"Noralmy Laureano":"haguirre@gomezleemarketing.com",[e.code]),Y=D.useMemo(()=>Array.from(new Set([n.employee,n.bankNameFile,n.bankAccountHolder].map(J=>String(J||"").trim()).filter(Boolean))),[n.employee,n.bankNameFile,n.bankAccountHolder]),se=async()=>{var J;if(!v.trim()){p("Escribe el nombre correcto del empleado en BambooHR.","error");return}if(!N){p("Confirma que se trata de la misma persona antes de enviar el caso.","error");return}if(!ut){p("Supabase no está configurado en esta aplicación.","error");return}X(!0);try{const he=await So(300),fe=he==null?void 0:he.access_token;if(!fe)throw new Error("Tu sesión expiró. Inicia sesión nuevamente antes de reportar el caso.");const Ae={country:e.code,country_name:e.name,source_name:n.employee,source_names:Y,bank_name_file:n.bankNameFile||"",bank_account_holder:n.bankAccountHolder||"",bank_account:n.account||"",bank_amount:n.amountBank,currency:e.currency,bamboo_name:v.trim(),bamboo_employee_number:_.trim(),reason:T,comment:R.trim(),confirmed_same_person:!0,execution_id:c||"",report_url:u||"",period_label:i.label,period_start:i.start,period_end:i.end,requested_by_name:a,requested_by_email:l},ve=new FormData;ve.append("payload",JSON.stringify(Ae)),ve.append("access_token",fe);const Ce=await fetch(vC,{method:"POST",body:ve}),L=await Ce.text(),K=xC(L);if(!Ce.ok||(K==null?void 0:K.ok)===!1){const Z=(K==null?void 0:K.message)||(K==null?void 0:K.error)||((J=K==null?void 0:K.errors)==null?void 0:J[0])||L||"No se pudo enviar el caso a RRHH.";throw new Error(String(Z))}m(n.id),p(`Caso enviado a RRHH de ${e.name}. La equivalencia quedó registrada para futuros cruces.`,"success"),d()}catch(he){const fe=he instanceof Error?he.message:"No se pudo enviar el caso a RRHH.";p(fe,"error")}finally{X(!1)}};return g.jsxs("div",{className:"fixed inset-0 z-[90] flex items-center justify-center px-4 py-6",children:[g.jsx("button",{type:"button",className:"absolute inset-0 bg-black/45",onClick:G?void 0:d,"aria-label":"Cerrar"}),g.jsxs("div",{className:"relative w-full max-w-2xl bg-white border border-[#D0D0D0] shadow-2xl max-h-[92vh] overflow-y-auto",children:[g.jsx("div",{className:"h-1.5 bg-[#6CC24A]"}),g.jsxs("div",{className:"px-6 py-5 border-b border-neutral-200 flex items-start justify-between gap-4",children:[g.jsxs("div",{children:[g.jsx("p",{className:"text-[10px] uppercase tracking-[0.18em] font-black text-[#6B8FA3]",children:"Banco sin BambooHR"}),g.jsx("h2",{className:"text-xl font-black text-[#4F758B] mt-1",children:"Reportar corrección de identidad a RRHH"}),g.jsx("p",{className:"text-xs text-neutral-500 mt-2 leading-relaxed",children:"Esta validación crea una equivalencia permanente para que el mismo falso positivo no vuelva a aparecer mientras RRHH corrige BambooHR."})]}),g.jsx("button",{type:"button",onClick:d,disabled:G,className:"p-2 text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100 disabled:opacity-40","aria-label":"Cerrar modal",children:g.jsx(Ka,{className:"w-5 h-5"})})]}),g.jsxs("div",{className:"px-6 py-5 space-y-5",children:[g.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3 bg-[#F5F5F5] border border-neutral-200 p-4",children:[g.jsxs("div",{children:[g.jsx("p",{className:"text-[9px] uppercase tracking-wider font-black text-[#6B8FA3]",children:"Nombre detectado"}),g.jsx("p",{className:"text-sm font-black text-neutral-800 mt-1",children:n.employee})]}),g.jsxs("div",{children:[g.jsx("p",{className:"text-[9px] uppercase tracking-wider font-black text-[#6B8FA3]",children:"Cuenta bancaria"}),g.jsx("p",{className:"text-sm font-mono font-bold text-neutral-700 mt-1",children:n.account||"—"})]}),g.jsxs("div",{className:"sm:col-span-2",children:[g.jsx("p",{className:"text-[9px] uppercase tracking-wider font-black text-[#6B8FA3]",children:"Se notificará a"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700 mt-1",children:q})]})]}),(y==null?void 0:y.employeeName)&&g.jsxs("div",{className:"border border-[#D6E8F4] bg-[#F7FBFD] p-4 flex items-start gap-3",children:[g.jsx(fo,{className:"w-4 h-4 text-[#4F758B] mt-0.5 flex-shrink-0"}),g.jsxs("div",{className:"text-xs text-neutral-600 leading-relaxed",children:[g.jsx("strong",{className:"text-[#4F758B]",children:"Candidato sugerido por el cruce:"})," ",y.employeeName,y.employeeNumber?` · Employee Number ${y.employeeNumber}`:"",". Verifícalo manualmente antes de confirmar."]})]}),g.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[g.jsxs("label",{className:"sm:col-span-2",children:[g.jsx("span",{className:"block text-[10px] uppercase tracking-wider font-black text-[#4F758B] mb-1.5",children:"Nombre correcto en BambooHR *"}),g.jsx("input",{type:"text",value:v,onChange:J=>x(J.target.value),placeholder:"Ej.: Jonathan Alexander Pérez",className:"w-full border border-[#D0D0D0] px-3 py-2.5 text-sm font-medium focus:outline-none focus:border-[#4F758B]"})]}),g.jsxs("label",{children:[g.jsx("span",{className:"block text-[10px] uppercase tracking-wider font-black text-[#4F758B] mb-1.5",children:"Employee Number"}),g.jsx("input",{type:"text",value:_,onChange:J=>S(J.target.value),placeholder:"Recomendado para mayor seguridad",className:"w-full border border-[#D0D0D0] px-3 py-2.5 text-sm font-medium focus:outline-none focus:border-[#4F758B]"})]}),g.jsxs("label",{children:[g.jsx("span",{className:"block text-[10px] uppercase tracking-wider font-black text-[#4F758B] mb-1.5",children:"Motivo *"}),g.jsx("select",{value:T,onChange:J=>k(J.target.value),className:"w-full border border-[#D0D0D0] px-3 py-2.5 text-sm font-medium focus:outline-none focus:border-[#4F758B] bg-white",children:Od.map(J=>g.jsx("option",{value:J,children:J},J))})]}),g.jsxs("label",{className:"sm:col-span-2",children:[g.jsx("span",{className:"block text-[10px] uppercase tracking-wider font-black text-[#4F758B] mb-1.5",children:"Comentario para RRHH"}),g.jsx("textarea",{value:R,onChange:J=>M(J.target.value),rows:3,placeholder:"Detalle adicional que ayude a RRHH a corregir el registro.",className:"w-full border border-[#D0D0D0] px-3 py-2.5 text-sm font-medium focus:outline-none focus:border-[#4F758B] resize-y"})]})]}),g.jsxs("label",{className:"flex items-start gap-3 border border-[#D0D0D0] p-4 cursor-pointer",children:[g.jsx("input",{type:"checkbox",checked:N,onChange:J=>P(J.target.checked),className:"mt-0.5 accent-[#6CC24A]"}),g.jsxs("span",{className:"text-xs text-neutral-600 leading-relaxed",children:["Confirmo que revisé el caso manualmente y que ",g.jsx("strong",{children:n.employee})," corresponde a la misma persona indicada arriba en BambooHR."]})]})]}),g.jsxs("div",{className:"px-6 py-4 border-t border-neutral-200 bg-neutral-50 flex flex-col-reverse sm:flex-row sm:justify-end gap-2",children:[g.jsx("button",{type:"button",onClick:d,disabled:G,className:"px-4 py-2.5 border border-neutral-300 bg-white text-neutral-600 text-xs font-black uppercase tracking-wider disabled:opacity-40",children:"Cancelar"}),g.jsx("button",{type:"button",onClick:se,disabled:G||!N||!v.trim(),className:"px-5 py-2.5 bg-[#4F758B] text-white text-xs font-black uppercase tracking-wider inline-flex items-center justify-center gap-2 border-l-4 border-[#6CC24A] disabled:bg-neutral-300 disabled:border-neutral-300 disabled:cursor-not-allowed",children:G?g.jsxs(g.Fragment,{children:[g.jsx("span",{className:"w-4 h-4 border-2 border-white/40 border-t-white rounded-full animate-spin"}),"Enviando..."]}):g.jsxs(g.Fragment,{children:[g.jsx(fw,{className:"w-4 h-4"}),"Enviar a RRHH"]})})]})]})]})}const wC="https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-reportar";function _C(n){try{return n?JSON.parse(n):null}catch{return null}}function SC(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`report-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Pw({country:n,operatorName:e,operatorEmail:i,section:a,onShowToast:l}){const[c,u]=D.useState(!1),[d,m]=D.useState(""),[p,y]=D.useState(!1),v=()=>{p||u(!1)},x=async()=>{const _=d.trim();if(!_){l("Escribe una descripción del reporte.","error");return}if(!ut){l("Supabase no está configurado en esta aplicación.","error");return}y(!0);try{const S=await So(300),T=S==null?void 0:S.access_token;if(!T)throw new Error("Tu sesión expiró. Inicia sesión nuevamente antes de enviar el reporte.");const k={message:_.slice(0,5e3),userName:e,userEmail:i,country:n.code,countryName:n.name,section:a,submittedAt:new Date().toISOString(),pageUrl:window.location.href,appSessionId:SC()},R=new FormData;R.append("payload",JSON.stringify(k)),R.append("access_token",T);const M=await fetch(wC,{method:"POST",body:R}),N=await M.text(),P=_C(N);if(!M.ok||(P==null?void 0:P.ok)===!1){const G=(P==null?void 0:P.message)||(P==null?void 0:P.error)||N||"No se pudo enviar el reporte.";throw new Error(String(G))}m(""),u(!1),l("Reporte enviado correctamente.","success")}catch(S){l(S instanceof Error?S.message:"No se pudo enviar el reporte.","error")}finally{y(!1)}};return g.jsxs(g.Fragment,{children:[g.jsxs("button",{type:"button",onClick:()=>u(!0),className:"inline-flex items-center justify-center gap-2 border border-[#4F758B]/25 bg-white text-[#4F758B] h-9 px-2.5 sm:px-3 text-xs font-black hover:border-[#4F758B]/55 hover:bg-[#4F758B]/5 transition-colors shadow-sm",title:"Reportar un error o incidencia","aria-label":"Reportar",children:[g.jsx(Yj,{className:"w-4 h-4"}),g.jsx("span",{className:"hidden sm:inline",children:"Reportar"})]}),c&&g.jsxs("div",{className:"fixed inset-0 z-[90] flex items-center justify-center px-4 py-6",children:[g.jsx("button",{type:"button",className:"absolute inset-0 bg-black/45",onClick:v,"aria-label":"Cerrar reporte"}),g.jsxs("div",{className:"relative w-full max-w-2xl bg-white border border-[#D0D0D0] shadow-2xl",children:[g.jsx("div",{className:"h-1.5 bg-[#6CC24A]"}),g.jsxs("div",{className:"px-6 py-5 border-b border-neutral-200 flex items-center justify-between gap-4",children:[g.jsx("h2",{className:"text-xl font-black text-[#4F758B]",children:"Reporte"}),g.jsx("button",{type:"button",onClick:v,disabled:p,className:"p-2 text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100 disabled:opacity-40","aria-label":"Cerrar modal",children:g.jsx(Ka,{className:"w-5 h-5"})})]}),g.jsxs("div",{className:"px-6 py-5",children:[g.jsxs("label",{className:"block",children:[g.jsx("span",{className:"block text-[10px] uppercase tracking-wider font-black text-[#4F758B] mb-1.5",children:"Descripción del Reporte *"}),g.jsx("textarea",{value:d,onChange:_=>m(_.target.value.slice(0,5e3)),rows:7,autoFocus:!0,disabled:p,placeholder:"Escribe aquí el error, incidencia o mejora que deseas reportar...",className:"w-full resize-y min-h-[150px] border border-[#D0D0D0] bg-white px-3.5 py-3 text-sm text-neutral-700 placeholder-neutral-400 focus:outline-none focus:border-[#4F758B] disabled:bg-neutral-50"})]}),g.jsxs("div",{className:"mt-1.5 text-right text-[10px] text-neutral-400",children:[d.length,"/5000"]})]}),g.jsxs("div",{className:"px-6 py-4 border-t border-neutral-200 bg-neutral-50 flex items-center justify-end gap-3",children:[g.jsx("button",{type:"button",onClick:v,disabled:p,className:"border border-neutral-300 bg-white text-neutral-600 px-4 py-2.5 text-xs font-bold hover:bg-neutral-100 disabled:opacity-50",children:"Cancelar"}),g.jsxs("button",{type:"button",onClick:()=>void x(),disabled:p||!d.trim(),className:"bg-[#4F758B] hover:bg-[#3F6174] text-white px-4 py-2.5 text-xs font-black inline-flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed",children:[p?g.jsx($a,{className:"w-4 h-4 animate-spin"}):g.jsx(fw,{className:"w-4 h-4"}),g.jsx("span",{children:p?"Enviando...":"Enviar reporte"})]})]})]})]})]})}const Vw=[{value:1,label:"Enero"},{value:2,label:"Febrero"},{value:3,label:"Marzo"},{value:4,label:"Abril"},{value:5,label:"Mayo"},{value:6,label:"Junio"},{value:7,label:"Julio"},{value:8,label:"Agosto"},{value:9,label:"Septiembre"},{value:10,label:"Octubre"},{value:11,label:"Noviembre"},{value:12,label:"Diciembre"}],rv=[{value:"quincena_15",label:"Quincena 15",description:"Del día 1 al 15 del mes."},{value:"quincena_30",label:"Quincena 30 / fin de mes",description:"Del día 16 al último día del mes."}],TC="https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-analizar-nomina";function EC(n){return n==="TT"?"https://agenteit.digitalcompass.agency/webhook/nominatt-bamboo-test":n==="PA"?"https://agenteit.digitalcompass.agency/webhook/nominapa-bamboo-test":n==="SV"?"https://agenteit.digitalcompass.agency/webhook/nominasv-bamboo-test":n==="HN"?"https://agenteit.digitalcompass.agency/webhook/nominahn-bamboo-test":n==="PR"?"https://agenteit.digitalcompass.agency/webhook/nominapr-bamboo-test":"https://agenteit.digitalcompass.agency/webhook/nominagt-bamboo-test"}function AC(){return"https://agenteit.digitalcompass.agency/webhook/bono14gt-bamboo-test"}function jC(){const n=new Date().getFullYear(),e=n-5,i=n+10;return Array.from({length:i-e+1},(a,l)=>e+l)}function NC(){const n=new Date,e=n.getDate();let i=n.getFullYear(),a=n.getMonth()+1,l="quincena_15";return e<=15&&(a-=1,l="quincena_30",a===0&&(a=12,i-=1)),{year:i,month:a,periodType:l}}function zc(n){return n<1024*1024?`${(n/1024).toFixed(1)} KB`:`${(n/(1024*1024)).toFixed(2)} MB`}function Yr(n){const e=n.name.toLowerCase();return e.endsWith(".xlsx")||e.endsWith(".xls")}function Dd(n){return n.name.toLowerCase().endsWith(".csv")}function ov(n){return n.name.toLowerCase().endsWith(".pdf")}function kC(n){return Array.from(n).map(e=>({name:e.name,size:zc(e.size),type:"payroll",rawFile:e}))}function Md(n){return Array.from(n).map(e=>({name:e.name,size:zc(e.size),type:"bank",rawFile:e}))}function Ha(n,e,i){return`${n}-${String(e).padStart(2,"0")}-${String(i).padStart(2,"0")}`}function lv(n){const e=/^(\d{4})-(\d{2})-(\d{2})$/.exec(n);return e?`${e[3]}-${e[2]}-${e[1]}`:n}function cv(n,e,i){var c;const a=new Date(n,e,0).getDate(),l=((c=Vw.find(u=>u.value===e))==null?void 0:c.label)??"Mes";return i==="quincena_15"?{start:Ha(n,e,1),end:Ha(n,e,15),label:`${l} ${n} · Quincena 15`}:{start:Ha(n,e,16),end:Ha(n,e,a),label:`${l} ${n} · Quincena 30 / fin de mes`}}function RC(n){const e=n-1;return{start:Ha(e,7,1),end:Ha(n,6,30),label:`Bono 14 ${n} · Julio ${e} a junio ${n}`}}function Bd(n,e,i){if(n==null||Number.isNaN(n))return"—";const a=i==="USD"||i==="GTQ"||i==="TTD"?i:e.currency,l=a==="USD"?"en-US":e.locale;return new Intl.NumberFormat(l,{style:"currency",currency:a,minimumFractionDigits:2}).format(n)}function Xn(n,e=0){const i=Number(n);return Number.isFinite(i)?i:e}function Tt(n){return n.normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase()}function CC(n,e){const i=Tt(String(n??e??""));return i.includes("coincid")?"Coincidencia":i.includes("resuelto")?"Resuelto":i.includes("no encontrado")?"No encontrado":i.includes("pendiente")?"Pendiente revisión":i.includes("riesgo")||i.includes("discrep")||i.includes("mal digitada")?"Riesgo":e==="coincidencia"?"Coincidencia":e==="posible_cuenta_mal_digitada"||e==="discrepancia"?"Riesgo":"Pendiente revisión"}function lc(n,e){for(const i of e){if(typeof n[i]=="number")return n[i];if(typeof n[i]=="string"&&n[i]!==""){const a=n[i].replace(/[Q,$\s]/g,"").replace(/,/g,""),l=Number(a);if(Number.isFinite(l))return l}}return null}function uv(n){return Array.isArray(n)?n.map((e,i)=>{const a=e,l=String(a.category??a.categoria??a.tipo??a.source??a.fuente??""),c=lc(a,["amountPayroll","monto_nomina","payroll_amount","amount_payroll","montoNomina"]),u=lc(a,["amountBank","monto_banco","bank_amount","amount_bank","montoBanco"]),d=lc(a,["difference","diferencia","diff"]);return{id:String(a.id??a.employeeNumber??a.employee_number??a.account??a.cuenta??`row-${i+1}`),employee:String(a.employee??a.empleado??a.name??a.nombre??a.employee_name??"Sin nombre"),employeeNumber:String(a.employeeNumber??a.employee_number??a.codigo??""),account:a.account||a.cuenta||a.bank_account?String(a.account??a.cuenta??a.bank_account):void 0,currency:String(a.currency??a.moneda??"").toUpperCase()||void 0,amountPayroll:c,amountBank:u,difference:d??(c!==null&&u!==null?c-u:null),status:CC(a.status??a.estado,l),category:l,observation:String(a.observation??a.observacion??a.note??a.nota??a.comentario??""),source:a.source??a.fuente??l,bankNameFile:String(a.bank_name_file??a.bankNameFile??""),bankAccountHolder:String(a.bank_account_holder??a.bankAccountHolder??""),bestBambooCandidate:a.best_bamboo_candidate&&typeof a.best_bamboo_candidate=="object"?{employeeNumber:String(a.best_bamboo_candidate.employee_number??""),employeeName:String(a.best_bamboo_candidate.employee_name??""),score:lc(a.best_bamboo_candidate,["score"])}:null,ambiguousBambooMatch:!!a.ambiguous_bamboo_match}}):[]}function hv(n){const i=(Array.isArray(n)?n[0]:n)??{},a=i.originalResponse??i.original_response??i.response??i,l=a.summary??a.resumen??i.summary??i.resumen??{},c=uv(a.rows??i.rows??a.resultados??i.resultados??[]),u=uv(a.bankWithoutBamboo??i.bankWithoutBamboo??a.banco_sin_bamboo_rows??i.banco_sin_bamboo_rows??[]).map(N=>({...N,category:N.category||"banco_sin_bamboo",source:"banco_sin_bamboo",status:N.status==="Coincidencia"?"Pendiente revisión":N.status})),d=new Map;[...c,...u].forEach((N,P)=>{const G=N.id||`${N.source??N.category??"row"}-${P}`;d.set(G,N)});const m=Array.from(d.values()),p=Xn(l.matches??l.coincidencias,c.filter(N=>N.status==="Coincidencia").length),y=Xn(l.discrepancies??l.discrepancias,c.filter(N=>{const P=Tt(String(N.category??N.source??""));return P.includes("discrepancia")||P.includes("posible_cuenta_mal_digitada")}).length),v=Xn(l.bankWithoutPayroll??l.bancoSinNomina??l.banco_sin_nomina,c.filter(N=>Ua(N,"banco_sin_nomina")).length),x=Xn(l.bankWithoutBamboo??l.bancoSinBamboo??l.banco_sin_bamboo,u.length),_=Xn(l.payrollWithoutAccount??l.nominaSinCuenta??l.nomina_sin_cuenta),S=Xn(l.nameDifferences??l.diferenciasNombreBanco??l.diferencias_nombre_banco,c.filter(N=>Tt(String(N.category??"")).includes("diferencia_nombre_banco")).length),T=Xn(l.possibleWrongAccounts??l.posiblesCuentasMalDigitadas??l.posibles_cuentas_mal_digitadas,c.filter(N=>Tt(String(N.category??"")).includes("posible_cuenta_mal_digitada")).length),k=y+v+x+_+S,R=a.metadata??i.metadata??{},M=String(R.period_type??R.periodType??"").toLowerCase();return{ok:!!(a.ok??i.ok??!0),reportKind:M==="bono14"?"bono14":"nomina",executionId:a.executionId||a.execution_id||i.executionId||i.execution_id?String(a.executionId??a.execution_id??i.executionId??i.execution_id):void 0,reportUrl:a.reportUrl||a.report_url||i.reportUrl||i.report_url||i.google_sheet_url?String(a.reportUrl??a.report_url??i.reportUrl??i.report_url??i.google_sheet_url):void 0,summary:{matches:p,discrepancies:y,bankWithoutPayroll:v,bankWithoutBamboo:x,payrollWithoutAccount:_,nameDifferences:S,possibleWrongAccounts:T,totalPending:k,totalRows:m.length,totalPayroll:Xn(l.totalNomina??l.total_nomina,void 0),totalBank:Xn(l.totalBanco??l.total_banco,void 0),totalDifference:Xn(l.diferenciaTotal??l.diferencia_total,void 0)},rows:m,message:a.message||i.message?String(a.message??i.message):void 0}}function OC(n){return n==="Coincidencia"?"bg-emerald-50 text-emerald-800 border-emerald-200":n==="Resuelto"?"bg-blue-50 text-blue-800 border-blue-200":n==="No encontrado"?"bg-amber-50 text-amber-800 border-amber-200":n==="Pendiente revisión"?"bg-neutral-100 text-neutral-700 border-neutral-300":"bg-red-50 text-[#ba1a1a] border-red-200"}function dv(n){const e=Tt(String(n.category??n.source??"")),i=Tt(n.observation??"");return n.status==="Coincidencia"||e.includes("coincidencia")?90:e.includes("posible_cuenta_mal_digitada")||i.includes("mal digitada")?1:e.includes("discrepancia")||n.status==="Riesgo"?2:e.includes("banco_sin_bamboo")?3:e.includes("banco_sin_nomina")?4:e.includes("diferencia_nombre_banco")?5:e.includes("nomina_sin_cuenta")?6:n.status==="Pendiente revisión"?7:n.status==="No encontrado"?10:20}function DC(n){return[...n].sort((e,i)=>{const a=dv(e)-dv(i);return a!==0?a:e.employee.localeCompare(i.employee,"es")})}function MC(n){const e=Tt(String(n.category??n.source??""));return e.includes("discrepancia")||e.includes("posible_cuenta_mal_digitada")}function Ua(n,e){return n.source===e||Tt(String(n.category??"")).includes(e)}function BC(n,e="nomina"){const i=Tt(String(n??""));return i?i.includes("posible_cuenta_mal_digitada")?"Posible cuenta mal digitada":i.includes("banco_sin_bamboo")?"Banco sin Bamboo":i.includes("banco_sin_nomina")?e==="bono14"?"Banco sin Bono 14":"Banco sin nómina":i.includes("diferencia_nombre_banco")?"Diferencia nombre banco":i.includes("nomina_sin_cuenta")?e==="bono14"?"Bono 14 sin cuenta":"Nómina sin cuenta":i.includes("discrepancia")?"Discrepancia":i.includes("coincidencia")?"Coincidencia":String(n).replace(/_/g," "):"—"}function fv(n){const e=n instanceof Error?n.message:"";return e.includes("planillas del banco repetidas")||e.toLowerCase().includes("sesión expiró")||e.toLowerCase().includes("no hay conexión a internet")?e:"No se pudo procesar el cruce. Verifica los archivos e intenta nuevamente."}function UC(n){try{return new TextDecoder("windows-1252").decode(n)}catch{return new TextDecoder("utf-8").decode(n)}}function mv(n,e){let i=0,a=!1;for(let l=0;lmv(n,a)>mv(n,i)?a:i)}function pv(n,e=Hw(n)){const i=[];let a="",l=!1;for(let c=0;cc.replace(/^\uFEFF/,"").trim())}function LC(n){const e=String(n??"").replace(/\D/g,"");return/^\d{1,20}$/.test(e)?e:null}function zC(n){const e=n.split(/\r?\n/).slice(0,120);for(const i of e.slice(0,25)){const l=Tt(i).match(/(?:consulta\s+(?:del\s+)?)?detalle\s+(?:del\s+)?envio\s+(\d{1,20})/);if(l!=null&&l[1])return l[1]}for(let i=0;iTt(m).trim()).findIndex(m=>m==="numero de envio"||m.includes("numero de envio"));if(!(d<0))for(let m=i+1;mi.length>1).map(([i,a])=>({shipmentNumber:i,fileNames:a}))}const VC={1:["enero","january","jan"],2:["febrero","february","feb"],3:["marzo","march","mar"],4:["abril","april","apr"],5:["mayo","may"],6:["junio","june","jun"],7:["julio","july","jul"],8:["agosto","august","aug"],9:["septiembre","setiembre","september","sep"],10:["octubre","october","oct"],11:["noviembre","november","nov"],12:["diciembre","december","dec"]};function HC(n){const e=Tt(n).replace(/[_\-.()]+/g," ").replace(/\s+/g," ").trim(),i=e.match(/\b(20\d{2})\b/),a=i?Number(i[1]):void 0;let l;for(const[d,m]of Object.entries(VC))if(m.some(p=>new RegExp(`\\b${p}\\b`,"i").test(e))){l=Number(d);break}const c=e.match(/\b(1[0-2]|[1-9])\s+(1|2)\s+(20\d{2})\b/);!l&&c&&(l=Number(c[1]));let u;return(c==null?void 0:c[2])==="1"?u="quincena_15":(c==null?void 0:c[2])==="2"?u="quincena_30":/\b(?:1q|q1|quincena\s*15|primera\s+quincena)\b/.test(e)?u="quincena_15":/\b(?:2q|q2|quincena\s*30|segunda\s+quincena|fin\s+de\s+mes)\b/.test(e)?u="quincena_30":/\b15\b/.test(e)?u="quincena_15":/\b(?:30|31)\b/.test(e)&&(u="quincena_30"),{year:a,month:l,periodType:u}}function yv(n){const e=NC();try{const i=window.localStorage.getItem(`glm_cruce_period_${n}`);if(!i)return e;const a=JSON.parse(i);if(Number.isInteger(a.year)&&Number.isInteger(a.month)&&a.month>=1&&a.month<=12&&(a.periodType==="quincena_15"||a.periodType==="quincena_30"))return a}catch{}return e}async function $C(n,e){const i=HC(n);try{const a=await fetch(TC,{method:"POST",headers:{"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify({fileName:n,country:e.code,countryName:e.name})});if(!a.ok)return i;const l=await a.json().catch(()=>null),c=(l==null?void 0:l.detected)??(l==null?void 0:l.result)??(l==null?void 0:l.analysis)??l??{},u=String(c.periodType??c.period_type??""),d=Number(c.year)||i.year,m=Number(c.month)||i.month,p=u==="quincena_15"||u==="quincena_30"?u:i.periodType;return{year:d,month:m,periodType:p,confidence:Number.isFinite(Number(c.confidence))?Number(c.confidence):void 0,requiresManualReview:!!(c.requiresManualReview??c.requires_manual_review??!1),source:String(c.source??"gemini")}}catch{return{...i,source:"local_fallback",requiresManualReview:!(Number.isInteger(i.year)&&Number.isInteger(i.month)&&(i.periodType==="quincena_15"||i.periodType==="quincena_30"))}}}function qC({onShowToast:n,uploadedPayroll:e,setUploadedPayroll:i,uploadedPayrollFiles:a,setUploadedPayrollFiles:l,uploadedBankFiles:c,setUploadedBankFiles:u,isCruceExecuted:d,setIsCruceExecuted:m,response:p,setResponse:y,onOpenSidebar:v,operatorName:x,operatorEmail:_,resetToken:S=0,country:T}){const k=D.useMemo(()=>yv(T.code),[T.code]),R=T.code==="PA",M=T.code==="SV",N=T.code==="HN",P=T.code==="PR",G=R||M,X=P?"PDF":"CSV",q=P?".pdf":".csv",[Y,se]=D.useState(!1),[J,he]=D.useState(""),[fe,Ae]=D.useState("todos"),[ve,Ce]=D.useState(k.year),[L,K]=D.useState(k.month),[Z,pe]=D.useState(k.periodType),[ie,E]=D.useState(1),[H,W]=D.useState(""),[Q,oe]=D.useState(""),[re,_e]=D.useState(null),[ke,He]=D.useState([]),[en,jn]=D.useState(""),[Rs,is]=D.useState(null),[te,Be]=D.useState(()=>new Set),Ue=`glm_cruce_period_${T.code}`,xe=D.useRef(null),$e=D.useRef(null),kt=D.useRef(null),xt=D.useRef(null),Et=D.useMemo(()=>jC(),[]),Ht=D.useMemo(()=>cv(ve,L,Z),[ve,L,Z]),Nn=T.code==="GT"&&L===7&&Z==="quincena_15",We=D.useMemo(()=>RC(ve),[ve]),tn=(p==null?void 0:p.reportKind)==="bono14",Gt=tn?We.label:Ht.label,kn=D.useMemo(()=>DC((p==null?void 0:p.rows)??[]),[p==null?void 0:p.rows]),fn=D.useMemo(()=>{const C=Tt(Q.trim());return c.map((ee,ae)=>({file:ee,originalIndex:ae})).filter(({file:ee})=>!C||Tt(ee.name).includes(C))},[c,Q]),Rn=D.useMemo(()=>{const C=Tt(en.trim());return ke.map((ee,ae)=>({file:ee,originalIndex:ae})).filter(({file:ee})=>!C||Tt(ee.name).includes(C))},[ke,en]),Cs=kn.filter(C=>{const ee=Tt(H.trim());return Tt(`${C.employee} ${C.employeeNumber} ${C.account??""} ${C.observation} ${C.category??""} ${C.source??""}`).includes(ee)?fe==="discrepancias"?MC(C):fe==="coincidencias"?C.status==="Coincidencia":fe==="banco_sin_nomina"?Ua(C,"banco_sin_nomina"):fe==="banco_sin_bamboo"?Ua(C,"banco_sin_bamboo"):fe==="diferencia_nombre_banco"?Ua(C,"diferencia_nombre_banco"):fe==="nomina_sin_cuenta"?Ua(C,"nomina_sin_cuenta"):!0:!1}),Os=10,qn=Math.max(1,Math.ceil(Cs.length/Os)),as=Cs.slice((ie-1)*Os,ie*Os);D.useEffect(()=>{ie>qn&&E(qn)},[ie,qn]);const $t=D.useMemo(()=>{var C;return((C=rv.find(ee=>ee.value===Z))==null?void 0:C.description)??""},[Z]);D.useEffect(()=>{const C=yv(T.code);Ce(C.year),K(C.month),pe(C.periodType),E(1),W(""),oe(""),jn(""),_e(null),He([]),Ae("todos"),is(null),Be(new Set)},[T.code]),D.useEffect(()=>{window.localStorage.setItem(Ue,JSON.stringify({year:ve,month:L,periodType:Z}))},[Ue,ve,L,Z]),D.useEffect(()=>{W(""),oe(""),jn(""),_e(null),He([]),Ae("todos"),E(1),he(""),se(!1),is(null),Be(new Set),xe.current&&(xe.current.value=""),$e.current&&($e.current.value=""),kt.current&&(kt.current.value=""),xt.current&&(xt.current.value="")},[S]),D.useEffect(()=>{c.length===0&&Q&&oe("")},[c.length,Q]),D.useEffect(()=>{ke.length===0&&en&&jn("")},[ke.length,en]);const et=()=>{m(!1),y(null),E(1),W(""),Ae("todos")},Lt=async(C,ee=1)=>{const ae=await $C(C.name,T);if(Number.isInteger(ae.year)&&Number.isInteger(ae.month)&&(ae.periodType==="quincena_15"||ae.periodType==="quincena_30")){Ce(ae.year),K(ae.month),pe(ae.periodType);const Rt=cv(ae.year,ae.month,ae.periodType),st=ee>1?`${ee} archivos de nómina cargados.`:"Nómina cargada.";return ae.requiresManualReview?n(`${st} Período sugerido: ${Rt.label}. Confirma los datos antes de ejecutar.`,"info"):n(`${st} Período detectado: ${Rt.label}.`,"success"),!0}return!1},ko=async C=>{i({name:C.name,size:zc(C.size),type:"payroll",rawFile:C}),l([]),et(),await Lt(C)||n("Archivo de nómina cargado con éxito.","success")},Ro=async C=>{const ee=C.filter(Yr);if(ee.length===0){n(`Formato inválido. ${T.name} requiere uno o varios archivos Excel (.xlsx, .xls).`,"error");return}const ae=new Set(a.map(at=>{var it;return`${at.name}|${((it=at.rawFile)==null?void 0:it.size)??at.size}`})),nt=kC(ee).filter(at=>{var it;return!ae.has(`${at.name}|${((it=at.rawFile)==null?void 0:it.size)??at.size}`)}),Rt=[...a,...nt];l(Rt),i(null),et();const st=ee.find(at=>/quincenal/i.test(at.name))||ee[0];await Lt(st,Rt.length)||n(`${nt.length} archivo(s) de nómina de ${T.name} cargado(s) con éxito.`,"success")},ui=C=>{C.preventDefault()},hi=async C=>{C.preventDefault();const ee=Array.from(C.dataTransfer.files);if(ee.length===0)return;if(G){await Ro(ee);return}const ae=ee[0];Yr(ae)?await ko(ae):n("Formato inválido. Por favor carga un archivo Excel (.xlsx, .xls).","error")},Hi=C=>{C.preventDefault();const ae=Array.from(C.dataTransfer.files).filter(P?ov:Dd);if(ae.length===0){n(`Formato inválido. Por favor carga uno o varios archivos ${X} (${q}).`,"error");return}u([...c,...Md(ae)]),et(),n(`${ae.length} archivo(s) del banco cargado(s) con éxito.`,"success")},$i=async C=>{const ee=Array.from(C.target.files||[]);if(ee.length===0)return;if(G){await Ro(ee);return}const ae=ee[0];Yr(ae)?await ko(ae):n("Formato inválido. Por favor carga un archivo Excel (.xlsx, .xls).","error")},rs=C=>{l(a.filter((ee,ae)=>ae!==C)),xe.current&&(xe.current.value=""),et(),n("Archivo de nómina removido.","info")},qi=C=>{const ee=C.target.files;if(!ee||ee.length===0)return;const ae=Array.from(ee).filter(P?ov:Dd);if(ae.length===0){n(`Formato inválido. Por favor carga uno o varios archivos ${X} (${q}).`,"error");return}u([...c,...Md(ae)]),et(),n(`${ae.length} archivo(s) del banco cargado(s) con éxito.`,"success")},di=C=>{u(c.filter((ee,ae)=>ae!==C)),$e.current&&($e.current.value=""),et(),n("Planilla de banco removida.","info")},Xc=()=>{i(null),l([]),u([]),oe(""),xe.current&&(xe.current.value=""),$e.current&&($e.current.value=""),et(),n("Todos los archivos cargados fueron eliminados.","info")},Za=C=>{_e({name:C.name,size:zc(C.size),type:"payroll",rawFile:C}),et(),n("Archivo Excel de Bono 14 cargado con éxito.","success")},Wa=C=>{C.preventDefault();const ee=C.dataTransfer.files[0];if(ee){if(!Yr(ee)){n("Formato inválido. El Bono 14 requiere un archivo Excel (.xlsx, .xls).","error");return}Za(ee)}},fi=C=>{var ae;const ee=(ae=C.target.files)==null?void 0:ae[0];if(ee){if(!Yr(ee)){n("Formato inválido. El Bono 14 requiere un archivo Excel (.xlsx, .xls).","error");return}Za(ee)}},Co=C=>{const ee=C.filter(Dd);if(ee.length===0){n("Formato inválido. Carga uno o varios archivos CSV del Bono 14.","error");return}He([...ke,...Md(ee)]),et(),n(`${ee.length} archivo(s) bancario(s) de Bono 14 cargado(s).`,"success")},Oo=C=>{C.preventDefault(),Co(Array.from(C.dataTransfer.files))},Do=C=>{var ee;(ee=C.target.files)!=null&&ee.length&&Co(Array.from(C.target.files))},Mo=C=>{He(ke.filter((ee,ae)=>ae!==C)),xt.current&&(xt.current.value=""),et(),n("Archivo bancario de Bono 14 removido.","info")},er=async()=>{if(Y)return;if(!ve||!L||!Z){n("Debes seleccionar año, mes y tipo de cruce antes de ejecutar.","error");return}const C=G?a:e?[e]:[];if(C.length===0||C.some(ee=>!ee.rawFile)){n(G?`Debes cargar todos los archivos de nómina de ${T.name} correspondientes al período antes de ejecutar el cruce.`:"Debes cargar la nómina antes de ejecutar el cruce.","error");return}if(c.length===0||c.some(ee=>!ee.rawFile)){n("Debes cargar al menos una planilla del banco antes de ejecutar el cruce.","error");return}se(!0),he("Validando archivos..."),E(1);try{const ee=P?[]:await gv(c);if(ee.length>0){const Le=ee.map(zt=>`Número de envío ${zt.shipmentNumber}: ${zt.fileNames.join(", ")}`).join(` -`);throw new Error(`Hay planillas del banco repetidas. Revisa los archivos cargados antes de continuar. -${Le}`)}const ae=EC(T.code);if(!ae)throw new Error("No se pudo procesar el cruce. El servicio de conciliación no está disponible.");const nt=iv();he("Revalidando sesión..."),await So(300),he("Reactivando conexión segura..."),await sv(ae);const Rt=av(ae,nt),st=C.find(Le=>/quincenal/i.test(Le.name))||C[0],Cn={country:T.code,country_name:T.name,year:ve,month:L,period_type:Z,period_label:Ht.label,period_start:Ht.start,period_end:Ht.end,payroll_file_name:st.name,payroll_file_names:C.map(Le=>Le.name),bank_file_names:c.map(Le=>Le.name),requested_by_name:x,requested_by_email:_,auth_mode:"supabase_google",source_app:"portal-cruce-cuentas-glm",client_request_id:nt};he("Procesando cruce de cuentas...");const at=new FormData;at.append("metadata",JSON.stringify(Cn)),Object.entries(Cn).forEach(([Le,zt])=>{at.append(Le,Array.isArray(zt)?JSON.stringify(zt):String(zt))}),G&&C.forEach((Le,zt)=>{Le.rawFile&&(at.append("payroll_files",Le.rawFile,Le.name),at.append(`payroll_file_${zt+1}`,Le.rawFile,Le.name))}),st.rawFile&&at.append("payroll_file",st.rawFile,st.name),c.forEach((Le,zt)=>{Le.rawFile&&(at.append("bank_files",Le.rawFile,Le.name),at.append(`bank_file_${zt+1}`,Le.rawFile,Le.name))});const it=await fetch(Rt,{method:"POST",body:at,cache:"no-store",credentials:"omit"});he("Generando reporte...");const Ge=(it.headers.get("content-type")??"").includes("application/json")?await it.json():{ok:it.ok,message:await it.text()};if(!it.ok||(Ge==null?void 0:Ge.ok)===!1)throw new Error(typeof(Ge==null?void 0:Ge.message)=="string"?Ge.message:"No se pudo procesar el cruce. Verifica los archivos e intenta nuevamente.");const wt=hv(Ge);wt.reportKind="nomina",y(wt),m(!0),n(wt.message||"Cruce procesado correctamente.","success"),setTimeout(()=>{const Le=document.getElementById("resultados-seccion");Le&&Le.scrollIntoView({behavior:"smooth",block:"start"})},150)}catch(ee){const ae=fv(ee);m(!1),y(null),n(ae,"error")}finally{se(!1),he("")}},tr=async()=>{if(!Y){if(!Nn){n("El cruce de Bono 14 solo está disponible en Guatemala para julio · Quincena 15.","error");return}if(!(re!=null&&re.rawFile)){n("Debes cargar el Excel de Bono 14 antes de generar el reporte.","error");return}if(ke.length===0||ke.some(C=>!C.rawFile)){n("Debes cargar al menos un CSV bancario del Bono 14.","error");return}se(!0),he("Validando archivos de Bono 14..."),E(1);try{const C=await gv(ke);if(C.length>0){const Ge=C.map(wt=>`Número de envío ${wt.shipmentNumber}: ${wt.fileNames.join(", ")}`).join(` -`);throw new Error(`Hay planillas del banco repetidas. Revisa los archivos cargados antes de continuar. -${Ge}`)}const ee=AC(),ae=iv();he("Revalidando sesión..."),await So(300),he("Reactivando conexión segura..."),await sv(ee);const nt=av(ee,ae),Rt={country:"GT",country_name:"Guatemala",year:ve,month:7,period_type:"bono14",report_kind:"bono14",period_label:We.label,period_start:We.start,period_end:We.end,payroll_file_name:re.name,bank_file_names:ke.map(Ge=>Ge.name),requested_by_name:x,requested_by_email:_,auth_mode:"supabase_google",source_app:"portal-cruce-cuentas-glm-bono14",client_request_id:ae},st=new FormData;st.append("metadata",JSON.stringify(Rt)),Object.entries(Rt).forEach(([Ge,wt])=>{st.append(Ge,Array.isArray(wt)?JSON.stringify(wt):String(wt))}),st.append("payroll_file",re.rawFile,re.name),ke.forEach((Ge,wt)=>{Ge.rawFile&&(st.append("bank_files",Ge.rawFile,Ge.name),st.append(`bank_file_${wt+1}`,Ge.rawFile,Ge.name))}),he("Procesando Bono 14...");const Cn=await fetch(nt,{method:"POST",body:st,cache:"no-store",credentials:"omit"});he("Generando reporte independiente de Bono 14...");const it=(Cn.headers.get("content-type")??"").includes("application/json")?await Cn.json():{ok:Cn.ok,message:await Cn.text()};if(!Cn.ok||(it==null?void 0:it.ok)===!1)throw new Error(typeof(it==null?void 0:it.message)=="string"?it.message:"No se pudo procesar el Bono 14. Verifica los archivos e intenta nuevamente.");const Fn=hv(it);Fn.reportKind="bono14",y(Fn),m(!0),n(Fn.message||"Bono 14 procesado correctamente.","success"),setTimeout(()=>{const Ge=document.getElementById("resultados-seccion");Ge&&Ge.scrollIntoView({behavior:"smooth",block:"start"})},150)}catch(C){m(!1),y(null),n(fv(C),"error")}finally{se(!1),he("")}}},Bo=()=>{if(p!=null&&p.reportUrl){window.open(p.reportUrl,"_blank","noopener,noreferrer");return}n("El reporte aún no tiene un enlace disponible.","info")};return g.jsxs("div",{className:"flex-1 flex flex-col min-h-screen bg-neutral-50 text-neutral-800 font-sans",children:[g.jsxs("header",{className:"bg-white border-b-4 border-[#6CC24A] flex justify-between items-center w-full px-4 sm:px-8 h-[84px] sticky top-0 z-40 shadow-sm gap-x-4",children:[g.jsxs("div",{className:"flex items-center gap-2 sm:gap-3 min-w-0",children:[g.jsx("button",{onClick:v,className:"md:hidden p-2 -ml-2 text-neutral-600 hover:text-neutral-800 hover:bg-neutral-100 transition-colors flex-shrink-0","aria-label":"Abrir menú",children:g.jsx(dw,{className:"w-6 h-6"})}),g.jsx("h1",{className:"text-xs sm:text-sm md:text-lg lg:text-2xl font-black text-[#4F758B] tracking-tight uppercase flex items-center gap-1.5 sm:gap-2 min-w-0",children:g.jsxs("span",{className:"truncate",children:["Cruce de Cuentas GLM - ",T.name]})})]}),g.jsxs("div",{className:"flex-shrink-0 flex items-center gap-2",children:[g.jsx(Pw,{country:T,operatorName:x,operatorEmail:_,section:"Cruce de Cuentas",onShowToast:n}),g.jsx("div",{className:"border border-neutral-200 bg-white px-2.5 py-2 shadow-sm","aria-label":`Bandera de ${T.name}`,children:g.jsx("img",{src:T.flag,alt:`Bandera de ${T.name}`,className:"h-5 sm:h-6 w-auto object-contain"})})]})]}),g.jsxs("main",{className:"flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 py-8 flex flex-col gap-8",children:[g.jsxs("section",{className:"bg-white border border-[#D0D0D0] p-5 shadow-sm",children:[g.jsx("div",{className:"flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4 mb-5",children:g.jsxs("div",{className:"flex items-center gap-3",children:[g.jsx("div",{className:"bg-[#4F758B]/10 p-2 rounded-full",children:g.jsx(hw,{className:"w-5 h-5 text-[#4F758B]"})}),g.jsx("div",{className:"pt-0.5",children:g.jsx("h2",{className:"text-sm font-black text-[#4F758B] uppercase tracking-wider leading-none",children:"Datos del cruce"})})]})}),g.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[g.jsxs("label",{className:"flex flex-col gap-1.5",children:[g.jsx("span",{className:"text-[10px] font-black uppercase tracking-wider text-neutral-500",children:"Año"}),g.jsx("select",{value:ve,onChange:C=>{Ce(Number(C.target.value)),et()},className:"border border-[#D0D0D0] bg-white px-3 py-2.5 text-sm font-bold text-neutral-700 focus:outline-none focus:border-[#4F758B]",children:Et.map(C=>g.jsx("option",{value:C,children:C},C))})]}),g.jsxs("label",{className:"flex flex-col gap-1.5",children:[g.jsx("span",{className:"text-[10px] font-black uppercase tracking-wider text-neutral-500",children:"Mes"}),g.jsx("select",{value:L,onChange:C=>{K(Number(C.target.value)),et()},className:"border border-[#D0D0D0] bg-white px-3 py-2.5 text-sm font-bold text-neutral-700 focus:outline-none focus:border-[#4F758B]",children:Vw.map(C=>g.jsx("option",{value:C.value,children:C.label},C.value))})]}),g.jsxs("label",{className:"flex flex-col gap-1.5",children:[g.jsx("span",{className:"text-[10px] font-black uppercase tracking-wider text-neutral-500",children:"Tipo de cruce"}),g.jsx("select",{value:Z,onChange:C=>{pe(C.target.value),et()},className:"border border-[#D0D0D0] bg-white px-3 py-2.5 text-sm font-bold text-neutral-700 focus:outline-none focus:border-[#4F758B]",children:rv.map(C=>g.jsx("option",{value:C.value,children:C.label},C.value))})]})]}),g.jsxs("div",{className:"mt-4 grid grid-cols-1 md:grid-cols-[1fr_auto] gap-3 items-center bg-[#4F758B]/5 border border-[#4F758B]/10 px-4 py-3",children:[g.jsxs("div",{className:"flex items-start gap-2 text-xs text-neutral-600",children:[g.jsx(bj,{className:"w-4 h-4 text-[#4F758B] mt-0.5 flex-shrink-0"}),g.jsxs("div",{children:[g.jsx("span",{className:"font-black text-[#4F758B]",children:"Período calculado:"})," ",lv(Ht.start)," al ",lv(Ht.end),g.jsx("p",{className:"text-[10px] text-neutral-500 mt-0.5",children:$t})]})]}),g.jsx("div",{className:"text-[10px] font-bold text-neutral-500 uppercase tracking-wider",children:Ht.label})]})]}),(G||N||P)&&(e!==null||a.length>0||c.length>0)&&g.jsx("div",{className:"flex justify-end",style:{marginBottom:"-20px"},children:g.jsxs("button",{type:"button",onClick:Xc,className:"inline-flex items-center gap-2 border border-red-100 bg-white px-3 py-2 text-[10px] font-black text-red-600 hover:bg-red-50 transition-colors uppercase tracking-wide shadow-sm","aria-label":"Borrar todos los archivos cargados",title:"Eliminar de una vez todas las nóminas y planillas del banco cargadas",children:[g.jsx(Ea,{className:"w-4 h-4"}),"Borrar todo"]})}),g.jsxs("section",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[g.jsxs("div",{className:"bg-white border border-[#D0D0D0] p-6 flex flex-col justify-between relative shadow-sm hover:shadow-md transition-shadow",children:[g.jsx("div",{className:"absolute top-0 left-0 w-full h-1 bg-[#4F758B]"}),g.jsxs("div",{children:[g.jsxs("div",{className:"flex items-center gap-2.5 mb-4",children:[g.jsx(Oa,{className:"w-5 h-5 text-[#4F758B]"}),g.jsx("h2",{className:"text-sm font-black text-neutral-800 uppercase tracking-wider",children:"1. Carga de Nómina"})]}),g.jsx("input",{type:"file",ref:xe,onChange:$i,accept:".xlsx,.xls",multiple:G,className:"hidden"}),G?a.length>0?g.jsxs("div",{className:"space-y-3",children:[g.jsxs("div",{className:"border border-[#4F758B]/20 bg-[#4F758B]/5 px-4 py-3",children:[g.jsxs("p",{className:"text-[10px] font-black uppercase tracking-wider text-[#4F758B]",children:[a.length," archivo(s) de nómina cargado(s)"]}),g.jsx("p",{className:"text-[10px] text-neutral-500 mt-1",children:R?"Incluye la quincenal y todas las planillas extraordinarias, vacaciones o XIII Mes que correspondan al período.":"Incluye todos los archivos de nómina de El Salvador que correspondan a la quincena seleccionada (General, Karla Elias, Nestlé, Motorola u otros del mismo formato)."})]}),g.jsx("div",{className:"max-h-[260px] overflow-y-auto border border-neutral-200 divide-y divide-neutral-100",children:a.map((C,ee)=>g.jsxs("div",{className:"bg-white px-4 py-3 flex items-center justify-between gap-3",children:[g.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[g.jsx(Oa,{className:"w-6 h-6 text-[#6CC24A] flex-shrink-0"}),g.jsxs("div",{className:"overflow-hidden",children:[g.jsx("p",{className:"text-xs font-bold text-neutral-700 truncate max-w-[290px]",title:C.name,children:C.name}),g.jsxs("p",{className:"text-[10px] text-neutral-400 font-mono mt-0.5",children:[C.size," • Excel"]})]})]}),g.jsx("button",{onClick:()=>rs(ee),className:"p-1.5 text-neutral-400 hover:text-red-500 hover:bg-neutral-100 transition-all rounded","aria-label":`Remover ${C.name}`,children:g.jsx(Ea,{className:"w-4.5 h-4.5"})})]},`${C.name}-${ee}`))}),g.jsx("button",{type:"button",onClick:()=>{var C;return(C=xe.current)==null?void 0:C.click()},className:"w-full border border-dashed border-[#4F758B]/40 bg-white px-4 py-2.5 text-[10px] font-black text-[#4F758B] hover:bg-[#4F758B]/5 transition-colors uppercase tracking-wide",children:"Agregar más archivos de nómina"})]}):g.jsxs("div",{onDragOver:ui,onDrop:hi,onClick:()=>{var C;return(C=xe.current)==null?void 0:C.click()},className:"border-2 border-dashed border-[#D0D0D0] bg-neutral-50 hover:bg-[#4F758B]/5 hover:border-[#4F758B]/40 transition-colors flex flex-col items-center justify-center py-10 px-4 text-center cursor-pointer min-h-[190px]",children:[g.jsx(Gr,{className:"w-8 h-8 text-neutral-300 mb-2"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700",children:"Arrastre la nómina y sus suplementos"}),g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1 font-medium",children:"Puede seleccionar varios .xlsx / .xls a la vez"}),g.jsx("button",{type:"button",className:"mt-4 border border-[#D0D0D0] bg-white px-4 py-1.5 text-[10px] font-bold text-neutral-600 hover:border-[#4F758B] hover:text-[#4F758B] transition-colors shadow-sm uppercase tracking-wide",children:"Seleccionar Archivos"})]}):e?g.jsxs("div",{className:"border border-[#6CC24A]/30 bg-[#6CC24A]/5 p-5 flex items-center justify-between gap-3",children:[g.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[g.jsx(Oa,{className:"w-8 h-8 text-[#6CC24A] flex-shrink-0"}),g.jsxs("div",{className:"overflow-hidden",children:[g.jsx("p",{className:"text-xs font-bold text-neutral-700 truncate max-w-[300px]",title:e.name,children:e.name}),g.jsxs("p",{className:"text-[10px] text-neutral-400 font-mono mt-0.5",children:[e.size," • Excel"]})]})]}),g.jsx("button",{onClick:()=>{i(null),xe.current&&(xe.current.value=""),et(),n("Nómina removida.","info")},className:"p-1.5 text-neutral-400 hover:text-red-500 hover:bg-neutral-100 transition-all rounded","aria-label":"Remover nómina",children:g.jsx(Ea,{className:"w-4.5 h-4.5"})})]}):g.jsxs("div",{onDragOver:ui,onDrop:hi,onClick:()=>{var C;return(C=xe.current)==null?void 0:C.click()},className:"border-2 border-dashed border-[#D0D0D0] bg-neutral-50 hover:bg-[#4F758B]/5 hover:border-[#4F758B]/40 transition-colors flex flex-col items-center justify-center py-10 px-4 text-center cursor-pointer min-h-[190px]",children:[g.jsx(Gr,{className:"w-8 h-8 text-neutral-300 mb-2"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700",children:"Arrastre y suelte archivo Excel"}),g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1 font-medium",children:"Formato .xlsx, .xls"}),g.jsx("button",{type:"button",className:"mt-4 border border-[#D0D0D0] bg-white px-4 py-1.5 text-[10px] font-bold text-neutral-600 hover:border-[#4F758B] hover:text-[#4F758B] transition-colors shadow-sm uppercase tracking-wide",children:"Seleccionar Archivo"})]})]})]}),g.jsxs("div",{className:"bg-white border border-[#D0D0D0] p-6 flex flex-col justify-between relative shadow-sm hover:shadow-md transition-shadow",children:[g.jsx("div",{className:"absolute top-0 left-0 w-full h-1 bg-[#4F758B]"}),g.jsxs("div",{children:[g.jsxs("div",{className:"flex items-center gap-2.5 mb-2",children:[g.jsx(Wl,{className:"w-5 h-5 text-[#4F758B]"}),g.jsx("h2",{className:"text-sm font-black text-neutral-800 uppercase tracking-wider",children:"2. Carga de Planillas del Banco"})]}),g.jsx("p",{className:"text-[11px] text-neutral-500 mb-4 leading-relaxed",children:"Puede subir múltiples archivos separados o un archivo consolidado del período."}),g.jsx("input",{type:"file",ref:$e,onChange:qi,accept:P?".pdf":".csv",multiple:!0,className:"hidden"}),g.jsxs("div",{onDragOver:ui,onDrop:Hi,onClick:()=>{var C;return(C=$e.current)==null?void 0:C.click()},className:"border-2 border-dashed border-[#D0D0D0] bg-neutral-50 hover:bg-[#4F758B]/5 hover:border-[#4F758B]/40 transition-colors flex flex-col items-center justify-center py-8 px-4 text-center cursor-pointer min-h-[130px]",children:[g.jsx(Gr,{className:"w-7 h-7 text-neutral-300 mb-2"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700",children:`Arrastre y suelte archivo ${X}`}),g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1 font-medium",children:`Formato ${q}`}),g.jsx("button",{type:"button",className:"mt-4 border border-[#D0D0D0] bg-white px-4 py-1.5 text-[10px] font-bold text-neutral-600 hover:border-[#4F758B] hover:text-[#4F758B] transition-colors shadow-sm uppercase tracking-wide",children:"Seleccionar Archivos"})]}),c.length>0&&g.jsxs("div",{className:"mt-4 border border-neutral-200 bg-white",children:[g.jsxs("div",{className:"p-3 border-b border-neutral-200 bg-neutral-50",children:[g.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 mb-2",children:[g.jsxs("div",{children:[g.jsxs("p",{className:"text-[11px] font-black text-neutral-700 uppercase tracking-wide",children:[c.length," ",c.length===1?"archivo cargado":"archivos cargados"]}),g.jsx("p",{className:"text-[9px] text-neutral-400 mt-0.5",children:"Busque por nombre para localizar y eliminar una planilla rápidamente."})]}),Q&&g.jsx("button",{type:"button",onClick:C=>{C.stopPropagation(),oe("")},className:"self-start sm:self-auto text-[9px] font-bold uppercase tracking-wide text-[#4F758B] hover:underline",children:"Limpiar búsqueda"})]}),g.jsxs("div",{className:"relative",children:[g.jsx(Jr,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-neutral-400 pointer-events-none"}),g.jsx("input",{type:"search",value:Q,onChange:C=>oe(C.target.value),onClick:C=>C.stopPropagation(),placeholder:`Buscar archivo ${X} por nombre...`,className:"w-full h-9 pl-9 pr-3 border border-[#D0D0D0] bg-white text-[11px] text-neutral-700 outline-none focus:border-[#4F758B] focus:ring-2 focus:ring-[#4F758B]/10 transition-all","aria-label":`Buscar archivos ${X} cargados`})]}),Q&&g.jsxs("p",{className:"text-[9px] text-neutral-400 mt-2",children:["Mostrando ",fn.length," de ",c.length," archivos."]})]}),g.jsx("div",{className:"max-h-[330px] overflow-y-auto overscroll-contain p-2 space-y-2",children:fn.length>0?fn.map(({file:C,originalIndex:ee})=>g.jsxs("div",{className:"border border-neutral-200 bg-white px-3 py-3 flex items-center justify-between gap-3 hover:border-[#4F758B]/40 hover:bg-[#4F758B]/[0.025] transition-colors",children:[g.jsxs("div",{className:"flex items-start gap-3 min-w-0 flex-1",children:[g.jsx("div",{className:"w-7 h-7 mt-0.5 border border-[#4F758B]/20 bg-[#4F758B]/5 flex items-center justify-center flex-shrink-0",children:g.jsx(Wl,{className:"w-4 h-4 text-[#4F758B]"})}),g.jsxs("div",{className:"min-w-0 flex-1",children:[g.jsx("p",{className:"text-[11px] leading-4 font-bold text-neutral-700 whitespace-normal break-words",title:C.name,children:C.name}),g.jsxs("div",{className:"flex items-center gap-2 mt-1",children:[g.jsx("span",{className:"text-[9px] text-neutral-400 font-mono",children:C.size}),g.jsx("span",{className:"text-[8px] font-bold uppercase tracking-wide text-[#4F758B] bg-[#4F758B]/5 border border-[#4F758B]/10 px-1.5 py-0.5",children:X})]})]})]}),g.jsx("button",{type:"button",onClick:ae=>{ae.stopPropagation(),di(ee)},className:"w-8 h-8 flex items-center justify-center flex-shrink-0 text-neutral-400 hover:text-red-600 hover:bg-red-50 border border-transparent hover:border-red-100 rounded transition-colors","aria-label":`Remover ${C.name}`,title:`Eliminar ${C.name}`,children:g.jsx(Ea,{className:"w-4 h-4"})})]},`${C.name}-${ee}`)):g.jsxs("div",{className:"py-8 px-4 text-center",children:[g.jsx(Jr,{className:"w-5 h-5 text-neutral-300 mx-auto mb-2"}),g.jsx("p",{className:"text-[11px] font-bold text-neutral-600",children:"No encontramos archivos con ese nombre."}),g.jsx("p",{className:"text-[9px] text-neutral-400 mt-1",children:"Pruebe con otra parte del nombre del archivo."})]})})]})]})]})]}),Nn&&g.jsx("section",{className:"bg-white border border-[#D0D0D0] shadow-sm",children:g.jsxs("div",{className:"border-t-4 border-[#6CC24A] p-5 sm:p-6",children:[g.jsxs("div",{className:"flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4 mb-5",children:[g.jsxs("div",{className:"flex items-start gap-3",children:[g.jsx("div",{className:"bg-[#6CC24A]/10 p-2 rounded-full",children:g.jsx(wb,{className:"w-5 h-5 text-[#4F758B]"})}),g.jsxs("div",{children:[g.jsx("h2",{className:"text-sm font-black text-[#4F758B] uppercase tracking-wider",children:"Bono 14 · Reporte independiente"}),g.jsx("p",{className:"text-[11px] text-neutral-500 mt-1 max-w-3xl leading-relaxed",children:"Esta sección aparece únicamente para Guatemala · Julio · Quincena 15. El Bono 14 se procesa separado de la nómina quincenal y genera su propio Google Sheet e histórico."})]})]}),g.jsxs("div",{className:"text-left lg:text-right",children:[g.jsx("p",{className:"text-[9px] font-black uppercase tracking-wider text-neutral-400",children:"Período del Bono 14"}),g.jsxs("p",{className:"text-[11px] font-bold text-[#4F758B] mt-1",children:[We.start," al ",We.end]})]})]}),g.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-5",children:[g.jsxs("div",{className:"border border-neutral-200 p-4 bg-neutral-50/50",children:[g.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[g.jsx(Oa,{className:"w-4.5 h-4.5 text-[#4F758B]"}),g.jsx("h3",{className:"text-xs font-black uppercase tracking-wider text-neutral-700",children:"1. Excel de Bono 14"})]}),g.jsx("p",{className:"text-[10px] text-neutral-500 mb-3",children:"Archivo anual con los montos calculados de Bono 14."}),g.jsx("input",{type:"file",ref:kt,onChange:fi,accept:".xlsx,.xls",className:"hidden"}),re?g.jsxs("div",{className:"border border-neutral-200 bg-white px-3 py-3 flex items-center justify-between gap-3",children:[g.jsxs("div",{className:"min-w-0",children:[g.jsx("p",{className:"text-[11px] font-bold text-neutral-700 break-words",title:re.name,children:re.name}),g.jsxs("p",{className:"text-[9px] text-neutral-400 font-mono mt-1",children:[re.size," · Excel"]})]}),g.jsx("button",{type:"button",onClick:()=>{_e(null),kt.current&&(kt.current.value=""),et(),n("Excel de Bono 14 removido.","info")},className:"w-8 h-8 flex items-center justify-center text-neutral-400 hover:text-red-600 hover:bg-red-50 border border-transparent hover:border-red-100 rounded transition-colors","aria-label":"Remover Excel de Bono 14",children:g.jsx(Ea,{className:"w-4 h-4"})})]}):g.jsxs("div",{onDragOver:ui,onDrop:Wa,onClick:()=>{var C;return(C=kt.current)==null?void 0:C.click()},className:"border-2 border-dashed border-[#D0D0D0] bg-white hover:bg-[#4F758B]/5 hover:border-[#4F758B]/40 transition-colors py-8 px-4 text-center cursor-pointer",children:[g.jsx(Gr,{className:"w-7 h-7 text-neutral-300 mx-auto mb-2"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700",children:"Arrastre el Excel de Bono 14"}),g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1",children:"Formato .xlsx, .xls"}),g.jsx("button",{type:"button",className:"mt-4 border border-[#D0D0D0] bg-white px-4 py-1.5 text-[10px] font-bold text-neutral-600 hover:border-[#4F758B] hover:text-[#4F758B] transition-colors shadow-sm uppercase tracking-wide",children:"Seleccionar Archivo"})]})]}),g.jsxs("div",{className:"border border-neutral-200 p-4 bg-neutral-50/50",children:[g.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[g.jsx(Wl,{className:"w-4.5 h-4.5 text-[#4F758B]"}),g.jsx("h3",{className:"text-xs font-black uppercase tracking-wider text-neutral-700",children:"2. CSV bancarios del Bono 14"})]}),g.jsx("p",{className:"text-[10px] text-neutral-500 mb-3",children:"Puede cargar todos los envíos bancarios correspondientes al Bono 14."}),g.jsx("input",{type:"file",ref:xt,onChange:Do,accept:".csv",multiple:!0,className:"hidden"}),g.jsxs("div",{onDragOver:ui,onDrop:Oo,onClick:()=>{var C;return(C=xt.current)==null?void 0:C.click()},className:"border-2 border-dashed border-[#D0D0D0] bg-white hover:bg-[#4F758B]/5 hover:border-[#4F758B]/40 transition-colors py-6 px-4 text-center cursor-pointer",children:[g.jsx(Gr,{className:"w-6 h-6 text-neutral-300 mx-auto mb-2"}),g.jsx("p",{className:"text-xs font-bold text-neutral-700",children:"Arrastre uno o varios CSV"}),g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1",children:"Formato .csv"}),g.jsx("button",{type:"button",className:"mt-4 border border-[#D0D0D0] bg-white px-4 py-1.5 text-[10px] font-bold text-neutral-600 hover:border-[#4F758B] hover:text-[#4F758B] transition-colors shadow-sm uppercase tracking-wide",children:"Seleccionar Archivos"})]}),ke.length>0&&g.jsxs("div",{className:"mt-3 border border-neutral-200 bg-white",children:[g.jsxs("div",{className:"p-3 border-b border-neutral-200 bg-neutral-50",children:[g.jsxs("div",{className:"relative",children:[g.jsx(Jr,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-neutral-400 pointer-events-none"}),g.jsx("input",{type:"search",value:en,onChange:C=>jn(C.target.value),onClick:C=>C.stopPropagation(),placeholder:"Buscar CSV de Bono 14...",className:"w-full h-9 pl-9 pr-3 border border-[#D0D0D0] bg-white text-[11px] text-neutral-700 outline-none focus:border-[#4F758B]"})]}),g.jsxs("p",{className:"text-[9px] text-neutral-400 mt-2",children:[ke.length," archivo(s) cargado(s)."]})]}),g.jsx("div",{className:"max-h-[250px] overflow-y-auto p-2 space-y-2",children:Rn.map(({file:C,originalIndex:ee})=>g.jsxs("div",{className:"border border-neutral-200 px-3 py-2.5 flex items-start justify-between gap-3",children:[g.jsxs("div",{className:"min-w-0",children:[g.jsx("p",{className:"text-[10px] leading-4 font-bold text-neutral-700 break-words",children:C.name}),g.jsx("p",{className:"text-[9px] text-neutral-400 font-mono mt-0.5",children:C.size})]}),g.jsx("button",{type:"button",onClick:ae=>{ae.stopPropagation(),Mo(ee)},className:"w-8 h-8 flex items-center justify-center flex-shrink-0 text-neutral-400 hover:text-red-600 hover:bg-red-50 rounded transition-colors","aria-label":`Remover ${C.name}`,children:g.jsx(Ea,{className:"w-4 h-4"})})]},`bonus14-${C.name}-${ee}`))})]})]})]}),g.jsxs("div",{className:"mt-5 flex flex-col items-center gap-2",children:[g.jsxs("button",{type:"button",onClick:tr,disabled:Y||!(re!=null&&re.rawFile)||ke.length===0,className:"inline-flex items-center justify-center gap-2 bg-[#4F758B] hover:bg-[#3d6378] text-white px-7 py-3 text-xs font-black uppercase tracking-wider transition-colors disabled:opacity-45 disabled:cursor-not-allowed min-w-[280px]",children:[Y?g.jsx($a,{className:"w-4 h-4 animate-spin"}):g.jsx(wb,{className:"w-4 h-4"}),"Generar reporte Bono 14"]}),g.jsxs("p",{className:"text-[9px] text-neutral-400 text-center",children:["Se guardará como un reporte separado: GT · ",ve," · Bono 14."]})]})]})}),g.jsx("section",{className:"flex flex-col items-center gap-3",children:g.jsx("button",{onClick:er,disabled:Y,className:"w-full sm:w-auto min-w-[280px] bg-[#4F758B] hover:bg-[#41677b] disabled:bg-neutral-300 disabled:cursor-not-allowed text-white px-8 py-4 font-black text-sm uppercase tracking-wider shadow-md flex items-center justify-center gap-3 transition-all duration-150 active:scale-[0.99] border-l-4 border-[#6CC24A]",children:Y?g.jsxs(g.Fragment,{children:[g.jsx($a,{className:"w-5 h-5 animate-spin"}),g.jsx("span",{children:J||"Procesando cruce de cuentas..."})]}):g.jsxs(g.Fragment,{children:[g.jsx(Jj,{className:"w-5 h-5"}),g.jsx("span",{children:"Ejecutar Cruce de Cuentas"})]})})}),g.jsx(si,{children:d&&p&&g.jsxs(un.section,{id:"resultados-seccion",initial:{opacity:0,y:20},animate:{opacity:1,y:0},exit:{opacity:0,y:10},className:"flex flex-col gap-5 scroll-mt-28",children:[g.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-4",children:[g.jsxs("div",{className:"bg-white border border-emerald-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-emerald-700",children:[g.jsx(kc,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:"Coincidencias"})]}),g.jsx("p",{className:"text-3xl font-black text-emerald-800 mt-2",children:p.summary.matches})]}),g.jsxs("div",{className:"bg-white border border-red-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-[#ba1a1a]",children:[g.jsx(fo,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:"Discrepancias"})]}),g.jsx("p",{className:"text-3xl font-black text-[#ba1a1a] mt-2",children:p.summary.discrepancies})]}),g.jsxs("div",{className:"bg-white border border-amber-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-amber-800",children:[g.jsx(xb,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:tn?"Banco sin Bono 14":"Banco sin nómina"})]}),g.jsx("p",{className:"text-3xl font-black text-amber-800 mt-2",children:p.summary.bankWithoutPayroll})]}),g.jsxs("div",{className:"bg-white border border-orange-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-orange-800",children:[g.jsx(xb,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:"Banco sin Bamboo"})]}),g.jsx("p",{className:"text-3xl font-black text-orange-800 mt-2",children:p.summary.bankWithoutBamboo})]}),g.jsxs("div",{className:"bg-white border border-violet-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-violet-800",children:[g.jsx(Wl,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:"Diferencias nombre banco"})]}),g.jsx("p",{className:"text-3xl font-black text-violet-800 mt-2",children:p.summary.nameDifferences})]}),g.jsxs("div",{className:"bg-white border border-blue-200 p-4 shadow-sm",children:[g.jsxs("div",{className:"flex items-center gap-2 text-blue-800",children:[g.jsx(Oa,{className:"w-5 h-5"}),g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black",children:tn?"Bono 14 sin cuenta":"Nómina sin cuenta"})]}),g.jsx("p",{className:"text-3xl font-black text-blue-800 mt-2",children:p.summary.payrollWithoutAccount})]})]}),g.jsxs("div",{className:"bg-white border border-[#D0D0D0] shadow-sm overflow-hidden",children:[g.jsxs("div",{className:"p-5 border-b border-neutral-200 flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4",children:[g.jsxs("div",{children:[g.jsx("h2",{className:"text-lg font-black text-[#4F758B] uppercase tracking-tight",children:tn?"Resultados del Bono 14":"Resultados del Cruce"}),g.jsx("p",{className:"text-[11px] text-neutral-500 mt-1",children:Gt})]}),g.jsx("div",{className:"flex flex-col sm:flex-row gap-2",children:g.jsxs("button",{onClick:Bo,disabled:!p.reportUrl,className:"inline-flex items-center justify-center gap-2 border border-[#4F758B] text-[#4F758B] hover:bg-[#4F758B] hover:text-white px-4 py-2 text-xs font-bold transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:[g.jsx(Rj,{className:"w-4 h-4"}),"Abrir Google Sheet"]})})]}),g.jsxs("div",{className:"p-4 border-b border-neutral-200 bg-neutral-50 flex flex-col lg:flex-row gap-3 lg:items-center lg:justify-between",children:[g.jsxs("div",{className:"relative w-full lg:max-w-sm",children:[g.jsx(Jr,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400"}),g.jsx("input",{type:"text",value:H,onChange:C=>{W(C.target.value),E(1)},placeholder:"Buscar empleado, Employee Number o cuenta...",className:"w-full pl-9 pr-3 py-2 border border-[#D0D0D0] text-xs font-medium focus:outline-none focus:border-[#4F758B]"})]}),g.jsx("div",{className:"flex flex-wrap gap-2",children:[["todos","Todos"],["discrepancias","Discrepancias"],["coincidencias","Coincidencias"],["banco_sin_nomina",tn?"Banco sin Bono 14":"Banco sin nómina"],["banco_sin_bamboo","Banco sin Bamboo"],["diferencia_nombre_banco","Diferencias nombre banco"],["nomina_sin_cuenta",tn?"Bono 14 sin cuenta":"Nómina sin cuenta"]].map(([C,ee])=>g.jsx("button",{onClick:()=>{Ae(C),E(1)},className:`px-3 py-1.5 text-[10px] uppercase tracking-wider font-black border transition-colors ${fe===C?"bg-[#4F758B] text-white border-[#4F758B]":"bg-white text-neutral-500 border-neutral-300 hover:border-[#4F758B] hover:text-[#4F758B]"}`,children:ee},C))})]}),g.jsx("div",{className:"overflow-x-auto",children:g.jsxs("table",{className:"w-full text-left border-collapse min-w-[960px] xl:min-w-full",children:[g.jsx("thead",{children:g.jsxs("tr",{className:"bg-[#4F758B] text-white text-xs font-bold uppercase tracking-wider",children:[g.jsx("th",{className:"py-3 px-3 xl:px-4",children:"Empleado"}),g.jsx("th",{className:"py-3 px-3 xl:px-4",children:"Employee Number"}),g.jsx("th",{className:"py-3 px-3 xl:px-4",children:"Cuenta"}),g.jsx("th",{className:"py-3 px-3 xl:px-4 text-right",children:tn?"Monto Bono 14":"Monto Nómina"}),g.jsx("th",{className:"py-3 px-3 xl:px-4 text-right",children:"Monto Banco"}),g.jsx("th",{className:"py-3 px-3 xl:px-4 text-right",children:"Diferencia"}),g.jsx("th",{className:"py-3 px-3 xl:px-4 text-center",children:"Estado"}),g.jsx("th",{className:"py-3 px-3 xl:px-4",children:"Categoría"}),g.jsx("th",{className:"py-3 px-3 xl:px-4",children:"Observación"}),g.jsx("th",{className:"py-3 px-3 xl:px-4 text-center",children:"Acciones"})]})}),g.jsx("tbody",{className:"divide-y divide-neutral-200 text-xs",children:as.length>0?as.map(C=>g.jsxs("tr",{className:"hover:bg-neutral-50 transition-colors",children:[g.jsx("td",{className:"py-3 px-3 xl:px-4 font-bold text-neutral-800",children:C.employee}),g.jsx("td",{className:"py-3 px-3 xl:px-4 font-mono text-neutral-600",children:C.employeeNumber||"—"}),g.jsx("td",{className:"py-3 px-3 xl:px-4 font-mono text-neutral-500",children:C.account??"—"}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-right font-mono text-neutral-700",children:Bd(C.amountPayroll,T,C.currency)}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-right font-mono text-neutral-700",children:Bd(C.amountBank,T,C.currency)}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-right font-mono text-neutral-700",children:Bd(C.difference,T,C.currency)}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-center",children:g.jsx("span",{className:`inline-block px-2.5 py-1 text-[9px] font-black uppercase tracking-wider border ${OC(C.status)}`,children:C.status})}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-neutral-600 max-w-[180px] capitalize",children:BC(C.category??C.source,(p==null?void 0:p.reportKind)??"nomina")}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-neutral-600 max-w-[300px]",children:C.observation}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-center",children:Ua(C,"banco_sin_bamboo")?te.has(C.id)?g.jsx("span",{className:"inline-flex items-center px-2.5 py-1 border border-emerald-200 bg-emerald-50 text-emerald-800 text-[9px] font-black uppercase tracking-wider",children:"Reportado a RRHH"}):g.jsx("button",{type:"button",onClick:()=>is(C),className:"inline-flex items-center justify-center px-3 py-2 border border-[#4F758B] text-[#4F758B] hover:bg-[#4F758B] hover:text-white text-[9px] font-black uppercase tracking-wider transition-colors whitespace-nowrap",children:"Reportar a RRHH"}):g.jsx("span",{className:"text-neutral-300",children:"—"})})]},C.id)):g.jsx("tr",{children:g.jsx("td",{colSpan:10,className:"py-12 text-center text-neutral-400 font-medium",children:"No hay resultados para el filtro seleccionado."})})})]})}),g.jsxs("div",{className:"p-4 border-t border-neutral-200 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 text-xs text-neutral-500",children:[g.jsxs("span",{children:["Mostrando ",as.length," de ",Cs.length," resultado(s)."]}),g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx("button",{onClick:()=>E(C=>Math.max(1,C-1)),disabled:ie===1,className:"px-3 py-1.5 border border-neutral-300 bg-white disabled:opacity-40 disabled:cursor-not-allowed hover:border-[#4F758B] font-bold",children:"Anterior"}),g.jsxs("span",{className:"font-bold text-neutral-700",children:["Página ",ie," de ",qn]}),g.jsx("button",{onClick:()=>E(C=>Math.min(qn,C+1)),disabled:ie===qn,className:"px-3 py-1.5 border border-neutral-300 bg-white disabled:opacity-40 disabled:cursor-not-allowed hover:border-[#4F758B] font-bold",children:"Siguiente"})]})]})]})]})})]}),Rs&&p&&g.jsx(zw,{row:Rs,country:T,periodRange:tn?We:Ht,operatorName:x,operatorEmail:_,executionId:p.executionId,reportUrl:p.reportUrl,onClose:()=>is(null),onSuccess:C=>Be(ee=>{const ae=new Set(ee);return ae.add(C),ae}),onShowToast:n})]})}const cc=10;function FC(n){return n==="TT"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-tt-historicos":n==="PA"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-pa-historicos":n==="SV"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-sv-historicos":n==="HN"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-hn-historicos":n==="PR"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-pr-historicos":"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-gt-historicos"}function IC(n){return n==="TT"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-tt-marcar-resuelto":n==="PA"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-pa-marcar-resuelto":n==="SV"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-sv-marcar-resuelto":n==="HN"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-hn-marcar-resuelto":n==="PR"?"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-pr-marcar-resuelto":"https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-gt-marcar-resuelto"}function Pn(n){const e=Number(n);return Number.isFinite(e)?e:0}function GC(n,e){if(!n)return"";const i=new Date(String(n));return Number.isNaN(i.getTime())?String(n).slice(0,10):i.toLocaleDateString(e,{year:"numeric",month:"2-digit",day:"2-digit"})}function xf(n,e){if(!n)return"";const i=new Date(String(n));return Number.isNaN(i.getTime())?String(n):i.toLocaleString(e,{dateStyle:"short",timeStyle:"short"})}function KC(n){return String(n??"").toLowerCase().includes("resuelto")?"Resuelto":"Pendiente revisión"}function bv(n,e){const i=n,a=!Array.isArray(i)&&i?i:{};return(Array.isArray(i)?i:Array.isArray(a.reports)?a.reports:[]).map((c,u)=>{const d=c,m=Pn(d.discrepancias??d.discrepancies),p=Pn(d.bancoSinNomina??d.banco_sin_nomina??d.bankWithoutPayroll),y=Pn(d.bancoSinBamboo??d.banco_sin_bamboo??d.bankWithoutBamboo),v=Pn(d.nominaSinCuenta??d.nomina_sin_cuenta??d.payrollWithoutAccount),x=Pn(d.diferenciasNombreBanco??d.diferencias_nombre_banco??d.nameDifferences),_=m+p+y+v+x,S=String(d.country??d.pais??d.country_code??e.code).toUpperCase(),T=Array.isArray(d.archivosBanco)?d.archivosBanco.map(String):Array.isArray(d.bank_file_names)?d.bank_file_names.map(String):[],k=d.updated_at??d.fechaEjecucion??d.ejecutado_en??d.created_at;return{id:String(d.id??`reporte-${u+1}`),country:S==="TT"?"TT":S==="PA"?"PA":S==="SV"?"SV":S==="HN"?"HN":S==="PR"?"PR":"GT",date:GC(d.fecha??d.period_end??k,e.locale),executionDate:xf(k,e.locale),period:String(d.periodo??d.period_label??d.period??"Período no especificado"),periodStart:d.period_start?String(d.period_start):void 0,periodEnd:d.period_end?String(d.period_end):void 0,payrollFile:String(d.archivoNomina??d.payroll_file_name??d.payrollFile??""),bankFiles:T,matches:Pn(d.coincidencias??d.matches),discrepancies:m,bankWithoutPayroll:p,bankWithoutBamboo:y,payrollWithoutAccount:v,nameDifferences:x,totalPending:_,totalPayroll:Pn(d.totalNomina??d.total_nomina),totalBank:Pn(d.totalBanco??d.total_banco),totalDifference:Pn(d.diferenciaTotal??d.diferencia_total),status:KC(d.estado??d.status??d.estadoLabel),reportUrl:d.reportUrl||d.report_url?String(d.reportUrl??d.report_url):void 0,spreadsheetId:d.spreadsheetId||d.spreadsheet_id?String(d.spreadsheetId??d.spreadsheet_id):void 0,executedBy:d.ejecutadoPorNombre||d.ejecutado_por_nombre?String(d.ejecutadoPorNombre??d.ejecutado_por_nombre):void 0,executedByEmail:d.ejecutadoPorEmail||d.ejecutado_por_email?String(d.ejecutadoPorEmail??d.ejecutado_por_email):void 0,resolvedBy:d.resueltoPorNombre||d.resuelto_por_nombre?String(d.resueltoPorNombre??d.resuelto_por_nombre):void 0,resolvedByEmail:d.resueltoPorEmail||d.resuelto_por_email?String(d.resueltoPorEmail??d.resuelto_por_email):void 0,resolvedAt:xf(d.resueltoEn??d.resuelto_en,e.locale),resolutionComment:d.comentarioResolucion||d.comentario_resolucion?String(d.comentarioResolucion??d.comentario_resolucion):void 0,_sortTime:new Date(String(k??d.period_end??"")).getTime()||0}}).filter(c=>c.country===e.code).sort((c,u)=>u._sortTime-c._sortTime).map(({_sortTime:c,...u})=>u)}function wf(n){return String(n??"").toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^a-z0-9 ]/g," ").replace(/\s+/g," ").trim()}function _f(n){return String(n??"").replace(/\.0$/g,"").replace(/\D/g,"").trim()}function vv(n,e){for(const i of e){const a=n[i];if(typeof a=="number"&&Number.isFinite(a))return a;if(typeof a=="string"&&a.trim()){const l=Number(a.replace(/[A-Za-z$Q,\s]/g,"").trim());if(Number.isFinite(l))return l}}return null}function YC(n){return Array.isArray(n)?n.map((e,i)=>{const a=e??{},l=String(a.employee??a.employee_name??a.bank_name_file??a.bank_account_holder??"Sin nombre"),c=vv(a,["bankAmount","bank_amount","amount","monto_banco"]),u=a.best_bamboo_candidate&&typeof a.best_bamboo_candidate=="object"?a.best_bamboo_candidate:null;return{id:String(a.id??`historical-bamboo-${wf(l)}-${_f(a.account??a.bank_account)}-${i+1}`),employee:l,employeeNumber:"",account:String(a.account??a.bank_account??a.bankAccount??""),amountPayroll:0,amountBank:c,difference:c===null?null:0-c,status:"Pendiente revisión",category:"banco_sin_bamboo",source:"banco_sin_bamboo",observation:String(a.observation??a.observacion??"Pago bancario sin empleado identificado de forma confiable en BambooHR."),bankNameFile:String(a.bank_name_file??a.bankNameFile??""),bankAccountHolder:String(a.bank_account_holder??a.bankAccountHolder??""),bestBambooCandidate:u?{employeeNumber:String(u.employee_number??u.employeeNumber??""),employeeName:String(u.employee_name??u.employeeName??""),score:vv(u,["score"])}:null,ambiguousBambooMatch:!!a.ambiguous_bamboo_match}}):[]}function XC(n){return Array.isArray(n)?n.map(e=>{const i=e??{};return{id:String(i.id??""),sourceName:String(i.nombre_origen_principal??i.source_name??""),sourceNames:Array.isArray(i.nombres_origen)?i.nombres_origen.map(String):[],bankAccount:String(i.cuenta_bancaria??i.bank_account??""),status:String(i.estado??""),emailSent:i.correo_enviado===!0}}):[]}function JC(n,e){const i=n.status.toLowerCase();if(!(n.emailSent||i==="notificado_rrhh"||i==="corregido_bamboo"))return!1;const l=_f(n.bankAccount),c=_f(e.account);if(l&&c&&l!==c)return!1;const u=new Set([n.sourceName,...n.sourceNames].map(wf).filter(Boolean));return[e.employee,e.bankNameFile,e.bankAccountHolder].map(wf).filter(Boolean).some(m=>u.has(m))}function QC(n){return n==="Resuelto"?"bg-blue-50 text-blue-800 border-blue-200":"bg-amber-50 text-amber-800 border-amber-200"}function ZC(n){return n==="Resuelto"?"RESUELTO":"PENDIENTE REVISIÓN"}function WC({onShowToast:n,onOpenSidebar:e,operatorName:i,operatorEmail:a,country:l}){const[c,u]=D.useState(""),[d,m]=D.useState("todos"),[p,y]=D.useState([]),[v,x]=D.useState(1),[_,S]=D.useState(!1),[T,k]=D.useState(!1),[R,M]=D.useState(""),[N,P]=D.useState(null),[G,X]=D.useState(""),[q,Y]=D.useState(null),[se,J]=D.useState([]),[he,fe]=D.useState(new Set),[Ae,ve]=D.useState(!1),[Ce,L]=D.useState(""),[K,Z]=D.useState(null),[pe,ie]=D.useState(0),[E,H]=D.useState(0),W=D.useRef(0),Q=D.useRef(null),oe=Math.max(1,Math.ceil(E/cc)),re=p;D.useEffect(()=>{x(1)},[c,d,l.code]),D.useEffect(()=>{v>oe&&x(oe)},[v,oe]);const _e=async()=>{var xe;const te=++W.current;(xe=Q.current)==null||xe.abort();const Be=new AbortController;Q.current=Be;const Ue=()=>W.current===te&&!Be.signal.aborted;S(!0),M("");try{if(ut){const Gt=d==="pendiente"?"pendiente_revision":d==="resuelto"?"resuelto":null,{data:kn,error:fn}=await ut.rpc("cruce_cuentas_get_historicos",{p_country:l.code,p_page:v,p_page_size:cc,p_search:c.trim()||null,p_status:Gt});if(!Ue())return;if(!fn&&kn){const Rn=Array.isArray(kn)?kn[0]:kn,Cs=bv(Rn,l),Os=Pn(Rn==null?void 0:Rn.total),qn=Pn((Rn==null?void 0:Rn.filtered_total)??Os);y(Cs),ie(Os),H(qn);return}}if(!Ue())return;const $e=FC(l.code);if(!$e)throw new Error(`No está configurado el origen histórico de ${l.name}.`);const kt=new URL($e);kt.searchParams.set("country",l.code);const xt=await fetch(kt.toString(),{method:"GET",signal:Be.signal}),Et=await xt.json().catch(()=>null);if(!Ue())return;if(!xt.ok||(Et==null?void 0:Et.ok)===!1)throw new Error("No se pudieron cargar los reportes históricos.");const Ht=bv(Et,l),Nn=c.trim().toLowerCase(),We=Ht.filter(Gt=>{const kn=d==="todos"||d==="pendiente"&&Gt.status==="Pendiente revisión"||d==="resuelto"&&Gt.status==="Resuelto",fn=!Nn||Gt.period.toLowerCase().includes(Nn)||Gt.payrollFile.toLowerCase().includes(Nn)||Gt.id.toLowerCase().includes(Nn)||(Gt.resolvedBy??"").toLowerCase().includes(Nn)||(Gt.executedBy??"").toLowerCase().includes(Nn);return kn&&fn});if(!Ue())return;const tn=(v-1)*cc;y(We.slice(tn,tn+cc)),ie(Ht.length),H(We.length)}catch($e){if(!Ue()||$e instanceof DOMException&&$e.name==="AbortError")return;y([]),ie(0),H(0),M($e instanceof Error?$e.message:"No se pudieron cargar los reportes históricos. Intenta nuevamente."),n("No se pudieron cargar los reportes históricos.","error")}finally{Ue()&&(S(!1),Q.current===Be&&(Q.current=null))}};D.useEffect(()=>{const te=window.setTimeout(()=>{_e()},c.trim()?300:0);return()=>{var Be;window.clearTimeout(te),W.current+=1,(Be=Q.current)==null||Be.abort(),Q.current=null}},[l.code,v,c,d]);const ke=()=>{Z(null),Y(null),J([]),fe(new Set),L("")},He=async te=>{if(te.bankWithoutBamboo<=0){n("Este reporte no tiene casos de Banco sin Bamboo.","info");return}if(!ut){n("Supabase no está configurado en esta aplicación.","error");return}Y(te),Z(null),J([]),fe(new Set),L(""),ve(!0);try{const{data:Be,error:Ue}=await ut.rpc("cruce_cuentas_get_banco_sin_bamboo_reporte",{p_report_id:te.id,p_country:l.code});if(Ue)throw Ue;const xe=Array.isArray(Be)?Be[0]:Be;if(!xe||xe.ok===!1)throw new Error(String((xe==null?void 0:xe.message)||"No se pudieron recuperar los casos de Banco sin Bamboo."));const $e=YC(xe.cases),kt=XC(xe.corrections),xt=new Set($e.filter(Et=>kt.some(Ht=>JC(Ht,Et))).map(Et=>Et.id));J($e),fe(xt),$e.length===0&&L("Este reporte fue creado antes de que se guardara el detalle de Banco sin Bamboo. Los reportes nuevos conservarán los casos para revisarlos desde Históricos.")}catch(Be){const Ue=Be instanceof Error?Be.message:"No se pudieron recuperar los casos de Banco sin Bamboo.";L(Ue),n(Ue,"error")}finally{ve(!1)}},en={label:(q==null?void 0:q.period)||"Período no especificado",start:(q==null?void 0:q.periodStart)||"",end:(q==null?void 0:q.periodEnd)||""},jn=te=>{if(te.reportUrl){window.open(te.reportUrl,"_blank","noopener,noreferrer");return}n("Este reporte aún no tiene un Google Sheet disponible.","info")},Rs=te=>{if(te.status==="Resuelto"){n("Este reporte ya fue marcado como resuelto.","info");return}P(te),X("")},is=async()=>{if(!N)return;const te=G.trim();if(te.length<10){n("Debes escribir un comentario de resolución más descriptivo.","error");return}const Be=IC(l.code);if(!Be){n(`La resolución de reportes para ${l.name} estará disponible próximamente.`,"info");return}k(!0);try{const Ue=await fetch(Be,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({reportId:N.id,comentarioResolucion:te,resueltoPorNombre:i,resueltoPorEmail:a,country:l.code,countryName:l.name})}),xe=await Ue.json().catch(()=>null);if(!Ue.ok||(xe==null?void 0:xe.ok)===!1){const xt=Array.isArray(xe==null?void 0:xe.errors)?xe.errors.join(` -`):(xe==null?void 0:xe.message)||"No se pudo marcar el reporte como resuelto.";throw new Error(xt)}const $e=xe.report??{},kt=xf($e.resueltoEn??new Date().toISOString(),l.locale);y(xt=>xt.map(Et=>Et.id===N.id?{...Et,status:"Resuelto",resolvedBy:String($e.resueltoPorNombre??i),resolvedByEmail:String($e.resueltoPorEmail??a),resolvedAt:kt,resolutionComment:String($e.comentarioResolucion??te)}:Et)),P(null),X(""),n("Reporte marcado como resuelto correctamente.","success")}catch(Ue){const xe=Ue instanceof Error?Ue.message:"No se pudo marcar el reporte como resuelto.";n(xe,"error")}finally{k(!1)}};return g.jsxs("div",{className:"flex-1 flex flex-col min-h-screen bg-neutral-50 text-neutral-800 font-sans",children:[g.jsxs("header",{className:"bg-white border-b-4 border-[#6CC24A] flex justify-between items-center w-full px-4 sm:px-8 h-[84px] sticky top-0 z-40 shadow-sm gap-x-4",children:[g.jsxs("div",{className:"flex items-center gap-2 sm:gap-3 min-w-0",children:[g.jsx("button",{onClick:e,className:"md:hidden p-2 -ml-2 text-neutral-600 hover:text-neutral-800 hover:bg-neutral-100 transition-colors flex-shrink-0","aria-label":"Abrir menú",children:g.jsx(dw,{className:"w-6 h-6"})}),g.jsx("h1",{className:"text-xs sm:text-sm md:text-lg lg:text-2xl font-black text-[#4F758B] tracking-tight uppercase flex items-center gap-1.5 sm:gap-2 min-w-0",children:g.jsxs("span",{className:"truncate",children:["Reportes Históricos - ",l.name]})})]}),g.jsxs("div",{className:"flex items-center gap-2 sm:gap-3 flex-shrink-0",children:[g.jsx(Pw,{country:l,operatorName:i,operatorEmail:a,section:"Reportes Históricos",onShowToast:n}),g.jsx("div",{className:"hidden sm:flex items-center border border-neutral-200 bg-white px-2.5 py-2 shadow-sm","aria-label":`Bandera de ${l.name}`,children:g.jsx("img",{src:l.flag,alt:`Bandera de ${l.name}`,className:"h-5 sm:h-6 w-auto object-contain"})}),g.jsxs("button",{onClick:_e,disabled:_,className:"hidden sm:inline-flex items-center gap-2 border border-[#4F758B]/20 text-[#4F758B] px-3 py-2 text-xs font-bold hover:border-[#4F758B]/50 disabled:opacity-50",children:[g.jsx(eN,{className:`w-4 h-4 ${_?"animate-spin":""}`}),"Actualizar"]})]})]}),g.jsxs("main",{className:"flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 py-8 flex flex-col gap-6",children:[g.jsxs("div",{className:"bg-white border border-[#D0D0D0] p-4 flex flex-col lg:flex-row items-center justify-between gap-4 shadow-sm",children:[g.jsxs("div",{className:"relative w-full lg:max-w-md",children:[g.jsx(Jr,{className:"absolute left-3.5 top-1/2 transform -translate-y-1/2 text-neutral-400 w-4 h-4"}),g.jsx("input",{type:"text",placeholder:"Buscar por período, reporte, archivo o resolutor...",value:c,onChange:te=>u(te.target.value),className:"w-full pl-10 pr-4 py-2 border border-[#D0D0D0] text-xs font-medium placeholder-neutral-400 focus:outline-none focus:border-[#4F758B] transition-colors"})]}),g.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center gap-3 w-full lg:w-auto",children:[g.jsx("div",{className:"flex flex-wrap gap-2",children:[["todos","Todos"],["pendiente","Pendiente revisión"],["resuelto","Resuelto"]].map(([te,Be])=>g.jsx("button",{onClick:()=>m(te),className:`px-3 py-1.5 text-[10px] uppercase tracking-wider font-black border transition-colors ${d===te?"bg-[#4F758B] text-white border-[#4F758B]":"bg-white text-neutral-500 border-neutral-300 hover:border-[#4F758B] hover:text-[#4F758B]"}`,children:Be},te))}),g.jsxs("div",{className:"flex items-center gap-2 text-xs font-bold text-neutral-500",children:[g.jsx(Uj,{className:"w-4 h-4 text-neutral-400"}),g.jsxs("span",{children:["Mostrando: ",E," de ",pe," reportes"]})]})]})]}),R&&g.jsxs("div",{className:"border border-red-200 bg-red-50 text-[#ba1a1a] px-4 py-3 text-xs font-bold flex items-center gap-2",children:[g.jsx(fo,{className:"w-4 h-4"}),R]}),g.jsxs("div",{className:"bg-white border border-[#D0D0D0] shadow-sm overflow-hidden",children:[g.jsx("div",{className:"overflow-x-auto",children:g.jsxs("table",{className:"w-full text-left border-collapse min-w-[960px] xl:min-w-full",children:[g.jsx("thead",{children:g.jsxs("tr",{className:"bg-[#4F758B] text-white text-xs font-bold uppercase tracking-wider",children:[g.jsx("th",{className:"py-3 px-3 xl:px-4",children:"Fecha"}),g.jsx("th",{className:"py-3 px-3 xl:px-4",children:"Período"}),g.jsx("th",{className:"py-3 px-3 xl:px-4",children:"Archivo de Nómina / Bono 14"}),g.jsx("th",{className:"py-3 px-3 xl:px-4 text-center",children:"Coincidencias"}),g.jsx("th",{className:"py-3 px-3 xl:px-4 text-center",children:"Banco sin Bamboo"}),g.jsx("th",{className:"py-3 px-3 xl:px-4 text-center",children:"Pendientes"}),g.jsx("th",{className:"py-3 px-3 xl:px-4 text-center",children:"Estado"}),g.jsx("th",{className:"py-3 px-3 xl:px-4",children:"Resuelto por"}),g.jsx("th",{className:"py-3 px-3 xl:px-4 text-center",children:"Acciones"})]})}),g.jsx("tbody",{className:"divide-y divide-neutral-200 text-xs",children:_?g.jsx("tr",{children:g.jsx("td",{colSpan:9,className:"py-12 text-center text-neutral-400 font-medium",children:g.jsxs("div",{className:"inline-flex items-center gap-2",children:[g.jsx($a,{className:"w-4 h-4 animate-spin"}),"Cargando reportes históricos..."]})})}):re.length>0?re.map(te=>g.jsxs(un.tr,{initial:{opacity:0},animate:{opacity:1},className:"hover:bg-neutral-50/70 transition-colors",children:[g.jsx("td",{className:"py-3 px-3 xl:px-4 font-medium text-neutral-700",children:g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx(xj,{className:"w-4 h-4 text-neutral-400"}),g.jsxs("div",{children:[g.jsx("span",{children:te.date}),te.executionDate&&g.jsx("p",{className:"text-[9px] text-neutral-400 mt-0.5",children:te.executionDate})]})]})}),g.jsx("td",{className:"py-3 px-3 xl:px-4 font-bold text-[#4F758B]",children:te.period}),g.jsx("td",{className:"py-3 px-3 xl:px-4 font-mono text-neutral-500 truncate max-w-[260px]",title:te.payrollFile,children:g.jsxs("div",{className:"flex items-center gap-1.5",children:[g.jsx(Oa,{className:"w-4 h-4 text-neutral-400 flex-shrink-0"}),g.jsx("span",{className:"truncate",children:te.payrollFile||"No especificado"})]})}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-center font-black text-emerald-800",children:te.matches}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-center",children:te.bankWithoutBamboo>0?g.jsxs("button",{type:"button",onClick:()=>void He(te),className:"inline-flex items-center gap-1.5 min-w-8 px-2.5 py-1 text-[10px] font-black border bg-orange-50 text-orange-800 border-orange-200 hover:bg-orange-100 hover:border-orange-300 transition-colors",title:"Revisar casos y reportar correcciones a RRHH",children:[g.jsx("span",{children:te.bankWithoutBamboo}),g.jsx("span",{className:"hidden 2xl:inline",children:"Revisar"})]}):g.jsx("span",{className:"inline-block min-w-8 px-2.5 py-1 text-[10px] font-black border bg-neutral-50 text-neutral-400 border-neutral-200",children:"0"})}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-center",children:g.jsx("span",{className:`inline-block px-2.5 py-1 text-[10px] font-bold border ${te.totalPending>0?"bg-red-50 text-[#ba1a1a] border-red-200":"bg-emerald-50 text-emerald-800 border-emerald-200"}`,children:te.totalPending===0?"Sin pendientes":`${te.totalPending} pendiente${te.totalPending>1?"s":""}`})}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-center",children:g.jsx("span",{className:`inline-block px-2.5 py-1 text-[9px] uppercase font-black tracking-wider border ${QC(te.status)}`,children:ZC(te.status)})}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-neutral-600 max-w-[220px]",children:te.resolvedBy?g.jsxs("div",{title:te.resolutionComment||"",children:[g.jsx("p",{className:"font-bold text-neutral-700 truncate",children:te.resolvedBy}),g.jsx("p",{className:"text-[10px] text-neutral-400",children:te.resolvedAt})]}):g.jsx("span",{className:"text-neutral-400",children:"Pendiente"})}),g.jsx("td",{className:"py-3 px-3 xl:px-4 text-center",children:g.jsxs("div",{className:"flex justify-center gap-2",children:[g.jsxs("button",{onClick:()=>jn(te),className:"inline-flex items-center gap-1.5 text-[#4F758B] hover:text-[#3d6378] font-bold text-xs border border-[#4F758B]/20 hover:border-[#4F758B]/50 px-3 py-1.5 bg-white hover:bg-neutral-50 transition-colors",children:[g.jsx(Oj,{className:"w-3.5 h-3.5"}),g.jsx("span",{children:"Ver"})]}),g.jsxs("button",{onClick:()=>Rs(te),disabled:te.status==="Resuelto",className:"inline-flex items-center gap-1.5 text-emerald-700 hover:text-emerald-800 font-bold text-xs border border-emerald-200 hover:border-emerald-400 px-3 py-1.5 bg-emerald-50 hover:bg-emerald-100 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:[g.jsx(kc,{className:"w-3.5 h-3.5"}),g.jsx("span",{children:te.status==="Resuelto"?"Resuelto":"Marcar resuelto"})]})]})})]},te.id)):g.jsx("tr",{children:g.jsx("td",{colSpan:9,className:"py-12 text-center text-neutral-400 font-medium",children:"No se encontraron reportes históricos."})})})]})}),g.jsxs("div",{className:"p-4 border-t border-neutral-200 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 text-xs text-neutral-500",children:[g.jsxs("span",{children:["Mostrando ",re.length," de ",E," reporte(s)."]}),g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsx("button",{onClick:()=>x(te=>Math.max(1,te-1)),disabled:v===1,className:"px-3 py-1.5 border border-neutral-300 bg-white disabled:opacity-40 disabled:cursor-not-allowed hover:border-[#4F758B] font-bold",children:"Anterior"}),g.jsxs("span",{className:"font-bold text-neutral-700",children:["Página ",v," de ",oe]}),g.jsx("button",{onClick:()=>x(te=>Math.min(oe,te+1)),disabled:v===oe,className:"px-3 py-1.5 border border-neutral-300 bg-white disabled:opacity-40 disabled:cursor-not-allowed hover:border-[#4F758B] font-bold",children:"Siguiente"})]})]})]})]}),g.jsx(si,{children:q&&g.jsx(un.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:"fixed inset-0 z-[80] flex items-center justify-center bg-black/45 px-4 py-6",children:g.jsxs(un.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},exit:{opacity:0,y:12},className:"w-full max-w-5xl bg-white border border-[#D0D0D0] shadow-2xl max-h-[92vh] flex flex-col",children:[g.jsx("div",{className:"h-1.5 bg-[#6CC24A] flex-shrink-0"}),g.jsxs("div",{className:"border-b border-neutral-200 px-5 sm:px-6 py-4 flex items-start justify-between gap-4 flex-shrink-0",children:[g.jsxs("div",{children:[g.jsx("p",{className:"text-[10px] uppercase tracking-[0.18em] font-black text-[#6B8FA3]",children:"Histórico · Banco sin BambooHR"}),g.jsx("h2",{className:"text-lg sm:text-xl font-black text-[#4F758B] mt-1",children:q.period}),g.jsxs("p",{className:"text-xs text-neutral-500 mt-1",children:[l.name," · ",q.bankWithoutBamboo," caso",q.bankWithoutBamboo===1?"":"s"," guardado",q.bankWithoutBamboo===1?"":"s"," en este reporte"]})]}),g.jsx("button",{type:"button",onClick:ke,className:"p-2 text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100","aria-label":"Cerrar revisión de Banco sin Bamboo",children:g.jsx(Ka,{className:"w-5 h-5"})})]}),g.jsxs("div",{className:"px-5 sm:px-6 py-4 overflow-y-auto",children:[g.jsxs("div",{className:"border border-[#D6E8F4] bg-[#F7FBFD] px-4 py-3 text-xs text-neutral-600 leading-relaxed mb-4",children:["Aquí puedes volver días después al reporte y enviar a RRHH únicamente los falsos positivos que ya verificaste manualmente. Los casos previamente enviados se muestran como ",g.jsx("strong",{children:"Reportado a RRHH"}),"."]}),Ae?g.jsxs("div",{className:"py-14 text-center text-neutral-500 text-sm",children:[g.jsx($a,{className:"w-5 h-5 animate-spin mx-auto mb-2 text-[#4F758B]"}),"Recuperando casos del reporte..."]}):Ce?g.jsxs("div",{className:"border border-amber-200 bg-amber-50 text-amber-800 px-4 py-3 text-xs font-medium flex items-start gap-2",children:[g.jsx(fo,{className:"w-4 h-4 mt-0.5 flex-shrink-0"}),g.jsx("span",{children:Ce})]}):se.length>0?g.jsx("div",{className:"overflow-x-auto border border-neutral-200",children:g.jsxs("table",{className:"w-full text-left border-collapse min-w-[760px]",children:[g.jsx("thead",{children:g.jsxs("tr",{className:"bg-[#4F758B] text-white text-[10px] font-black uppercase tracking-wider",children:[g.jsx("th",{className:"px-3 py-3",children:"Nombre detectado"}),g.jsx("th",{className:"px-3 py-3",children:"Cuenta"}),g.jsx("th",{className:"px-3 py-3 text-right",children:"Monto banco"}),g.jsx("th",{className:"px-3 py-3",children:"Candidato BambooHR"}),g.jsx("th",{className:"px-3 py-3 text-center",children:"Acción"})]})}),g.jsx("tbody",{className:"divide-y divide-neutral-200 text-xs",children:se.map(te=>{var xe;const Be=he.has(te.id),Ue=te.amountBank;return g.jsxs("tr",{className:"hover:bg-neutral-50",children:[g.jsxs("td",{className:"px-3 py-3",children:[g.jsx("p",{className:"font-black text-neutral-800",children:te.employee}),(te.bankNameFile||te.bankAccountHolder)&&g.jsx("p",{className:"text-[10px] text-neutral-400 mt-1",children:[te.bankNameFile,te.bankAccountHolder].filter(Boolean).join(" · ")})]}),g.jsx("td",{className:"px-3 py-3 font-mono font-bold text-neutral-600",children:te.account||"—"}),g.jsx("td",{className:"px-3 py-3 text-right font-black text-neutral-700",children:Ue===null?"—":new Intl.NumberFormat(l.locale,{style:"currency",currency:l.currency,maximumFractionDigits:2}).format(Ue)}),g.jsx("td",{className:"px-3 py-3 text-neutral-600 max-w-[260px]",children:(xe=te.bestBambooCandidate)!=null&&xe.employeeName?g.jsxs("div",{children:[g.jsx("p",{className:"font-bold text-[#4F758B]",children:te.bestBambooCandidate.employeeName}),te.bestBambooCandidate.employeeNumber&&g.jsxs("p",{className:"text-[10px] text-neutral-400 mt-0.5",children:["Employee Number ",te.bestBambooCandidate.employeeNumber]})]}):g.jsx("span",{className:"text-neutral-400",children:"Sin candidato confiable"})}),g.jsx("td",{className:"px-3 py-3 text-center",children:Be?g.jsxs("span",{className:"inline-flex items-center gap-1.5 px-3 py-1.5 border border-emerald-200 bg-emerald-50 text-emerald-800 text-[10px] font-black uppercase tracking-wider",children:[g.jsx(kc,{className:"w-3.5 h-3.5"}),"Reportado a RRHH"]}):g.jsx("button",{type:"button",onClick:()=>Z(te),className:"inline-flex items-center gap-1.5 px-3 py-1.5 bg-[#6CC24A] hover:bg-[#5aaa3f] text-white text-[10px] font-black uppercase tracking-wider transition-colors",children:"Reportar a RRHH"})})]},te.id)})})]})}):g.jsx("div",{className:"py-12 text-center text-neutral-400 text-sm",children:"No hay casos guardados en este reporte."})]}),g.jsxs("div",{className:"border-t border-neutral-200 px-5 sm:px-6 py-4 flex items-center justify-between gap-3 flex-shrink-0",children:[g.jsxs("span",{className:"text-[10px] text-neutral-400",children:["ID del reporte: ",q.id]}),g.jsx("button",{type:"button",onClick:ke,className:"border border-neutral-300 bg-white px-4 py-2 text-xs font-bold text-neutral-600 hover:bg-neutral-50",children:"Cerrar"})]})]})})}),K&&q&&g.jsx(zw,{row:K,country:l,periodRange:en,operatorName:i,operatorEmail:a,executionId:q.id,reportUrl:q.reportUrl,onClose:()=>Z(null),onSuccess:te=>{fe(Be=>{const Ue=new Set(Be);return Ue.add(te),Ue})},onShowToast:n}),g.jsx(si,{children:N&&g.jsx(un.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:"fixed inset-0 z-[80] flex items-center justify-center bg-black/45 px-4",children:g.jsxs(un.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},exit:{opacity:0,y:12},className:"w-full max-w-lg bg-white border border-[#D0D0D0] shadow-xl",children:[g.jsxs("div",{className:"border-b border-neutral-200 px-5 py-4 flex items-center justify-between",children:[g.jsxs("div",{children:[g.jsx("h2",{className:"text-base font-black text-[#4F758B] uppercase tracking-tight",children:"Marcar reporte como resuelto"}),g.jsx("p",{className:"text-xs text-neutral-500 mt-1",children:N.period})]}),g.jsx("button",{onClick:()=>P(null),disabled:T,className:"p-2 text-neutral-400 hover:text-neutral-700 disabled:opacity-50","aria-label":"Cerrar",children:g.jsx(Ka,{className:"w-4 h-4"})})]}),g.jsxs("div",{className:"p-5 space-y-4",children:[g.jsx("div",{className:"bg-amber-50 border border-amber-200 text-amber-800 p-3 text-xs leading-relaxed",children:"Antes de resolver, confirma que las diferencias fueron revisadas y explica cómo se cerró el caso."}),g.jsxs("label",{className:"block",children:[g.jsx("span",{className:"text-[10px] uppercase tracking-wider font-black text-neutral-500",children:"Comentario de resolución"}),g.jsx("textarea",{value:G,onChange:te=>X(te.target.value),placeholder:"Ejemplo: Se corrigió la cuenta bancaria en nómina y se validó contra el banco.",className:"mt-2 w-full min-h-[130px] border border-[#D0D0D0] px-3 py-2 text-sm focus:outline-none focus:border-[#4F758B]"})]})]}),g.jsxs("div",{className:"border-t border-neutral-200 px-5 py-4 flex justify-end gap-3",children:[g.jsx("button",{onClick:()=>P(null),disabled:T,className:"border border-neutral-300 bg-white px-4 py-2 text-xs font-bold text-neutral-600 hover:bg-neutral-50 disabled:opacity-50",children:"Cancelar"}),g.jsxs("button",{onClick:is,disabled:T,className:"bg-[#4F758B] hover:bg-[#41677b] text-white px-4 py-2 text-xs font-black uppercase tracking-wider disabled:opacity-50 inline-flex items-center gap-2",children:[T&&g.jsx($a,{className:"w-4 h-4 animate-spin"}),"Confirmar resolución"]})]})]})})})]})}function Ud({message:n,type:e,onClose:i}){D.useEffect(()=>{const c=setTimeout(()=>{i()},2e3);return()=>clearTimeout(c)},[i]);const a={success:"bg-[#6CC24A] text-white border-l-4 border-emerald-700",error:"bg-[#ba1a1a] text-white border-l-4 border-red-800",info:"bg-[#4F758B] text-white border-l-4 border-slate-700"},l={success:kc,error:Tj,info:hw}[e];return g.jsx("div",{className:"fixed bottom-6 right-6 z-50 max-w-sm w-full",children:g.jsxs(un.div,{initial:{opacity:0,y:30,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:20,scale:.95},className:`flex items-center gap-3 p-4 shadow-lg rounded-md border border-neutral-200/10 ${a[e]}`,children:[g.jsx("span",{className:"flex-shrink-0",children:g.jsx(l,{className:"w-5 h-5"})}),g.jsx("div",{className:"flex-1 font-medium text-sm leading-tight pr-2",children:n}),g.jsx("button",{onClick:i,className:"flex-shrink-0 hover:bg-white/20 p-1 rounded transition-colors text-white",children:g.jsx(Ka,{className:"w-4 h-4"})})]})})}function eO({onShowToast:n}){const[e,i]=D.useState(!1),a=async()=>{if(!oo||!ut){n("El acceso con Google aún no está disponible. Contacta a IT.","error");return}i(!0),await gC();const{error:l}=await ut.auth.signInWithOAuth({provider:"google",options:{redirectTo:Lw(),queryParams:{access_type:"offline",prompt:"select_account"}}});l&&(i(!1),n("No se pudo iniciar sesión con Google. Intenta nuevamente.","error"))};return g.jsxs("div",{className:"min-h-screen w-full flex flex-col justify-between bg-[#F5F5F5] relative overflow-hidden font-sans",children:[g.jsx("div",{className:"h-1.5 w-full bg-[#4F758B]"}),g.jsx("div",{className:"flex-1 flex items-center justify-center p-4",children:g.jsxs(un.div,{initial:{opacity:0,y:15},animate:{opacity:1,y:0},transition:{duration:.5,ease:"easeOut"},className:"w-full max-w-md bg-white border border-[#D0D0D0] p-8 shadow-xl flex flex-col items-center gap-6",children:[g.jsx("div",{className:"w-full flex justify-center py-2",children:g.jsx("img",{alt:"Logo GOMEZLEE MARKETING",className:"h-14 object-contain",src:"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png",referrerPolicy:"no-referrer"})}),g.jsx("div",{className:"text-center w-full",children:g.jsx("h1",{className:"text-2xl font-bold text-[#4F758B] tracking-tight",children:"Portal de Cruce de Cuentas GLM"})}),g.jsx("button",{onClick:a,disabled:e||!oo,className:"w-full relative overflow-hidden flex items-center justify-center gap-3 bg-[#6CC24A] hover:bg-[#5bb03c] disabled:bg-neutral-300 disabled:cursor-not-allowed text-white font-semibold py-3.5 px-6 transition-all duration-150 transform active:scale-[0.99] select-none text-sm tracking-wide",children:e?g.jsxs("div",{className:"flex items-center gap-2",children:[g.jsxs("svg",{className:"animate-spin h-5 w-5 text-white",fill:"none",viewBox:"0 0 24 24",children:[g.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),g.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),g.jsx("span",{children:"Redirigiendo a Google..."})]}):g.jsxs(g.Fragment,{children:[g.jsxs("svg",{className:"w-5 h-5 flex-shrink-0 fill-current text-white",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[g.jsx("path",{d:"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"}),g.jsx("path",{d:"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"}),g.jsx("path",{d:"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"}),g.jsx("path",{d:"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"})]}),g.jsx("span",{children:"Continuar con Google"})]})}),!oo&&g.jsxs("div",{className:"w-full flex items-start gap-2 border border-amber-200 bg-amber-50 px-3 py-2 text-[11px] text-amber-800 leading-relaxed",children:[g.jsx(fo,{className:"w-4 h-4 mt-0.5 flex-shrink-0"}),g.jsx("span",{children:"El acceso con Google está pendiente de activación."})]})]})})]})}const tO="https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png";function nO({onSelect:n}){return g.jsxs("div",{className:"min-h-screen bg-[#F5F5F5] flex flex-col font-sans",children:[g.jsx("div",{className:"h-1.5 bg-[#6CC24A]"}),g.jsx("main",{className:"flex-1 flex items-center justify-center px-4 py-10",children:g.jsxs(un.section,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},className:"w-full max-w-3xl bg-white border border-[#D0D0D0] shadow-xl p-6 sm:p-9",children:[g.jsx("img",{src:tO,alt:"GomezLee Marketing",className:"h-14 object-contain mb-7"}),g.jsxs("div",{className:"flex items-start gap-3 mb-7",children:[g.jsx("div",{className:"bg-[#4F758B]/10 p-2.5 rounded-full",children:g.jsx(uw,{className:"w-5 h-5 text-[#4F758B]"})}),g.jsxs("div",{children:[g.jsx("h1",{className:"text-xl sm:text-2xl font-black text-[#4F758B] uppercase tracking-tight",children:"Selecciona el país"}),g.jsx("p",{className:"text-sm text-neutral-500 mt-1",children:"El portal cargará las reglas, la moneda y los reportes correspondientes."})]})]}),g.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",children:mo.map(e=>g.jsxs("button",{type:"button",disabled:!e.enabled,onClick:()=>e.enabled&&n(e.code),className:`text-left border p-5 transition-all min-h-[150px] flex flex-col justify-between ${e.enabled?"border-[#4F758B]/30 hover:border-[#4F758B] hover:shadow-md bg-white":"border-neutral-200 bg-neutral-50 cursor-not-allowed opacity-70"}`,children:[g.jsxs("div",{className:"flex items-start justify-between gap-3",children:[g.jsx("img",{src:e.flag,alt:"",className:"w-12 h-8 sm:w-16 sm:h-10 object-cover shadow-sm border border-neutral-200","aria-hidden":"true"}),e.enabled?g.jsx(pj,{className:"w-5 h-5 text-[#6CC24A]"}):g.jsx(qj,{className:"w-4 h-4 text-neutral-400"})]}),g.jsxs("div",{children:[g.jsx("p",{className:"font-black text-[#4F758B] uppercase tracking-wide",children:e.name}),g.jsx("p",{className:"text-xs text-neutral-500 mt-1",children:e.enabled?`Moneda ${e.currency}`:"Próximamente"})]})]},e.code))})]})})]})}const sO="cruce_cuentas_mi_acceso",xv=2;function $w(n){return(n??"").trim().toLowerCase()}function iO(n){return Array.isArray(n)?Array.from(new Set(n.map(e=>String(e??"").trim().toUpperCase()).filter(Boolean))):[]}function aO(n){const e=Array.isArray(n)?n[0]:n;if(!e||typeof e!="object")throw new Error("Supabase no devolvió una respuesta válida al comprobar el acceso.");return{ok:e.ok===!0,authenticated:e.autenticado===!0,authorized:e.autorizado===!0,email:$w(typeof e.email=="string"?e.email:""),name:typeof e.nombre=="string"?e.nombre.trim():"",active:e.activo===!0,appAccess:e.acceso_app===!0,historyAccess:e.acceso_historicos===!0,receivesGeneratedReports:e.recibe_reportes_generados===!0,receivesResolvedEmails:e.recibe_correos_resuelto===!0,countries:iO(e.paises),reason:typeof e.motivo=="string"?e.motivo.trim():""}}function rO(n){return new Promise(e=>window.setTimeout(e,n))}async function oO(){if(!ut)throw new Error("Supabase no está configurado.");let n=null;for(let i=1;i<=xv;i+=1){const{data:a,error:l}=await ut.rpc(sO);if(!l)return aO(a);n=l,i{if(typeof indexedDB>"u"){e(new Error("IndexedDB no está disponible en este navegador."));return}const i=indexedDB.open(lO,cO);i.onupgradeneeded=()=>{const a=i.result;a.objectStoreNames.contains(ns)||a.createObjectStore(ns,{keyPath:"sessionId"})},i.onsuccess=()=>n(i.result),i.onerror=()=>e(i.error??new Error("No se pudo abrir IndexedDB.")),i.onblocked=()=>e(new Error("La base local está bloqueada por otra pestaña."))}),Ra.catch(()=>{Ra=null}),Ra)}function hO(n){return new Promise((e,i)=>{n.onsuccess=()=>e(n.result),n.onerror=()=>i(n.error??new Error("Falló una operación local."))})}function Yc(n){return new Promise((e,i)=>{n.oncomplete=()=>e(),n.onerror=()=>i(n.error??new Error("Falló la transacción local.")),n.onabort=()=>i(n.error??new Error("La transacción local fue cancelada."))})}function dO(n){if(!n||typeof n!="object")return!1;const e=n;return e.version===qw&&typeof e.sessionId=="string"&&typeof e.updatedAt=="number"&&(e.currentView==="cruce"||e.currentView==="historial")&&Array.isArray(e.uploadedBankFiles)&&typeof e.isCruceExecuted=="boolean"}async function fO(n,e){const i=Date.now()-uO,a=n.transaction(ns,"readwrite"),l=Yc(a),u=a.objectStore(ns).openCursor();await new Promise((d,m)=>{u.onsuccess=()=>{const p=u.result;if(!p){d();return}const y=p.value;y.sessionId!==e&&typeof y.updatedAt=="number"&&y.updatedAtm(u.error??new Error("No se pudieron limpiar borradores antiguos."))}),await l}async function mO(){const n=nm();try{const e=await sm(),i=e.transaction(ns,"readonly"),a=Yc(i),l=await hO(i.objectStore(ns).get(n));return await a,fO(e,n).catch(()=>{}),dO(l)?l:null}catch{return null}}function pO(n){const e=nm(),i={...n,version:qw,sessionId:e,updatedAt:Date.now()};return Fa=Fa.catch(()=>{}).then(async()=>{const l=(await sm()).transaction(ns,"readwrite"),c=Yc(l);l.objectStore(ns).put(i),await c}).catch(()=>{}),Fa}function Tv(){const n=nm();return Fa=Fa.catch(()=>{}).then(async()=>{const i=(await sm()).transaction(ns,"readwrite"),a=Yc(i);i.objectStore(ns).delete(n),await a}).catch(()=>{}),Fa}const Ev=!0,Sf="glm_cruce_selected_country",gO={name:"Isaac Aracena",email:"iaracena@gomezleemarketing.com"};function yO(n){const e=(n==null?void 0:n.user_metadata)??{},i=e.full_name||e.name||e.display_name;if(i)return String(i);const a=String((n==null?void 0:n.email)??"Usuario GLM");return a.includes("@")?a.split("@")[0]:a}function bO(){try{const n=window.localStorage.getItem(Sf),e=mo.find(i=>i.code===n&&i.enabled);return(e==null?void 0:e.code)??null}catch{return null}}function vO(){const[n,e]=D.useState("cruce"),[i,a]=D.useState(!1),[l,c]=D.useState(null),[u,d]=D.useState([]),[m,p]=D.useState([]),[y,v]=D.useState(!1),[x,_]=D.useState(null),[S,T]=D.useState(0),[k,R]=D.useState(()=>bO()),[M,N]=D.useState(null),[P,G]=D.useState(Ev),[X,q]=D.useState(!1),[Y,se]=D.useState(null),J=D.useRef(0),he=D.useMemo(()=>oo&&ut,[]),fe=k?_b(k):null,Ae=(ie,E)=>{se({message:ie,type:E})};D.useEffect(()=>{if(!he||!ut){G(!1);return}let ie=!0;const E=async Q=>{const oe=++J.current;if(!(Q!=null&&Q.email)){ie&&oe===J.current&&N(null);return}try{const re=await oO();if(!ie||oe!==J.current)return;const _e=$w(Q.email),ke=!!re.email&&re.email===_e;if(!re.ok||!re.authenticated||!re.authorized||!re.active||!re.appAccess||!ke){N(null),Ae(re.reason||"Tu usuario no tiene acceso autorizado a este módulo.","error"),ut.auth.signOut();return}N({name:re.name||yO(Q),email:_e})}catch(re){if(!ie||oe!==J.current)return;console.error("No se pudo validar el acceso en Supabase:",re),N(null),Ae("No se pudo validar tu acceso en Supabase. Intenta iniciar sesión nuevamente.","error"),ut.auth.signOut()}};(async()=>{var Q;try{const{data:oe,error:re}=await ut.auth.getSession();if(re)throw re;if(!ie)return;await E((Q=oe.session)==null?void 0:Q.user)}catch(oe){if(!ie)return;console.error("No se pudo recuperar la sesión de Supabase:",oe),N(null),Ae("No se pudo recuperar tu sesión. Intenta iniciar sesión nuevamente.","error")}finally{ie&&G(!1)}})();const{data:W}=ut.auth.onAuthStateChange((Q,oe)=>{if(ie){if(oe!=null&&oe.user){window.setTimeout(()=>{ie&&E(oe.user)},0);return}Q==="SIGNED_OUT"&&(J.current+=1,N(null),G(!1))}});return()=>{ie=!1,J.current+=1,W.subscription.unsubscribe()}},[he]),D.useEffect(()=>{if(!he||!ut)return;let ie=0;const E=()=>{if(document.visibilityState!=="visible")return;const H=Date.now();H-ie<5e3||(ie=H,So(300).catch(W=>{console.warn("No se pudo revalidar la sesión al reanudar la pestaña:",W)}))};return document.addEventListener("visibilitychange",E),window.addEventListener("focus",E),()=>{document.removeEventListener("visibilitychange",E),window.removeEventListener("focus",E)}},[he]),D.useEffect(()=>{let ie=!0;return(async()=>{const H=await mO();ie&&(H&&(!k||H.countryCode===k?(H.countryCode&&R(H.countryCode),e(H.currentView),c(H.uploadedPayroll),d(Array.isArray(H.uploadedPayrollFiles)?H.uploadedPayrollFiles:[]),p(H.uploadedBankFiles),v(H.isCruceExecuted),_(H.cruceResponse)):await Tv()),ie&&q(!0))})(),()=>{ie=!1}},[]),D.useEffect(()=>{X&&pO({countryCode:k,currentView:n,uploadedPayroll:l,uploadedPayrollFiles:u,uploadedBankFiles:m,isCruceExecuted:y,cruceResponse:x})},[X,k,n,l,u,m,y,x]);const ve=()=>{c(null),d([]),p([]),v(!1),_(null),T(ie=>ie+1)},Ce=async()=>{await Tv(),ut&&await ut.auth.signOut(),N(null),R(null),window.localStorage.removeItem(Sf),ve(),e("cruce"),Ae("Sesión cerrada correctamente.","success")},L=()=>{ve(),e("cruce"),Ae("Nuevo cruce iniciado.","success")},K=ie=>{const E=_b(ie);if(!E.enabled){Ae(`${E.name} estará disponible próximamente.`,"info");return}k&&k!==ie&&ve(),R(ie),window.localStorage.setItem(Sf,ie),e("cruce"),a(!1)},Z=()=>{R(null),a(!1)};if(P)return g.jsx("div",{className:"min-h-screen bg-[#F5F5F5] flex items-center justify-center text-[#4F758B] font-black uppercase tracking-wider",children:"Validando acceso..."});if(!M)return g.jsxs(g.Fragment,{children:[g.jsx(eO,{onShowToast:Ae}),g.jsx(si,{children:Y&&g.jsx(Ud,{message:Y.message,type:Y.type,onClose:()=>se(null)})})]});if(!fe)return g.jsxs(g.Fragment,{children:[g.jsx(nO,{onSelect:K}),g.jsx(si,{children:Y&&g.jsx(Ud,{message:Y.message,type:Y.type,onClose:()=>se(null)})})]});const pe=M??gO;return g.jsxs("div",{className:"min-h-screen bg-[#F5F5F5] selection:bg-[#6CC24A] selection:text-white antialiased font-sans flex flex-col",children:[g.jsxs(un.div,{initial:{opacity:0},animate:{opacity:1},className:"min-h-screen flex w-full relative overflow-x-hidden",children:[g.jsx(si,{children:i&&g.jsx(un.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},onClick:()=>a(!1),className:"fixed inset-0 bg-black/45 z-45 md:hidden"},"backdrop")}),g.jsx(lN,{currentView:n,onViewChange:ie=>{e(ie),a(!1)},onNewCruce:()=>{L(),a(!1)},isSidebarOpen:i,onCloseSidebar:()=>a(!1),user:pe,isAuthEnabled:Ev,onLogout:Ce,country:fe,onCountryChange:K,onChooseAnotherCountry:Z}),g.jsx("div",{className:"pl-0 md:pl-64 flex-1 flex flex-col w-full min-h-screen transition-all duration-300",children:g.jsx(si,{mode:"wait",children:n==="cruce"?g.jsx(un.div,{initial:{opacity:0,x:10},animate:{opacity:1,x:0},exit:{opacity:0,x:-10},transition:{duration:.2},className:"flex-1 flex flex-col",children:g.jsx(qC,{onShowToast:Ae,uploadedPayroll:l,setUploadedPayroll:c,uploadedPayrollFiles:u,setUploadedPayrollFiles:d,uploadedBankFiles:m,setUploadedBankFiles:p,isCruceExecuted:y,setIsCruceExecuted:v,response:x,setResponse:_,onOpenSidebar:()=>a(!0),operatorName:pe.name,operatorEmail:pe.email,resetToken:S,country:fe})},`view-cruce-${fe.code}`):g.jsx(un.div,{initial:{opacity:0,x:10},animate:{opacity:1,x:0},exit:{opacity:0,x:-10},transition:{duration:.2},className:"flex-1 flex flex-col",children:g.jsx(WC,{onShowToast:Ae,onOpenSidebar:()=>a(!0),operatorName:pe.name,operatorEmail:pe.email,country:fe})},`view-history-${fe.code}`)})})]},`interface-${fe.code}`),g.jsx(si,{children:Y&&g.jsx(Ud,{message:Y.message,type:Y.type,onClose:()=>se(null)})})]})}window.addEventListener("pageshow",n=>{n.persisted&&window.location.reload()});l1.createRoot(document.getElementById("root")).render(g.jsx(D.StrictMode,{children:g.jsx(vO,{})})); diff --git a/dist/index.html b/dist/index.html index 6abbf14..db1b070 100644 --- a/dist/index.html +++ b/dist/index.html @@ -9,8 +9,8 @@ Portal de Cruce de Cuentas GLM - - + +
diff --git a/src/components/BambooCorrectionModal.tsx b/src/components/BambooCorrectionModal.tsx index 4027da8..74ff4d5 100644 --- a/src/components/BambooCorrectionModal.tsx +++ b/src/components/BambooCorrectionModal.tsx @@ -69,6 +69,7 @@ export default function BambooCorrectionModal({ if (country.code === 'SV') return 'Carlos Antonio Malta Méndez'; if (country.code === 'HN') return 'Melody Chang Blandin'; if (country.code === 'PR') return 'Noralmy Laureano'; + if (country.code === 'RD') return 'Noralmy Laureano'; return 'haguirre@gomezleemarketing.com'; }, [country.code]); diff --git a/src/components/Dashboard.tsx b/src/components/Dashboard.tsx index 720c1af..407208e 100644 --- a/src/components/Dashboard.tsx +++ b/src/components/Dashboard.tsx @@ -105,6 +105,13 @@ function getReconciliationUrl(countryCode: string) { ); } + if (countryCode === 'RD') { + return ( + (import.meta.env.VITE_N8N_REPUBLICA_DOMINICANA_WEBHOOK_URL as string | undefined) || + 'https://agenteit.digitalcompass.agency/webhook/nominard-bamboo-test' + ); + } + return ( (import.meta.env.VITE_N8N_GUATEMALA_WEBHOOK_URL as string | undefined) || (import.meta.env.VITE_N8N_WEBHOOK_URL as string | undefined) || @@ -382,15 +389,32 @@ function normalizeWebhookResponse(payload: unknown): ReconciliationResponse { primaryRows.filter((row) => normalizeText(String(row.category ?? '')).includes('posible_cuenta_mal_digitada')).length ); - const totalPending = + const responseMetadata = + (original.metadata ?? item.metadata ?? {}) as Record; + const responseCountry = String( + responseMetadata.country ?? responseMetadata.country_code ?? '' + ).toUpperCase(); + const defaultTotalPending = discrepancies + bankWithoutPayroll + bankWithoutBamboo + payrollWithoutAccount + nameDifferences; - - const responseMetadata = - (original.metadata ?? item.metadata ?? {}) as Record; + const rdTotalPending = + discrepancies + + bankWithoutPayroll + + payrollWithoutAccount + + nameDifferences + + possibleWrongAccounts; + const totalPending = responseCountry === 'RD' + ? toNumber( + rawSummary.totalPending ?? + rawSummary.pendientes ?? + rawSummary.pendientes_cruce_principal ?? + rawSummary.total_pending, + rdTotalPending + ) + : defaultTotalPending; const responsePeriodType = String( responseMetadata.period_type ?? responseMetadata.periodType ?? '' ).toLowerCase(); @@ -675,7 +699,7 @@ const MONTH_ALIASES: Record = { 12: ['diciembre', 'december', 'dec'], }; -function detectPeriodFromPayrollFilename(fileName: string): Partial { +function detectPeriodFromPayrollFilename(fileName: string, countryCode?: CountryCode): Partial { const normalized = normalizeText(fileName) .replace(/[_\-.()]+/g, ' ') .replace(/\s+/g, ' ') @@ -712,6 +736,11 @@ function detectPeriodFromPayrollFilename(fileName: string): Partial isRepublicaDominicana ? (isCsvFile(file) || isPdfFile(file)) : isPuertoRico ? isPdfFile(file) : isCsvFile(file); const [isProcessing, setIsProcessing] = useState(false); const [processingStep, setProcessingStep] = useState(''); const [filterMode, setFilterMode] = useState< @@ -1098,7 +1129,7 @@ export default function Dashboard({ const handleBankDrop = (e: React.DragEvent) => { e.preventDefault(); const files = Array.from(e.dataTransfer.files) as File[]; - const validBankFiles = files.filter(isPuertoRico ? isPdfFile : isCsvFile); + const validBankFiles = files.filter(isValidBankFile); if (validBankFiles.length === 0) { onShowToast( @@ -1143,7 +1174,7 @@ export default function Dashboard({ const files = e.target.files; if (!files || files.length === 0) return; - const validBankFiles = (Array.from(files) as File[]).filter(isPuertoRico ? isPdfFile : isCsvFile); + const validBankFiles = (Array.from(files) as File[]).filter(isValidBankFile); if (validBankFiles.length === 0) { onShowToast( @@ -1283,7 +1314,7 @@ export default function Dashboard({ setCurrentPage(1); try { - const duplicatedShipments = isPuertoRico + const duplicatedShipments = (isPuertoRico || isRepublicaDominicana) ? [] : await findDuplicateBankShipments(uploadedBankFiles); if (duplicatedShipments.length > 0) { @@ -1689,7 +1720,7 @@ export default function Dashboard({ - {(isMultiPayrollCountry || isHonduras || isPuertoRico) && + {(isMultiPayrollCountry || isHonduras || isPuertoRico || isRepublicaDominicana) && (uploadedPayroll !== null || uploadedPayrollFiles.length > 0 || uploadedBankFiles.length > 0) && (
-
- +
+
+ + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + {paginatedRows.length > 0 ? ( paginatedRows.map((row) => ( - - - - - - - + + + + + + - - - + + \n `;\n}\n\nconst countryCode = 'PR';\nconst countryName = 'Puerto Rico';\n\nconst periodLabel =\n payload.period_label ||\n metadata.period_label ||\n [\n payload.year || metadata.year,\n payload.month || metadata.month,\n payload.period_type || metadata.period_type,\n ]\n .filter(Boolean)\n .join(' · ') ||\n 'Período no especificado';\n\nconst executedByName =\n payload.ejecutado_por_nombre ||\n metadata.requested_by_name ||\n 'Usuario GLM';\n\nconst executedByEmail =\n payload.ejecutado_por_email ||\n metadata.requested_by_email ||\n '';\n\nconst reportUrl =\n payload.report_url ||\n prepared.reportUrl ||\n '';\n\nconst discrepancias = numberValue(\n payload.discrepancias ??\n summary.discrepancias\n);\n\nconst bancoSinNomina = numberValue(\n payload.banco_sin_nomina ??\n summary.bancoSinNomina\n);\n\nconst bancoSinBamboo = numberValue(\n payload.banco_sin_bamboo ??\n summary.bancoSinBamboo\n);\n\nconst diferenciasNombreBanco = numberValue(\n metadata.diferencias_nombre_banco ??\n summary.diferenciasNombreBanco\n);\n\nconst nominaSinCuenta = numberValue(\n payload.nomina_sin_cuenta ??\n summary.nominaSinCuenta\n);\n\nconst coincidencias = numberValue(\n payload.coincidencias ??\n summary.coincidencias\n);\n\nconst generatedAt = new Date();\nconst generatedAtLabel =\n formatGeneratedAt(generatedAt);\n\nconst statusLabel =\n String(payload.estado || '').toLowerCase() === 'resuelto'\n ? 'Resuelto'\n : 'Pendiente de revisión';\n\nconst logoUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png';\n\nconst flagUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/bandera-nacional-tela-puerto-rico_113767-1759.avif';\n\nconst subject = reportUpdated\n ? `Reporte actualizado - Cruce de Cuentas ${countryName} - ${periodLabel}`\n : `Nuevo reporte generado - Cruce de Cuentas ${countryName} - ${periodLabel}`;\n\n/*\n * Todos son destinatarios directos.\n * Nadie se envía en CC.\n */\n\nconst to = [\n 'iaracena@gomezleemarketing.com',\n 'jgomez@gomezleemarketing.com',\n 'mgomez@gomezleemarketing.com',\n 'vparamo@gomezleemarketing.com',\n 'ymadera@gomezleemarketing.com',\n 'adminregional@gomezleemarketing.com',\n].join(',');\n\n\n// Paleta oficial GLM.\nconst metricCards = [\n metricCard(\n 'Discrepancias',\n discrepancias,\n '#FF6A13'\n ),\n metricCard(\n 'Banco sin nómina',\n bancoSinNomina,\n '#FF8C00'\n ),\n metricCard(\n 'Banco sin Bamboo',\n bancoSinBamboo,\n '#E87722'\n ),\n metricCard(\n 'Diferencias nombre banco',\n diferenciasNombreBanco,\n '#5B7F95'\n ),\n metricCard(\n 'Nómina sin cuenta',\n nominaSinCuenta,\n '#4F758B'\n ),\n].join('');\n\nconst htmlBody = `\n\n\n\n\n \n \n ${escapeHtml(subject)}\n\n\n\n\n \n \n \n \n  \n \n \n\n \n \n \n\n \n \n \n\n \n \n ${reportUpdated ? 'REPORTE ACTUALIZADO' : 'REPORTE GENERADO'}\n \n \n \n
EmpleadoEmployee NumberCuenta{isBonus14Result ? 'Monto Bono 14' : 'Monto Nómina'}Monto BancoDiferenciaEstadoCategoríaObservaciónAccionesEmpleadoEmployee NumberCuenta{isBonus14Result ? 'Monto Bono 14' : 'Monto Nómina'}Monto BancoDiferenciaEstadoCategoríaObservaciónAcciones
{row.employee}{row.employeeNumber || '—'}{row.account ?? '—'}{formatCurrency(row.amountPayroll, country, row.currency)}{formatCurrency(row.amountBank, country, row.currency)}{formatCurrency(row.difference, country, row.currency)} - + {row.employee}{row.employeeNumber || '—'}{row.account ?? '—'}{formatCurrency(row.amountPayroll, country, row.currency)}{formatCurrency(row.amountBank, country, row.currency)}{formatCurrency(row.difference, country, row.currency)} + {row.status} {formatCategory(row.category ?? row.source, response?.reportKind ?? 'nomina')}{row.observation} + {formatCategory(row.category ?? row.source, response?.reportKind ?? 'nomina')}{row.observation} {isSourceRow(row, 'banco_sin_bamboo') ? ( reportedBambooRows.has(row.id) ? ( @@ -2366,7 +2409,7 @@ export default function Dashboard({ diff --git a/src/components/History.tsx b/src/components/History.tsx index 0af92d9..9026c78 100644 --- a/src/components/History.tsx +++ b/src/components/History.tsx @@ -61,6 +61,13 @@ function getHistoryUrl(countryCode: string) { ); } + if (countryCode === 'RD') { + return ( + (import.meta.env.VITE_HISTORICOS_RD_URL as string | undefined) || + 'https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-rd-historicos' + ); + } + return ( (import.meta.env.VITE_HISTORICOS_GT_URL as string | undefined) || 'https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-gt-historicos' @@ -100,6 +107,13 @@ function getMarkResolvedUrl(countryCode: string) { ); } + if (countryCode === 'RD') { + return ( + (import.meta.env.VITE_MARCAR_RESUELTO_RD_URL as string | undefined) || + 'https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-rd-marcar-resuelto' + ); + } + return ( (import.meta.env.VITE_MARCAR_RESUELTO_GT_URL as string | undefined) || 'https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-gt-marcar-resuelto' @@ -164,18 +178,45 @@ function normalizeReports(input: unknown, country: CountryConfig): HistoricalRep const payrollWithoutAccount = toNumber( report.nominaSinCuenta ?? report.nomina_sin_cuenta ?? report.payrollWithoutAccount ); + const reportMetadata = + report.metadata && typeof report.metadata === 'object' && !Array.isArray(report.metadata) + ? report.metadata as Record + : {}; + const reportSummary = + report.summary && typeof report.summary === 'object' && !Array.isArray(report.summary) + ? report.summary as Record + : {}; const nameDifferences = toNumber( report.diferenciasNombreBanco ?? report.diferencias_nombre_banco ?? - report.nameDifferences + report.nameDifferences ?? + reportMetadata.diferencias_nombre_banco ?? + reportSummary.diferenciasNombreBanco ); - const totalPending = + const possibleWrongAccounts = toNumber( + report.posiblesCuentasMalDigitadas ?? + report.posibles_cuentas_mal_digitadas ?? + report.possibleWrongAccounts ?? + reportMetadata.posibles_cuentas_mal_digitadas ?? + reportSummary.posiblesCuentasMalDigitadas + ); + const calculatedTotalPending = discrepancies + bankWithoutPayroll + bankWithoutBamboo + payrollWithoutAccount + nameDifferences; const rawCountry = String(report.country ?? report.pais ?? report.country_code ?? country.code).toUpperCase(); + const totalPending = rawCountry === 'RD' + ? toNumber( + report.pendientes ?? + report.total_pending ?? + report.totalPending ?? + reportMetadata.pendientes_cruce_principal ?? + reportSummary.pendientes, + discrepancies + bankWithoutPayroll + payrollWithoutAccount + nameDifferences + possibleWrongAccounts + ) + : calculatedTotalPending; const bankFiles = Array.isArray(report.archivosBanco) ? report.archivosBanco.map(String) : Array.isArray(report.bank_file_names) @@ -185,7 +226,7 @@ function normalizeReports(input: unknown, country: CountryConfig): HistoricalRep return { id: String(report.id ?? `reporte-${index + 1}`), - country: (rawCountry === 'TT' ? 'TT' : rawCountry === 'PA' ? 'PA' : rawCountry === 'SV' ? 'SV' : rawCountry === 'HN' ? 'HN' : rawCountry === 'PR' ? 'PR' : 'GT') as HistoricalReport['country'], + country: (rawCountry === 'TT' ? 'TT' : rawCountry === 'PA' ? 'PA' : rawCountry === 'SV' ? 'SV' : rawCountry === 'HN' ? 'HN' : rawCountry === 'PR' ? 'PR' : rawCountry === 'RD' ? 'RD' : 'GT') as HistoricalReport['country'], date: formatDate(report.fecha ?? report.period_end ?? rawExecutionDate, country.locale), executionDate: formatDateTime(rawExecutionDate, country.locale), period: String(report.periodo ?? report.period_label ?? report.period ?? 'Período no especificado'), @@ -499,7 +540,7 @@ export default function History({ if (!isCurrentRequest()) return; // Respaldo temporal: webhook histórico existente. También se envía el país - // para impedir que se mezclen reportes de Guatemala, Trinidad y Tobago, Panamá, El Salvador, Honduras y Puerto Rico. + // para impedir que se mezclen reportes de Guatemala, Trinidad y Tobago, Panamá, El Salvador, Honduras, Puerto Rico y República Dominicana. const historyUrl = getHistoryUrl(country.code); if (!historyUrl) { throw new Error(`No está configurado el origen histórico de ${country.name}.`); @@ -834,19 +875,30 @@ export default function History({ )}
-
- +
+
+ + + + + + + + + + + - - - - - - - - - + + + + + + + + + @@ -867,7 +919,7 @@ export default function History({ animate={{ opacity: 1 }} className="hover:bg-neutral-50/70 transition-colors" > - - - + - - + - - - - diff --git a/src/config/countries.ts b/src/config/countries.ts index 58551b7..39dbfc9 100644 --- a/src/config/countries.ts +++ b/src/config/countries.ts @@ -49,6 +49,14 @@ export const COUNTRIES: CountryConfig[] = [ locale: 'es-PR', enabled: true, }, + { + code: 'RD', + name: 'República Dominicana', + flag: 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_the_Dominican_Republic.svg.webp', + currency: 'DOP', + locale: 'es-DO', + enabled: true, + }, ]; export const DEFAULT_COUNTRY_CODE: CountryCode = 'GT'; diff --git a/src/types.ts b/src/types.ts index 52535cc..d0067ae 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,7 +4,7 @@ export type ViewType = 'cruce' | 'historial'; export type ToastType = 'success' | 'error' | 'info'; -export type CountryCode = 'GT' | 'TT' | 'PA' | 'SV' | 'HN' | 'PR'; +export type CountryCode = 'GT' | 'TT' | 'PA' | 'SV' | 'HN' | 'PR' | 'RD'; export interface CountryConfig { code: CountryCode; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index e9ca1bc..b89d9fa 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -8,6 +8,7 @@ interface ImportMetaEnv { readonly VITE_N8N_EL_SALVADOR_WEBHOOK_URL?: string; readonly VITE_N8N_HONDURAS_WEBHOOK_URL?: string; readonly VITE_N8N_PUERTO_RICO_WEBHOOK_URL?: string; + readonly VITE_N8N_REPUBLICA_DOMINICANA_WEBHOOK_URL?: string; readonly VITE_HISTORICOS_GT_URL?: string; readonly VITE_MARCAR_RESUELTO_GT_URL?: string; readonly VITE_HISTORICOS_TT_URL?: string; @@ -20,6 +21,8 @@ interface ImportMetaEnv { readonly VITE_MARCAR_RESUELTO_HN_URL?: string; readonly VITE_HISTORICOS_PR_URL?: string; readonly VITE_MARCAR_RESUELTO_PR_URL?: string; + readonly VITE_HISTORICOS_RD_URL?: string; + readonly VITE_MARCAR_RESUELTO_RD_URL?: string; readonly VITE_ANALIZAR_NOMINA_URL?: string; readonly VITE_REPORTAR_BAMBOO_URL?: string; readonly VITE_REPORTAR_APP_URL?: string; diff --git a/workflows_n8n/Portal de Verificaci├│n de N├│mina - Analizar N├│mina con Gemini GT TT PA SV HN PR RD.json b/workflows_n8n/Portal de Verificaci├│n de N├│mina - Analizar N├│mina con Gemini GT TT PA SV HN PR RD.json new file mode 100644 index 0000000..1a17d04 --- /dev/null +++ b/workflows_n8n/Portal de Verificaci├│n de N├│mina - Analizar N├│mina con Gemini GT TT PA SV HN PR RD.json @@ -0,0 +1,280 @@ +{ + "name": "Portal de Verificación de Nómina - Analizar Nómina con Gemini GT TT PA SV HN PR RD", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "cruce-cuentas-analizar-nomina", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + 9584, + 4944 + ], + "id": "e5ca8880-286c-488d-9206-bf9e2d4ffe57", + "name": "Webhook - Analizar Nómina", + "webhookId": "db2d6a91-6fef-4c86-8409-ccf89dc52cb5" + }, + { + "parameters": { + "jsCode": "const input = $input.first().json || {};\n\nlet body = input.body ?? input;\n\nif (typeof body === 'string') {\n try {\n body = JSON.parse(body);\n } catch (error) {\n body = {};\n }\n}\n\nif (!body || typeof body !== 'object' || Array.isArray(body)) {\n body = {};\n}\n\nfunction clean(value) {\n return String(value ?? '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst fileName = clean(\n body.fileName ??\n body.filename ??\n body.file_name ??\n ''\n);\n\nconst country = clean(\n body.country ?? 'GT'\n).toUpperCase();\n\nconst supportedCountries = {\n GT: 'Guatemala',\n TT: 'Trinidad y Tobago',\n PA: 'Panamá',\n SV: 'El Salvador',\n HN: 'Honduras',\n PR: 'Puerto Rico',\n RD: 'República Dominicana',\n};\n\nconst countryName = clean(\n body.countryName ??\n body.country_name ??\n supportedCountries[country] ??\n ''\n);\n\nconst errors = [];\n\nif (!fileName) {\n errors.push(\n 'No se recibió el nombre del archivo de nómina.'\n );\n}\n\nif (!Object.prototype.hasOwnProperty.call(\n supportedCountries,\n country\n)) {\n errors.push(\n 'El analizador solo está habilitado para Guatemala, Trinidad y Tobago, Panamá, El Salvador, Honduras, Puerto Rico y República Dominicana.'\n );\n}\n\nconst supportedExtensions = [\n '.xlsx',\n '.xls',\n '.xlsm',\n '.csv',\n];\n\nconst lowerFileName = fileName.toLowerCase();\n\nconst hasSupportedExtension =\n supportedExtensions.some((extension) =>\n lowerFileName.endsWith(extension)\n );\n\nif (fileName && !hasSupportedExtension) {\n errors.push(\n 'El archivo recibido no tiene una extensión de nómina compatible.'\n );\n}\n\nreturn [\n {\n json: {\n ok: errors.length === 0,\n errors,\n\n fileName,\n country,\n countryName:\n countryName ||\n supportedCountries[country] ||\n '',\n\n receivedAt: new Date().toISOString(),\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 9792, + 4944 + ], + "id": "1505f1bd-6588-4de3-9924-e7c6d49199b6", + "name": "Validar y preparar solicitud" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "bd9fd675-d72b-4dba-ac03-a44f1123ecb0", + "leftValue": "={{ $json.ok }}", + "rightValue": "", + "operator": { + "type": "boolean", + "operation": "true", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + 10000, + 4944 + ], + "id": "6beff621-5a05-4b68-958d-8893c849f93d", + "name": "¿Solicitud válida?" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{\n{\n ok: false,\n message:\n 'No fue posible analizar el nombre del archivo.',\n errors: Array.isArray($json.errors)\n ? $json.errors\n : ['La solicitud recibida no es válida.'],\n detected: null\n}\n}}", + "options": { + "responseCode": 400, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 10208, + 5040 + ], + "id": "0a892ee2-ed32-42e5-8071-513eda810b6f", + "name": "Responder error" + }, + { + "parameters": { + "text": "={{\n`Analiza este nombre de archivo de nómina:\n\nPaís seleccionado: ${$json.countryName}\nCódigo del país: ${$json.country}\nNombre del archivo: ${$json.fileName}`\n}}", + "schemaType": "manual", + "inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"country\": {\n \"type\": \"string\",\n \"enum\": [\n \"GT\",\n \"TT\",\n \"PA\",\n \"SV\",\n \"HN\",\n \"PR\",\n \"RD\"\n ]\n },\n \"year\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"maximum\": 2100\n },\n \"month\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"maximum\": 12\n },\n \"period_type\": {\n \"type\": \"string\",\n \"enum\": [\n \"quincena_15\",\n \"quincena_30\",\n \"mensual\",\n \"desconocido\"\n ]\n },\n \"confidence\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 1\n },\n \"explanation\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"country\",\n \"year\",\n \"month\",\n \"period_type\",\n \"confidence\",\n \"explanation\"\n ],\n \"additionalProperties\": false\n}", + "options": { + "systemPromptTemplate": "Eres un clasificador determinista de nombres de archivos de nómina.\n\nTu tarea es identificar el país seleccionado, el año, el mes y el período de pago utilizando únicamente la información presente en el nombre del archivo y el país recibido.\n\nNo inventes datos que no estén contenidos o razonablemente codificados en el nombre.\n\nREGLAS GENERALES:\n\n1. Devuelve exactamente el código de país recibido:\n - GT para Guatemala.\n - TT para Trinidad y Tobago.\n - PA para Panamá.\n - SV para El Salvador.\n - HN para Honduras.\n - PR para Puerto Rico.\n - RD para República Dominicana.\n\n2. Detecta el año de cuatro dígitos. También puede aparecer dentro de una fecha compacta como YYYYMMDD; por ejemplo, 20260617 representa el año 2026.\n\n3. Convierte el mes a un número aceptando nombres en español o inglés:\n Enero / January = 1\n Febrero / February = 2\n Marzo / March = 3\n Abril / April = 4\n Mayo / May = 5\n Junio / June = 6\n Julio / July = 7\n Agosto / August = 8\n Septiembre / September = 9\n Octubre / October = 10\n Noviembre / November = 11\n Diciembre / December = 12\n\n4. Usa period_type = quincena_15 cuando aparezca cualquiera de estas señales:\n - 1Q\n - Q1\n - Primera quincena\n - 1ra quincena\n - First fortnight\n - First half\n - Mid month\n - Día 15\n - 15th\n\n5. Usa period_type = quincena_30 cuando aparezca cualquiera de estas señales:\n - 2Q\n - Q2\n - Segunda quincena\n - 2da quincena\n - Second fortnight\n - Second half\n - Fin de mes\n - End of month\n - Month end\n - Día 30\n - Día 31\n - 30th\n - 31st\n - El último día real del mes, incluyendo 28 o 29 de febrero\n\n6. Aunque el último día real del mes no sea 30, utiliza quincena_30 para representar la segunda quincena o cierre de mes.\n\n7. Si solamente aparecen el mes y el año, sin ninguna señal de quincena ni día de cierre, utiliza mensual.\n\n8. Para nombres como \"GLM_TT_Payroll June 30TH_20260617.xlsx\":\n - country = TT\n - year = 2026\n - month = 6\n - period_type = quincena_30\n\n9. Para República Dominicana reconoce nombres como \"GLM_Nomina Field Force Claro, Whirpool, Purina & Latam RD Febrero 28 2026_202602018.xlsx\": país RD, mes 2 y quincena_30 porque el día 28 es el último día real de febrero. También reconoce día 30 como quincena_30 y día 15 como quincena_15.\n\n10. Para Honduras también reconoce nombres como \"Nomina 7.1 2026 GLM HN.xlsx\" (mes 7, primera quincena) y \"Nomina 7.2 2026 GLM HN.xlsx\" (mes 7, segunda quincena). En general, cuando ese patrón forma parte del nombre de nómina, M.1 = quincena_15 y M.2 = quincena_30.\n\n11. Si no puedes identificar de manera confiable el año o el mes, utiliza:\n year = 0\n month = 0\n period_type = desconocido\n\n12. confidence debe estar entre 0 y 1.\n\n13. explanation debe ser breve y mencionar las señales encontradas en el nombre.\n\nNo agregues campos diferentes a los definidos por el esquema." + } + }, + "type": "@n8n/n8n-nodes-langchain.informationExtractor", + "typeVersion": 1.2, + "position": [ + 10208, + 4672 + ], + "id": "6a8a7596-86c6-462a-a5a6-a1f336cbd62b", + "name": "Extraer período con Gemini", + "retryOnFail": true, + "waitBetweenTries": 2000, + "onError": "continueRegularOutput" + }, + { + "parameters": { + "modelName": "models/gemini-2.5-pro", + "options": {} + }, + "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", + "typeVersion": 1.1, + "position": [ + 10208, + 4848 + ], + "id": "cdf54d68-9273-4af5-8b94-b9a7c24b7ba5", + "name": "Gemini - Analizar título nómina", + "credentials": { + "googlePalmApi": { + "id": "jvsXYwL6IOoY2DBU", + "name": "Isaac - Gemini Api Pago" + } + } + }, + { + "parameters": { + "jsCode": "const request =\n $('Validar y preparar solicitud').first().json || {};\n\nconst incoming = $input.first().json || {};\n\nfunction cleanText(value) {\n return String(value ?? '')\n .replace(/\\uFEFF/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalizeText(value) {\n return cleanText(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[_\\-.,()[\\]{}]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction parseObject(value) {\n if (\n value &&\n typeof value === 'object' &&\n !Array.isArray(value)\n ) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return {};\n }\n\n const cleaned = value\n .replace(/```json/gi, '')\n .replace(/```/g, '')\n .trim();\n\n try {\n return JSON.parse(cleaned);\n } catch (error) {\n return {};\n }\n}\n\nfunction clamp(value, minimum, maximum) {\n const number = Number(value);\n\n if (!Number.isFinite(number)) {\n return minimum;\n }\n\n return Math.min(\n maximum,\n Math.max(minimum, number)\n );\n}\n\nfunction pad(number) {\n return String(number).padStart(2, '0');\n}\n\nfunction getLastDay(year, month) {\n return new Date(\n Date.UTC(year, month, 0)\n ).getUTCDate();\n}\n\nfunction buildPeriodDates(\n year,\n month,\n periodType\n) {\n if (\n !Number.isInteger(year) ||\n year < 2000 ||\n !Number.isInteger(month) ||\n month < 1 ||\n month > 12\n ) {\n return {\n periodStart: null,\n periodEnd: null,\n };\n }\n\n const lastDay = getLastDay(year, month);\n const yearMonth = `${year}-${pad(month)}`;\n\n if (periodType === 'quincena_15') {\n return {\n periodStart: `${yearMonth}-01`,\n periodEnd: `${yearMonth}-15`,\n };\n }\n\n if (periodType === 'quincena_30') {\n return {\n periodStart: `${yearMonth}-16`,\n periodEnd:\n `${yearMonth}-${pad(lastDay)}`,\n };\n }\n\n if (periodType === 'mensual') {\n return {\n periodStart: `${yearMonth}-01`,\n periodEnd:\n `${yearMonth}-${pad(lastDay)}`,\n };\n }\n\n return {\n periodStart: null,\n periodEnd: null,\n };\n}\n\nconst countryNames = {\n GT: 'Guatemala',\n TT: 'Trinidad y Tobago',\n PA: 'Panamá',\n SV: 'El Salvador',\n HN: 'Honduras',\n PR: 'Puerto Rico',\n RD: 'República Dominicana',\n};\n\nconst country = ['GT', 'TT', 'PA', 'SV', 'HN', 'PR', 'RD'].includes(\n String(request.country || '').toUpperCase()\n)\n ? String(request.country).toUpperCase()\n : 'GT';\n\nconst countryName =\n request.countryName ||\n countryNames[country];\n\nconst monthNames = {\n 1: 'Enero',\n 2: 'Febrero',\n 3: 'Marzo',\n 4: 'Abril',\n 5: 'Mayo',\n 6: 'Junio',\n 7: 'Julio',\n 8: 'Agosto',\n 9: 'Septiembre',\n 10: 'Octubre',\n 11: 'Noviembre',\n 12: 'Diciembre',\n};\n\nconst monthPatterns = [\n ['ENERO', 1],\n ['JANUARY', 1],\n ['JAN', 1],\n\n ['FEBRERO', 2],\n ['FEBRUARY', 2],\n ['FEB', 2],\n\n ['MARZO', 3],\n ['MARCH', 3],\n ['MAR', 3],\n\n ['ABRIL', 4],\n ['APRIL', 4],\n ['APR', 4],\n\n ['MAYO', 5],\n ['MAY', 5],\n\n ['JUNIO', 6],\n ['JUNE', 6],\n ['JUN', 6],\n\n ['JULIO', 7],\n ['JULY', 7],\n ['JUL', 7],\n\n ['AGOSTO', 8],\n ['AUGUST', 8],\n ['AUG', 8],\n\n ['SEPTIEMBRE', 9],\n ['SETIEMBRE', 9],\n ['SEPTEMBER', 9],\n ['SEPT', 9],\n ['SEP', 9],\n\n ['OCTUBRE', 10],\n ['OCTOBER', 10],\n ['OCT', 10],\n\n ['NOVIEMBRE', 11],\n ['NOVEMBER', 11],\n ['NOV', 11],\n\n ['DICIEMBRE', 12],\n ['DECEMBER', 12],\n ['DEC', 12],\n];\n\nconst monthPatternText =\n monthPatterns\n .map(([name]) => name)\n .sort((a, b) => b.length - a.length)\n .join('|');\n\nconst validPeriodTypes = new Set([\n 'quincena_15',\n 'quincena_30',\n 'mensual',\n 'desconocido',\n]);\n\nconst fileName = cleanText(request.fileName);\nconst normalizedFileName =\n normalizeText(fileName);\n\nconst hondurasDecimal = country === 'HN'\n ? fileName.match(/(?:nomina|nómina)?\\s*(\\d{1,2})\\.(1|2)\\s+(20\\d{2})/i)\n : null;\n\nconst compactDateMatch =\n normalizedFileName.match(\n /\\b(20\\d{2})(0[1-9]|1[0-2])([0-2]\\d|3[01])\\b/\n );\n\nconst standaloneYearMatch =\n normalizedFileName.match(/\\b(20\\d{2})\\b/);\n\nconst fallbackYear = hondurasDecimal\n ? Number(hondurasDecimal[3])\n : standaloneYearMatch\n ? Number(standaloneYearMatch[1])\n : compactDateMatch\n ? Number(compactDateMatch[1])\n : 0;\n\nlet fallbackMonth = hondurasDecimal ? Number(hondurasDecimal[1]) : 0;\n\nfor (const [monthName, monthNumber] of monthPatterns) {\n const monthRegex = new RegExp(\n `\\\\b${monthName}\\\\b`\n );\n\n if (monthRegex.test(normalizedFileName)) {\n fallbackMonth = monthNumber;\n break;\n }\n}\n\nif (!fallbackMonth && compactDateMatch) {\n fallbackMonth = Number(compactDateMatch[2]);\n}\n\nconst monthThenDayRegex = new RegExp(\n `\\\\b(?:${monthPatternText})\\\\s+([0-3]?\\\\d)(?:ST|ND|RD|TH)?\\\\b`\n);\n\nconst dayThenMonthRegex = new RegExp(\n `\\\\b([0-3]?\\\\d)(?:ST|ND|RD|TH)?\\\\s+(?:DE\\\\s+)?(?:${monthPatternText})\\\\b`\n);\n\nconst explicitDayRegex =\n /\\b(?:DIA|DAY)\\s+([0-3]?\\d)(?:ST|ND|RD|TH)?\\b/;\n\nconst monthThenDayMatch =\n normalizedFileName.match(monthThenDayRegex);\n\nconst dayThenMonthMatch =\n normalizedFileName.match(dayThenMonthRegex);\n\nconst explicitDayMatch =\n normalizedFileName.match(explicitDayRegex);\n\nconst detectedDay = monthThenDayMatch\n ? Number(monthThenDayMatch[1])\n : dayThenMonthMatch\n ? Number(dayThenMonthMatch[1])\n : explicitDayMatch\n ? Number(explicitDayMatch[1])\n : 0;\n\nconst firstFortnight =\n /\\b(1Q|Q1)\\b/.test(normalizedFileName) ||\n normalizedFileName.includes(\n 'PRIMERA QUINCENA'\n ) ||\n normalizedFileName.includes(\n '1RA QUINCENA'\n ) ||\n normalizedFileName.includes(\n 'FIRST FORTNIGHT'\n ) ||\n normalizedFileName.includes(\n 'FIRST HALF'\n ) ||\n normalizedFileName.includes(\n 'MID MONTH'\n ) ||\n normalizedFileName.includes(\n 'MIDMONTH'\n );\n\nconst secondFortnight =\n /\\b(2Q|Q2)\\b/.test(normalizedFileName) ||\n normalizedFileName.includes(\n 'SEGUNDA QUINCENA'\n ) ||\n normalizedFileName.includes(\n '2DA QUINCENA'\n ) ||\n normalizedFileName.includes(\n 'SECOND FORTNIGHT'\n ) ||\n normalizedFileName.includes(\n 'SECOND HALF'\n ) ||\n normalizedFileName.includes(\n 'FIN DE MES'\n ) ||\n normalizedFileName.includes(\n 'END OF MONTH'\n ) ||\n normalizedFileName.includes(\n 'MONTH END'\n ) ||\n normalizedFileName.includes(\n 'MONTHEND'\n );\n\nlet fallbackPeriodType = 'desconocido';\nlet fallbackConfidence = 0.2;\nlet strongPeriodEvidence = false;\n\nif (hondurasDecimal) {\n fallbackPeriodType = hondurasDecimal[2] === '1' ? 'quincena_15' : 'quincena_30';\n fallbackConfidence = 1;\n strongPeriodEvidence = true;\n} else if (firstFortnight) {\n fallbackPeriodType = 'quincena_15';\n fallbackConfidence = 0.98;\n strongPeriodEvidence = true;\n} else if (secondFortnight) {\n fallbackPeriodType = 'quincena_30';\n fallbackConfidence = 0.98;\n strongPeriodEvidence = true;\n} else if (detectedDay === 15) {\n fallbackPeriodType = 'quincena_15';\n fallbackConfidence = 0.95;\n strongPeriodEvidence = true;\n} else if (\n fallbackYear &&\n fallbackMonth &&\n detectedDay === getLastDay(\n fallbackYear,\n fallbackMonth\n )\n) {\n fallbackPeriodType = 'quincena_30';\n fallbackConfidence = 0.95;\n strongPeriodEvidence = true;\n} else if (\n detectedDay === 30 ||\n detectedDay === 31\n) {\n fallbackPeriodType = 'quincena_30';\n fallbackConfidence = 0.94;\n strongPeriodEvidence = true;\n} else if (\n fallbackYear &&\n fallbackMonth\n) {\n fallbackPeriodType = 'mensual';\n fallbackConfidence = 0.75;\n}\n\nlet rawAI =\n incoming.output ??\n incoming.result ??\n incoming.text ??\n incoming;\n\nrawAI = parseObject(rawAI);\n\nconst aiCountry =\n String(rawAI.country || '').toUpperCase();\n\nconst aiYear = Number(rawAI.year);\nconst aiMonth = Number(rawAI.month);\n\nconst aiPeriodType =\n validPeriodTypes.has(rawAI.period_type)\n ? rawAI.period_type\n : 'desconocido';\n\nconst aiConfidence = clamp(\n rawAI.confidence,\n 0,\n 1\n);\n\nconst aiIsUsable =\n Number.isInteger(aiYear) &&\n aiYear >= 2000 &&\n aiYear <= 2100 &&\n Number.isInteger(aiMonth) &&\n aiMonth >= 1 &&\n aiMonth <= 12 &&\n aiPeriodType !== 'desconocido';\n\nlet year =\n fallbackYear ||\n (aiIsUsable ? aiYear : 0);\n\nlet month =\n fallbackMonth ||\n (aiIsUsable ? aiMonth : 0);\n\nlet periodType =\n aiIsUsable\n ? aiPeriodType\n : fallbackPeriodType;\n\nlet source =\n aiIsUsable\n ? 'gemini'\n : 'local_fallback';\n\nlet confidence =\n aiIsUsable\n ? aiConfidence\n : fallbackConfidence;\n\nlet conflictResolved = false;\n\nif (\n aiCountry &&\n aiCountry !== country\n) {\n source = 'gemini_validated_with_rules';\n conflictResolved = true;\n}\n\nif (\n strongPeriodEvidence &&\n periodType !== fallbackPeriodType\n) {\n periodType = fallbackPeriodType;\n source = 'gemini_validated_with_rules';\n confidence = Math.max(\n fallbackConfidence,\n Math.min(aiConfidence, 0.9)\n );\n conflictResolved = true;\n}\n\nif (\n fallbackYear &&\n aiIsUsable &&\n aiYear !== fallbackYear\n) {\n year = fallbackYear;\n source = 'gemini_validated_with_rules';\n conflictResolved = true;\n}\n\nif (\n fallbackMonth &&\n aiIsUsable &&\n aiMonth !== fallbackMonth\n) {\n month = fallbackMonth;\n source = 'gemini_validated_with_rules';\n conflictResolved = true;\n}\n\nif (\n !aiIsUsable &&\n fallbackYear &&\n fallbackMonth\n) {\n year = fallbackYear;\n month = fallbackMonth;\n periodType = fallbackPeriodType;\n confidence = fallbackConfidence;\n source = 'local_fallback';\n}\n\nconst complete =\n year >= 2000 &&\n month >= 1 &&\n month <= 12 &&\n periodType !== 'desconocido';\n\nconst dates = buildPeriodDates(\n year,\n month,\n periodType\n);\n\nlet periodDescription = 'Período desconocido';\n\nif (periodType === 'quincena_15') {\n periodDescription = 'Quincena 15';\n}\n\nif (periodType === 'quincena_30') {\n periodDescription =\n 'Quincena 30 / fin de mes';\n}\n\nif (periodType === 'mensual') {\n periodDescription = 'Mensual';\n}\n\nconst monthLabel =\n monthNames[month] || 'Mes desconocido';\n\nconst periodLabel = complete\n ? `${monthLabel} ${year} · ${periodDescription}`\n : 'Período pendiente de confirmar';\n\nconst requiresManualReview =\n !complete ||\n confidence < 0.75;\n\nconst explanation =\n cleanText(rawAI.explanation) ||\n (\n source === 'local_fallback'\n ? 'El período fue identificado mediante las reglas locales de respaldo.'\n : 'El período fue identificado mediante Gemini y validado con las reglas del portal.'\n );\n\nreturn [\n {\n json: {\n ok: true,\n\n message: requiresManualReview\n ? 'El archivo fue analizado, pero el período debe confirmarse manualmente.'\n : 'El período de la nómina fue detectado correctamente.',\n\n detected: {\n country,\n countryName,\n\n fileName,\n\n year,\n month,\n\n periodType,\n period_type: periodType,\n\n periodLabel,\n period_label: periodLabel,\n\n periodStart: dates.periodStart,\n period_start: dates.periodStart,\n\n periodEnd: dates.periodEnd,\n period_end: dates.periodEnd,\n\n confidence:\n Math.round(confidence * 100) / 100,\n\n complete,\n requiresManualReview,\n requires_manual_review:\n requiresManualReview,\n\n source,\n conflictResolved,\n explanation,\n },\n\n debug: {\n fallback: {\n country,\n year: fallbackYear,\n month: fallbackMonth,\n periodType: fallbackPeriodType,\n detectedDay,\n confidence: fallbackConfidence,\n strongPeriodEvidence,\n compactDate:\n compactDateMatch?.[0] || null,\n },\n\n gemini: {\n country: aiCountry || null,\n year: aiYear || 0,\n month: aiMonth || 0,\n periodType: aiPeriodType,\n confidence: aiConfidence,\n explanation:\n cleanText(rawAI.explanation),\n },\n },\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 10544, + 4688 + ], + "id": "c1e94839-9a12-4866-a962-0cff95c23286", + "name": "Normalizar análisis IA" + }, + { + "parameters": { + "options": { + "responseCode": 200, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 10752, + 4688 + ], + "id": "d50b0ab8-1547-4123-b5a7-8b343e7096e9", + "name": "Responder análisis" + }, + { + "parameters": { + "content": "# 🧠 ANÁLISIS AUTOMÁTICO DE NÓMINA — GT, TT, PA, SV, HN y PR\n\nAnaliza el nombre o título del archivo de nómina para identificar automáticamente el período correspondiente antes de ejecutar la verificación.\n\n## Recepción y validación\n\nEl Webhook recibe desde el Portal de Verificación de Nóminas la información del archivo seleccionado.\n\nLa solicitud puede incluir:\n\n- Nombre del archivo.\n- Título o descripción disponible.\n- País o portal de origen.\n- Identificador de la solicitud.\n- Información complementaria enviada por la aplicación.\n\nAntes de utilizar inteligencia artificial, el flujo valida que exista suficiente información para analizar el archivo.\n\n## Extracción con Gemini\n\nCuando la solicitud es válida, Gemini interpreta el nombre o título de la nómina e intenta determinar:\n\n- Año.\n- Mes.\n- Tipo de período.\n- Quincena 15.\n- Quincena 30 o fin de mes.\n- Nómina mensual.\n- País, cuando puede inferirse de forma confiable.\n- Nivel de confianza del análisis.\n\nGemini se utiliza únicamente para interpretar el texto recibido; no ejecuta el cruce de nómina ni modifica información.\n\n## Normalización del resultado\n\nLa respuesta de Gemini se transforma al formato requerido por la aplicación.\n\nEste bloque:\n\n- Limpia texto adicional generado por la IA.\n- Normaliza el año a formato numérico.\n- Convierte el mes al valor esperado por el portal.\n- Estandariza el tipo de período.\n- Corrige variaciones como “segunda quincena”, “fin de mes” o “30”.\n- Conserva los valores originales cuando la IA no puede determinar un dato.\n- Prepara una respuesta consistente para Guatemala, Trinidad y Tobago, Panamá y El Salvador.\n\n## Respuesta al portal\n\nCuando el análisis termina, el workflow devuelve a la aplicación:\n\n- Indicador de éxito.\n- Año detectado.\n- Mes detectado.\n- Tipo de período detectado.\n- País identificado, cuando corresponda.\n- Nivel de confianza.\n- Datos que requieren revisión manual.\n\nLos valores detectados sirven para completar automáticamente el formulario, pero el usuario puede corregirlos antes de ejecutar el proceso.\n\n## Ruta de error\n\nCuando la solicitud es inválida:\n\n- No se llama a Gemini.\n- No se intenta interpretar información incompleta.\n- Se devuelve una respuesta de error al portal.\n- Se indica que falta el nombre del archivo u otro dato obligatorio.\n\n## Reglas\n\n- No inventar un período cuando el título no contiene información suficiente.\n- No ejecutar el cruce de nómina desde este workflow.\n- No tratar una predicción de baja confianza como un dato definitivo.\n- Mantener la opción de corrección manual en la aplicación.\n- Responder siempre al Webhook, tanto en la ruta válida como en la ruta de error.\n- Utilizar una estructura de respuesta compatible con los portales de Guatemala, Trinidad y Tobago, Panamá y El Salvador.", + "height": 1488, + "width": 2256, + "color": 2 + }, + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 8720, + 4128 + ], + "id": "c2b50560-6c24-46cf-a5c9-763880a76a53", + "name": "Sticky Note" + } + ], + "pinData": {}, + "connections": { + "Webhook - Analizar Nómina": { + "main": [ + [ + { + "node": "Validar y preparar solicitud", + "type": "main", + "index": 0 + } + ] + ] + }, + "Validar y preparar solicitud": { + "main": [ + [ + { + "node": "¿Solicitud válida?", + "type": "main", + "index": 0 + } + ] + ] + }, + "¿Solicitud válida?": { + "main": [ + [ + { + "node": "Extraer período con Gemini", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Responder error", + "type": "main", + "index": 0 + } + ] + ] + }, + "Gemini - Analizar título nómina": { + "ai_languageModel": [ + [ + { + "node": "Extraer período con Gemini", + "type": "ai_languageModel", + "index": 0 + } + ] + ] + }, + "Extraer período con Gemini": { + "main": [ + [ + { + "node": "Normalizar análisis IA", + "type": "main", + "index": 0 + } + ] + ] + }, + "Normalizar análisis IA": { + "main": [ + [ + { + "node": "Responder análisis", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": { + "executionOrder": "v1", + "binaryMode": "separate", + "availableInMCP": true, + "timeSavedMode": "fixed", + "errorWorkflow": "puF4LUczoSz3hcek", + "timezone": "America/Santo_Domingo", + "callerPolicy": "workflowsFromSameOwner" + }, + "versionId": "2ddc71e4-ab0a-49c2-ba3f-72fc50283e27", + "meta": { + "templateCredsSetupCompleted": true, + "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" + }, + "id": "", + "tags": [] +} \ No newline at end of file diff --git a/workflows_n8n/Portal de Verificaci├│n de N├│mina - Analizar N├│mina con Gemini GT TT PA SV HN PR.json b/workflows_n8n/Portal de Verificaci├│n de N├│mina - Analizar N├│mina con Gemini GT TT PA SV HN PR.json new file mode 100644 index 0000000..850a2e1 --- /dev/null +++ b/workflows_n8n/Portal de Verificaci├│n de N├│mina - Analizar N├│mina con Gemini GT TT PA SV HN PR.json @@ -0,0 +1,280 @@ +{ + "name": "Portal de Verificación de Nómina - Analizar Nómina con Gemini GT TT PA SV HN PR", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "cruce-cuentas-analizar-nomina", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + 9008, + 3376 + ], + "id": "dd5223e5-ed61-442c-b87a-c3a11c4c2b38", + "name": "Webhook - Analizar Nómina", + "webhookId": "f265d1ec-437f-4a05-a699-76dae8c4d89e" + }, + { + "parameters": { + "jsCode": "const input = $input.first().json || {};\n\nlet body = input.body ?? input;\n\nif (typeof body === 'string') {\n try {\n body = JSON.parse(body);\n } catch (error) {\n body = {};\n }\n}\n\nif (!body || typeof body !== 'object' || Array.isArray(body)) {\n body = {};\n}\n\nfunction clean(value) {\n return String(value ?? '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst fileName = clean(\n body.fileName ??\n body.filename ??\n body.file_name ??\n ''\n);\n\nconst country = clean(\n body.country ?? 'GT'\n).toUpperCase();\n\nconst supportedCountries = {\n GT: 'Guatemala',\n TT: 'Trinidad y Tobago',\n PA: 'Panamá',\n SV: 'El Salvador',\n HN: 'Honduras',\n PR: 'Puerto Rico',\n};\n\nconst countryName = clean(\n body.countryName ??\n body.country_name ??\n supportedCountries[country] ??\n ''\n);\n\nconst errors = [];\n\nif (!fileName) {\n errors.push(\n 'No se recibió el nombre del archivo de nómina.'\n );\n}\n\nif (!Object.prototype.hasOwnProperty.call(\n supportedCountries,\n country\n)) {\n errors.push(\n 'El analizador solo está habilitado para Guatemala, Trinidad y Tobago, Panamá, El Salvador, Honduras y Puerto Rico.'\n );\n}\n\nconst supportedExtensions = [\n '.xlsx',\n '.xls',\n '.xlsm',\n '.csv',\n];\n\nconst lowerFileName = fileName.toLowerCase();\n\nconst hasSupportedExtension =\n supportedExtensions.some((extension) =>\n lowerFileName.endsWith(extension)\n );\n\nif (fileName && !hasSupportedExtension) {\n errors.push(\n 'El archivo recibido no tiene una extensión de nómina compatible.'\n );\n}\n\nreturn [\n {\n json: {\n ok: errors.length === 0,\n errors,\n\n fileName,\n country,\n countryName:\n countryName ||\n supportedCountries[country] ||\n '',\n\n receivedAt: new Date().toISOString(),\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 9216, + 3376 + ], + "id": "a9f66bf1-a4d5-40fc-bff1-d09b34b880e2", + "name": "Validar y preparar solicitud" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "bd9fd675-d72b-4dba-ac03-a44f1123ecb0", + "leftValue": "={{ $json.ok }}", + "rightValue": "", + "operator": { + "type": "boolean", + "operation": "true", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + 9424, + 3376 + ], + "id": "82cc723d-470e-40f4-8edd-afb9de5b27ed", + "name": "¿Solicitud válida?" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{\n{\n ok: false,\n message:\n 'No fue posible analizar el nombre del archivo.',\n errors: Array.isArray($json.errors)\n ? $json.errors\n : ['La solicitud recibida no es válida.'],\n detected: null\n}\n}}", + "options": { + "responseCode": 400, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 9632, + 3472 + ], + "id": "15bd9a4e-cd52-46e3-818a-e316b0132524", + "name": "Responder error" + }, + { + "parameters": { + "text": "={{\n`Analiza este nombre de archivo de nómina:\n\nPaís seleccionado: ${$json.countryName}\nCódigo del país: ${$json.country}\nNombre del archivo: ${$json.fileName}`\n}}", + "schemaType": "manual", + "inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"country\": {\n \"type\": \"string\",\n \"enum\": [\n \"GT\",\n \"TT\",\n \"PA\",\n \"SV\",\n \"HN\",\n \"PR\"\n ]\n },\n \"year\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"maximum\": 2100\n },\n \"month\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"maximum\": 12\n },\n \"period_type\": {\n \"type\": \"string\",\n \"enum\": [\n \"quincena_15\",\n \"quincena_30\",\n \"mensual\",\n \"desconocido\"\n ]\n },\n \"confidence\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 1\n },\n \"explanation\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"country\",\n \"year\",\n \"month\",\n \"period_type\",\n \"confidence\",\n \"explanation\"\n ],\n \"additionalProperties\": false\n}", + "options": { + "systemPromptTemplate": "Eres un clasificador determinista de nombres de archivos de nómina.\n\nTu tarea es identificar el país seleccionado, el año, el mes y el período de pago utilizando únicamente la información presente en el nombre del archivo y el país recibido.\n\nNo inventes datos que no estén contenidos o razonablemente codificados en el nombre.\n\nREGLAS GENERALES:\n\n1. Devuelve exactamente el código de país recibido:\n - GT para Guatemala.\n - TT para Trinidad y Tobago.\n - PA para Panamá.\n - SV para El Salvador.\n - HN para Honduras.\n - PR para Puerto Rico.\n\n2. Detecta el año de cuatro dígitos. También puede aparecer dentro de una fecha compacta como YYYYMMDD; por ejemplo, 20260617 representa el año 2026.\n\n3. Convierte el mes a un número aceptando nombres en español o inglés:\n Enero / January = 1\n Febrero / February = 2\n Marzo / March = 3\n Abril / April = 4\n Mayo / May = 5\n Junio / June = 6\n Julio / July = 7\n Agosto / August = 8\n Septiembre / September = 9\n Octubre / October = 10\n Noviembre / November = 11\n Diciembre / December = 12\n\n4. Usa period_type = quincena_15 cuando aparezca cualquiera de estas señales:\n - 1Q\n - Q1\n - Primera quincena\n - 1ra quincena\n - First fortnight\n - First half\n - Mid month\n - Día 15\n - 15th\n\n5. Usa period_type = quincena_30 cuando aparezca cualquiera de estas señales:\n - 2Q\n - Q2\n - Segunda quincena\n - 2da quincena\n - Second fortnight\n - Second half\n - Fin de mes\n - End of month\n - Month end\n - Día 30\n - Día 31\n - 30th\n - 31st\n - El último día real del mes, incluyendo 28 o 29 de febrero\n\n6. Aunque el último día real del mes no sea 30, utiliza quincena_30 para representar la segunda quincena o cierre de mes.\n\n7. Si solamente aparecen el mes y el año, sin ninguna señal de quincena ni día de cierre, utiliza mensual.\n\n8. Para nombres como \"GLM_TT_Payroll June 30TH_20260617.xlsx\":\n - country = TT\n - year = 2026\n - month = 6\n - period_type = quincena_30\n\n9. Para Honduras también reconoce nombres como \"Nomina 7.1 2026 GLM HN.xlsx\" (mes 7, primera quincena) y \"Nomina 7.2 2026 GLM HN.xlsx\" (mes 7, segunda quincena). En general, cuando ese patrón forma parte del nombre de nómina, M.1 = quincena_15 y M.2 = quincena_30.\n\n10. Si no puedes identificar de manera confiable el año o el mes, utiliza:\n year = 0\n month = 0\n period_type = desconocido\n\n11. confidence debe estar entre 0 y 1.\n\n12. explanation debe ser breve y mencionar las señales encontradas en el nombre.\n\nNo agregues campos diferentes a los definidos por el esquema." + } + }, + "type": "@n8n/n8n-nodes-langchain.informationExtractor", + "typeVersion": 1.2, + "position": [ + 9632, + 3104 + ], + "id": "183e2202-0bbd-4bcc-bc57-0b92e12b5d5f", + "name": "Extraer período con Gemini", + "retryOnFail": true, + "waitBetweenTries": 2000, + "onError": "continueRegularOutput" + }, + { + "parameters": { + "modelName": "models/gemini-2.5-pro", + "options": {} + }, + "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", + "typeVersion": 1.1, + "position": [ + 9632, + 3280 + ], + "id": "149a7c92-4c82-4348-9f88-58539d79e75f", + "name": "Gemini - Analizar título nómina", + "credentials": { + "googlePalmApi": { + "id": "jvsXYwL6IOoY2DBU", + "name": "Isaac - Gemini Api Pago" + } + } + }, + { + "parameters": { + "jsCode": "const request =\n $('Validar y preparar solicitud').first().json || {};\n\nconst incoming = $input.first().json || {};\n\nfunction cleanText(value) {\n return String(value ?? '')\n .replace(/\\uFEFF/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalizeText(value) {\n return cleanText(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[_\\-.,()[\\]{}]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction parseObject(value) {\n if (\n value &&\n typeof value === 'object' &&\n !Array.isArray(value)\n ) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return {};\n }\n\n const cleaned = value\n .replace(/```json/gi, '')\n .replace(/```/g, '')\n .trim();\n\n try {\n return JSON.parse(cleaned);\n } catch (error) {\n return {};\n }\n}\n\nfunction clamp(value, minimum, maximum) {\n const number = Number(value);\n\n if (!Number.isFinite(number)) {\n return minimum;\n }\n\n return Math.min(\n maximum,\n Math.max(minimum, number)\n );\n}\n\nfunction pad(number) {\n return String(number).padStart(2, '0');\n}\n\nfunction getLastDay(year, month) {\n return new Date(\n Date.UTC(year, month, 0)\n ).getUTCDate();\n}\n\nfunction buildPeriodDates(\n year,\n month,\n periodType\n) {\n if (\n !Number.isInteger(year) ||\n year < 2000 ||\n !Number.isInteger(month) ||\n month < 1 ||\n month > 12\n ) {\n return {\n periodStart: null,\n periodEnd: null,\n };\n }\n\n const lastDay = getLastDay(year, month);\n const yearMonth = `${year}-${pad(month)}`;\n\n if (periodType === 'quincena_15') {\n return {\n periodStart: `${yearMonth}-01`,\n periodEnd: `${yearMonth}-15`,\n };\n }\n\n if (periodType === 'quincena_30') {\n return {\n periodStart: `${yearMonth}-16`,\n periodEnd:\n `${yearMonth}-${pad(lastDay)}`,\n };\n }\n\n if (periodType === 'mensual') {\n return {\n periodStart: `${yearMonth}-01`,\n periodEnd:\n `${yearMonth}-${pad(lastDay)}`,\n };\n }\n\n return {\n periodStart: null,\n periodEnd: null,\n };\n}\n\nconst countryNames = {\n GT: 'Guatemala',\n TT: 'Trinidad y Tobago',\n PA: 'Panamá',\n SV: 'El Salvador',\n HN: 'Honduras',\n PR: 'Puerto Rico',\n};\n\nconst country = ['GT', 'TT', 'PA', 'SV', 'HN', 'PR'].includes(\n String(request.country || '').toUpperCase()\n)\n ? String(request.country).toUpperCase()\n : 'GT';\n\nconst countryName =\n request.countryName ||\n countryNames[country];\n\nconst monthNames = {\n 1: 'Enero',\n 2: 'Febrero',\n 3: 'Marzo',\n 4: 'Abril',\n 5: 'Mayo',\n 6: 'Junio',\n 7: 'Julio',\n 8: 'Agosto',\n 9: 'Septiembre',\n 10: 'Octubre',\n 11: 'Noviembre',\n 12: 'Diciembre',\n};\n\nconst monthPatterns = [\n ['ENERO', 1],\n ['JANUARY', 1],\n ['JAN', 1],\n\n ['FEBRERO', 2],\n ['FEBRUARY', 2],\n ['FEB', 2],\n\n ['MARZO', 3],\n ['MARCH', 3],\n ['MAR', 3],\n\n ['ABRIL', 4],\n ['APRIL', 4],\n ['APR', 4],\n\n ['MAYO', 5],\n ['MAY', 5],\n\n ['JUNIO', 6],\n ['JUNE', 6],\n ['JUN', 6],\n\n ['JULIO', 7],\n ['JULY', 7],\n ['JUL', 7],\n\n ['AGOSTO', 8],\n ['AUGUST', 8],\n ['AUG', 8],\n\n ['SEPTIEMBRE', 9],\n ['SETIEMBRE', 9],\n ['SEPTEMBER', 9],\n ['SEPT', 9],\n ['SEP', 9],\n\n ['OCTUBRE', 10],\n ['OCTOBER', 10],\n ['OCT', 10],\n\n ['NOVIEMBRE', 11],\n ['NOVEMBER', 11],\n ['NOV', 11],\n\n ['DICIEMBRE', 12],\n ['DECEMBER', 12],\n ['DEC', 12],\n];\n\nconst monthPatternText =\n monthPatterns\n .map(([name]) => name)\n .sort((a, b) => b.length - a.length)\n .join('|');\n\nconst validPeriodTypes = new Set([\n 'quincena_15',\n 'quincena_30',\n 'mensual',\n 'desconocido',\n]);\n\nconst fileName = cleanText(request.fileName);\nconst normalizedFileName =\n normalizeText(fileName);\n\nconst hondurasDecimal = country === 'HN'\n ? fileName.match(/(?:nomina|nómina)?\\s*(\\d{1,2})\\.(1|2)\\s+(20\\d{2})/i)\n : null;\n\nconst compactDateMatch =\n normalizedFileName.match(\n /\\b(20\\d{2})(0[1-9]|1[0-2])([0-2]\\d|3[01])\\b/\n );\n\nconst standaloneYearMatch =\n normalizedFileName.match(/\\b(20\\d{2})\\b/);\n\nconst fallbackYear = hondurasDecimal\n ? Number(hondurasDecimal[3])\n : standaloneYearMatch\n ? Number(standaloneYearMatch[1])\n : compactDateMatch\n ? Number(compactDateMatch[1])\n : 0;\n\nlet fallbackMonth = hondurasDecimal ? Number(hondurasDecimal[1]) : 0;\n\nfor (const [monthName, monthNumber] of monthPatterns) {\n const monthRegex = new RegExp(\n `\\\\b${monthName}\\\\b`\n );\n\n if (monthRegex.test(normalizedFileName)) {\n fallbackMonth = monthNumber;\n break;\n }\n}\n\nif (!fallbackMonth && compactDateMatch) {\n fallbackMonth = Number(compactDateMatch[2]);\n}\n\nconst monthThenDayRegex = new RegExp(\n `\\\\b(?:${monthPatternText})\\\\s+([0-3]?\\\\d)(?:ST|ND|RD|TH)?\\\\b`\n);\n\nconst dayThenMonthRegex = new RegExp(\n `\\\\b([0-3]?\\\\d)(?:ST|ND|RD|TH)?\\\\s+(?:DE\\\\s+)?(?:${monthPatternText})\\\\b`\n);\n\nconst explicitDayRegex =\n /\\b(?:DIA|DAY)\\s+([0-3]?\\d)(?:ST|ND|RD|TH)?\\b/;\n\nconst monthThenDayMatch =\n normalizedFileName.match(monthThenDayRegex);\n\nconst dayThenMonthMatch =\n normalizedFileName.match(dayThenMonthRegex);\n\nconst explicitDayMatch =\n normalizedFileName.match(explicitDayRegex);\n\nconst detectedDay = monthThenDayMatch\n ? Number(monthThenDayMatch[1])\n : dayThenMonthMatch\n ? Number(dayThenMonthMatch[1])\n : explicitDayMatch\n ? Number(explicitDayMatch[1])\n : 0;\n\nconst firstFortnight =\n /\\b(1Q|Q1)\\b/.test(normalizedFileName) ||\n normalizedFileName.includes(\n 'PRIMERA QUINCENA'\n ) ||\n normalizedFileName.includes(\n '1RA QUINCENA'\n ) ||\n normalizedFileName.includes(\n 'FIRST FORTNIGHT'\n ) ||\n normalizedFileName.includes(\n 'FIRST HALF'\n ) ||\n normalizedFileName.includes(\n 'MID MONTH'\n ) ||\n normalizedFileName.includes(\n 'MIDMONTH'\n );\n\nconst secondFortnight =\n /\\b(2Q|Q2)\\b/.test(normalizedFileName) ||\n normalizedFileName.includes(\n 'SEGUNDA QUINCENA'\n ) ||\n normalizedFileName.includes(\n '2DA QUINCENA'\n ) ||\n normalizedFileName.includes(\n 'SECOND FORTNIGHT'\n ) ||\n normalizedFileName.includes(\n 'SECOND HALF'\n ) ||\n normalizedFileName.includes(\n 'FIN DE MES'\n ) ||\n normalizedFileName.includes(\n 'END OF MONTH'\n ) ||\n normalizedFileName.includes(\n 'MONTH END'\n ) ||\n normalizedFileName.includes(\n 'MONTHEND'\n );\n\nlet fallbackPeriodType = 'desconocido';\nlet fallbackConfidence = 0.2;\nlet strongPeriodEvidence = false;\n\nif (hondurasDecimal) {\n fallbackPeriodType = hondurasDecimal[2] === '1' ? 'quincena_15' : 'quincena_30';\n fallbackConfidence = 1;\n strongPeriodEvidence = true;\n} else if (firstFortnight) {\n fallbackPeriodType = 'quincena_15';\n fallbackConfidence = 0.98;\n strongPeriodEvidence = true;\n} else if (secondFortnight) {\n fallbackPeriodType = 'quincena_30';\n fallbackConfidence = 0.98;\n strongPeriodEvidence = true;\n} else if (detectedDay === 15) {\n fallbackPeriodType = 'quincena_15';\n fallbackConfidence = 0.95;\n strongPeriodEvidence = true;\n} else if (\n fallbackYear &&\n fallbackMonth &&\n detectedDay === getLastDay(\n fallbackYear,\n fallbackMonth\n )\n) {\n fallbackPeriodType = 'quincena_30';\n fallbackConfidence = 0.95;\n strongPeriodEvidence = true;\n} else if (\n detectedDay === 30 ||\n detectedDay === 31\n) {\n fallbackPeriodType = 'quincena_30';\n fallbackConfidence = 0.94;\n strongPeriodEvidence = true;\n} else if (\n fallbackYear &&\n fallbackMonth\n) {\n fallbackPeriodType = 'mensual';\n fallbackConfidence = 0.75;\n}\n\nlet rawAI =\n incoming.output ??\n incoming.result ??\n incoming.text ??\n incoming;\n\nrawAI = parseObject(rawAI);\n\nconst aiCountry =\n String(rawAI.country || '').toUpperCase();\n\nconst aiYear = Number(rawAI.year);\nconst aiMonth = Number(rawAI.month);\n\nconst aiPeriodType =\n validPeriodTypes.has(rawAI.period_type)\n ? rawAI.period_type\n : 'desconocido';\n\nconst aiConfidence = clamp(\n rawAI.confidence,\n 0,\n 1\n);\n\nconst aiIsUsable =\n Number.isInteger(aiYear) &&\n aiYear >= 2000 &&\n aiYear <= 2100 &&\n Number.isInteger(aiMonth) &&\n aiMonth >= 1 &&\n aiMonth <= 12 &&\n aiPeriodType !== 'desconocido';\n\nlet year =\n fallbackYear ||\n (aiIsUsable ? aiYear : 0);\n\nlet month =\n fallbackMonth ||\n (aiIsUsable ? aiMonth : 0);\n\nlet periodType =\n aiIsUsable\n ? aiPeriodType\n : fallbackPeriodType;\n\nlet source =\n aiIsUsable\n ? 'gemini'\n : 'local_fallback';\n\nlet confidence =\n aiIsUsable\n ? aiConfidence\n : fallbackConfidence;\n\nlet conflictResolved = false;\n\nif (\n aiCountry &&\n aiCountry !== country\n) {\n source = 'gemini_validated_with_rules';\n conflictResolved = true;\n}\n\nif (\n strongPeriodEvidence &&\n periodType !== fallbackPeriodType\n) {\n periodType = fallbackPeriodType;\n source = 'gemini_validated_with_rules';\n confidence = Math.max(\n fallbackConfidence,\n Math.min(aiConfidence, 0.9)\n );\n conflictResolved = true;\n}\n\nif (\n fallbackYear &&\n aiIsUsable &&\n aiYear !== fallbackYear\n) {\n year = fallbackYear;\n source = 'gemini_validated_with_rules';\n conflictResolved = true;\n}\n\nif (\n fallbackMonth &&\n aiIsUsable &&\n aiMonth !== fallbackMonth\n) {\n month = fallbackMonth;\n source = 'gemini_validated_with_rules';\n conflictResolved = true;\n}\n\nif (\n !aiIsUsable &&\n fallbackYear &&\n fallbackMonth\n) {\n year = fallbackYear;\n month = fallbackMonth;\n periodType = fallbackPeriodType;\n confidence = fallbackConfidence;\n source = 'local_fallback';\n}\n\nconst complete =\n year >= 2000 &&\n month >= 1 &&\n month <= 12 &&\n periodType !== 'desconocido';\n\nconst dates = buildPeriodDates(\n year,\n month,\n periodType\n);\n\nlet periodDescription = 'Período desconocido';\n\nif (periodType === 'quincena_15') {\n periodDescription = 'Quincena 15';\n}\n\nif (periodType === 'quincena_30') {\n periodDescription =\n 'Quincena 30 / fin de mes';\n}\n\nif (periodType === 'mensual') {\n periodDescription = 'Mensual';\n}\n\nconst monthLabel =\n monthNames[month] || 'Mes desconocido';\n\nconst periodLabel = complete\n ? `${monthLabel} ${year} · ${periodDescription}`\n : 'Período pendiente de confirmar';\n\nconst requiresManualReview =\n !complete ||\n confidence < 0.75;\n\nconst explanation =\n cleanText(rawAI.explanation) ||\n (\n source === 'local_fallback'\n ? 'El período fue identificado mediante las reglas locales de respaldo.'\n : 'El período fue identificado mediante Gemini y validado con las reglas del portal.'\n );\n\nreturn [\n {\n json: {\n ok: true,\n\n message: requiresManualReview\n ? 'El archivo fue analizado, pero el período debe confirmarse manualmente.'\n : 'El período de la nómina fue detectado correctamente.',\n\n detected: {\n country,\n countryName,\n\n fileName,\n\n year,\n month,\n\n periodType,\n period_type: periodType,\n\n periodLabel,\n period_label: periodLabel,\n\n periodStart: dates.periodStart,\n period_start: dates.periodStart,\n\n periodEnd: dates.periodEnd,\n period_end: dates.periodEnd,\n\n confidence:\n Math.round(confidence * 100) / 100,\n\n complete,\n requiresManualReview,\n requires_manual_review:\n requiresManualReview,\n\n source,\n conflictResolved,\n explanation,\n },\n\n debug: {\n fallback: {\n country,\n year: fallbackYear,\n month: fallbackMonth,\n periodType: fallbackPeriodType,\n detectedDay,\n confidence: fallbackConfidence,\n strongPeriodEvidence,\n compactDate:\n compactDateMatch?.[0] || null,\n },\n\n gemini: {\n country: aiCountry || null,\n year: aiYear || 0,\n month: aiMonth || 0,\n periodType: aiPeriodType,\n confidence: aiConfidence,\n explanation:\n cleanText(rawAI.explanation),\n },\n },\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 9968, + 3120 + ], + "id": "abda0cdb-60df-4249-bb67-3697aba37a3f", + "name": "Normalizar análisis IA" + }, + { + "parameters": { + "options": { + "responseCode": 200, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 10176, + 3120 + ], + "id": "32ae875a-8f3e-45b2-9d5c-4ee3f28eec77", + "name": "Responder análisis" + }, + { + "parameters": { + "content": "# 🧠 ANÁLISIS AUTOMÁTICO DE NÓMINA — GT, TT, PA y SV\n\nAnaliza el nombre o título del archivo de nómina para identificar automáticamente el período correspondiente antes de ejecutar la verificación.\n\n## Recepción y validación\n\nEl Webhook recibe desde el Portal de Verificación de Nóminas la información del archivo seleccionado.\n\nLa solicitud puede incluir:\n\n- Nombre del archivo.\n- Título o descripción disponible.\n- País o portal de origen.\n- Identificador de la solicitud.\n- Información complementaria enviada por la aplicación.\n\nAntes de utilizar inteligencia artificial, el flujo valida que exista suficiente información para analizar el archivo.\n\n## Extracción con Gemini\n\nCuando la solicitud es válida, Gemini interpreta el nombre o título de la nómina e intenta determinar:\n\n- Año.\n- Mes.\n- Tipo de período.\n- Quincena 15.\n- Quincena 30 o fin de mes.\n- Nómina mensual.\n- País, cuando puede inferirse de forma confiable.\n- Nivel de confianza del análisis.\n\nGemini se utiliza únicamente para interpretar el texto recibido; no ejecuta el cruce de nómina ni modifica información.\n\n## Normalización del resultado\n\nLa respuesta de Gemini se transforma al formato requerido por la aplicación.\n\nEste bloque:\n\n- Limpia texto adicional generado por la IA.\n- Normaliza el año a formato numérico.\n- Convierte el mes al valor esperado por el portal.\n- Estandariza el tipo de período.\n- Corrige variaciones como “segunda quincena”, “fin de mes” o “30”.\n- Conserva los valores originales cuando la IA no puede determinar un dato.\n- Prepara una respuesta consistente para Guatemala, Trinidad y Tobago, Panamá y El Salvador.\n\n## Respuesta al portal\n\nCuando el análisis termina, el workflow devuelve a la aplicación:\n\n- Indicador de éxito.\n- Año detectado.\n- Mes detectado.\n- Tipo de período detectado.\n- País identificado, cuando corresponda.\n- Nivel de confianza.\n- Datos que requieren revisión manual.\n\nLos valores detectados sirven para completar automáticamente el formulario, pero el usuario puede corregirlos antes de ejecutar el proceso.\n\n## Ruta de error\n\nCuando la solicitud es inválida:\n\n- No se llama a Gemini.\n- No se intenta interpretar información incompleta.\n- Se devuelve una respuesta de error al portal.\n- Se indica que falta el nombre del archivo u otro dato obligatorio.\n\n## Reglas\n\n- No inventar un período cuando el título no contiene información suficiente.\n- No ejecutar el cruce de nómina desde este workflow.\n- No tratar una predicción de baja confianza como un dato definitivo.\n- Mantener la opción de corrección manual en la aplicación.\n- Responder siempre al Webhook, tanto en la ruta válida como en la ruta de error.\n- Utilizar una estructura de respuesta compatible con los portales de Guatemala, Trinidad y Tobago, Panamá y El Salvador.", + "height": 1488, + "width": 2256, + "color": 2 + }, + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 8144, + 2560 + ], + "id": "d5711cc9-9637-4129-bab9-8ec07b551774", + "name": "Sticky Note" + } + ], + "pinData": {}, + "connections": { + "Webhook - Analizar Nómina": { + "main": [ + [ + { + "node": "Validar y preparar solicitud", + "type": "main", + "index": 0 + } + ] + ] + }, + "Validar y preparar solicitud": { + "main": [ + [ + { + "node": "¿Solicitud válida?", + "type": "main", + "index": 0 + } + ] + ] + }, + "¿Solicitud válida?": { + "main": [ + [ + { + "node": "Extraer período con Gemini", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Responder error", + "type": "main", + "index": 0 + } + ] + ] + }, + "Gemini - Analizar título nómina": { + "ai_languageModel": [ + [ + { + "node": "Extraer período con Gemini", + "type": "ai_languageModel", + "index": 0 + } + ] + ] + }, + "Extraer período con Gemini": { + "main": [ + [ + { + "node": "Normalizar análisis IA", + "type": "main", + "index": 0 + } + ] + ] + }, + "Normalizar análisis IA": { + "main": [ + [ + { + "node": "Responder análisis", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": true, + "settings": { + "executionOrder": "v1", + "binaryMode": "separate", + "availableInMCP": true, + "timeSavedMode": "fixed", + "errorWorkflow": "puF4LUczoSz3hcek", + "timezone": "America/Santo_Domingo", + "callerPolicy": "workflowsFromSameOwner" + }, + "versionId": "d58ae020-ce4f-429b-ba40-1262c79492f9", + "meta": { + "templateCredsSetupCompleted": true, + "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" + }, + "id": "E9cNPlUjeGnhFqW2", + "tags": [] +} diff --git a/workflows_n8n/Portal de Verificaci├│n de N├│mina - Analizar N├│mina con Gemini GT TT PA SV HN.json b/workflows_n8n/Portal de Verificaci├│n de N├│mina - Analizar N├│mina con Gemini GT TT PA SV HN.json new file mode 100644 index 0000000..ab4647f --- /dev/null +++ b/workflows_n8n/Portal de Verificaci├│n de N├│mina - Analizar N├│mina con Gemini GT TT PA SV HN.json @@ -0,0 +1,279 @@ +{ + "name": "Portal de Verificación de Nómina - Analizar Nómina con Gemini GT TT PA SV HN", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "cruce-cuentas-analizar-nomina", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + 6432, + 2784 + ], + "id": "8518e0cc-3c55-4c55-9c9b-3498dd6ab7d3", + "name": "Webhook - Analizar Nómina", + "webhookId": "f265d1ec-437f-4a05-a699-76dae8c4d89e" + }, + { + "parameters": { + "jsCode": "const input = $input.first().json || {};\n\nlet body = input.body ?? input;\n\nif (typeof body === 'string') {\n try {\n body = JSON.parse(body);\n } catch (error) {\n body = {};\n }\n}\n\nif (!body || typeof body !== 'object' || Array.isArray(body)) {\n body = {};\n}\n\nfunction clean(value) {\n return String(value ?? '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst fileName = clean(\n body.fileName ??\n body.filename ??\n body.file_name ??\n ''\n);\n\nconst country = clean(\n body.country ?? 'GT'\n).toUpperCase();\n\nconst supportedCountries = {\n GT: 'Guatemala',\n TT: 'Trinidad y Tobago',\n PA: 'Panamá',\n SV: 'El Salvador',\n HN: 'Honduras',\n};\n\nconst countryName = clean(\n body.countryName ??\n body.country_name ??\n supportedCountries[country] ??\n ''\n);\n\nconst errors = [];\n\nif (!fileName) {\n errors.push(\n 'No se recibió el nombre del archivo de nómina.'\n );\n}\n\nif (!Object.prototype.hasOwnProperty.call(\n supportedCountries,\n country\n)) {\n errors.push(\n 'El analizador solo está habilitado para Guatemala, Trinidad y Tobago, Panamá, El Salvador y Honduras.'\n );\n}\n\nconst supportedExtensions = [\n '.xlsx',\n '.xls',\n '.xlsm',\n '.csv',\n];\n\nconst lowerFileName = fileName.toLowerCase();\n\nconst hasSupportedExtension =\n supportedExtensions.some((extension) =>\n lowerFileName.endsWith(extension)\n );\n\nif (fileName && !hasSupportedExtension) {\n errors.push(\n 'El archivo recibido no tiene una extensión de nómina compatible.'\n );\n}\n\nreturn [\n {\n json: {\n ok: errors.length === 0,\n errors,\n\n fileName,\n country,\n countryName:\n countryName ||\n supportedCountries[country] ||\n '',\n\n receivedAt: new Date().toISOString(),\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 6640, + 2784 + ], + "id": "6f8d45c3-8dc9-4c58-9ba7-93a9a37877cc", + "name": "Validar y preparar solicitud" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "bd9fd675-d72b-4dba-ac03-a44f1123ecb0", + "leftValue": "={{ $json.ok }}", + "rightValue": "", + "operator": { + "type": "boolean", + "operation": "true", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + 6848, + 2784 + ], + "id": "10aaa8bb-d2b7-48b8-b538-d7f968bba2d0", + "name": "¿Solicitud válida?" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{\n{\n ok: false,\n message:\n 'No fue posible analizar el nombre del archivo.',\n errors: Array.isArray($json.errors)\n ? $json.errors\n : ['La solicitud recibida no es válida.'],\n detected: null\n}\n}}", + "options": { + "responseCode": 400, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 7056, + 2880 + ], + "id": "3c592f6e-f2c5-4b3e-a1b6-56b86045f8b2", + "name": "Responder error" + }, + { + "parameters": { + "text": "={{\n`Analiza este nombre de archivo de nómina:\n\nPaís seleccionado: ${$json.countryName}\nCódigo del país: ${$json.country}\nNombre del archivo: ${$json.fileName}`\n}}", + "schemaType": "manual", + "inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"country\": {\n \"type\": \"string\",\n \"enum\": [\n \"GT\",\n \"TT\",\n \"PA\",\n \"SV\",\n \"HN\"\n ]\n },\n \"year\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"maximum\": 2100\n },\n \"month\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"maximum\": 12\n },\n \"period_type\": {\n \"type\": \"string\",\n \"enum\": [\n \"quincena_15\",\n \"quincena_30\",\n \"mensual\",\n \"desconocido\"\n ]\n },\n \"confidence\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 1\n },\n \"explanation\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"country\",\n \"year\",\n \"month\",\n \"period_type\",\n \"confidence\",\n \"explanation\"\n ],\n \"additionalProperties\": false\n}", + "options": { + "systemPromptTemplate": "Eres un clasificador determinista de nombres de archivos de nómina.\n\nTu tarea es identificar el país seleccionado, el año, el mes y el período de pago utilizando únicamente la información presente en el nombre del archivo y el país recibido.\n\nNo inventes datos que no estén contenidos o razonablemente codificados en el nombre.\n\nREGLAS GENERALES:\n\n1. Devuelve exactamente el código de país recibido:\n - GT para Guatemala.\n - TT para Trinidad y Tobago.\n - PA para Panamá.\n - SV para El Salvador.\n - HN para Honduras.\n\n2. Detecta el año de cuatro dígitos. También puede aparecer dentro de una fecha compacta como YYYYMMDD; por ejemplo, 20260617 representa el año 2026.\n\n3. Convierte el mes a un número aceptando nombres en español o inglés:\n Enero / January = 1\n Febrero / February = 2\n Marzo / March = 3\n Abril / April = 4\n Mayo / May = 5\n Junio / June = 6\n Julio / July = 7\n Agosto / August = 8\n Septiembre / September = 9\n Octubre / October = 10\n Noviembre / November = 11\n Diciembre / December = 12\n\n4. Usa period_type = quincena_15 cuando aparezca cualquiera de estas señales:\n - 1Q\n - Q1\n - Primera quincena\n - 1ra quincena\n - First fortnight\n - First half\n - Mid month\n - Día 15\n - 15th\n\n5. Usa period_type = quincena_30 cuando aparezca cualquiera de estas señales:\n - 2Q\n - Q2\n - Segunda quincena\n - 2da quincena\n - Second fortnight\n - Second half\n - Fin de mes\n - End of month\n - Month end\n - Día 30\n - Día 31\n - 30th\n - 31st\n - El último día real del mes, incluyendo 28 o 29 de febrero\n\n6. Aunque el último día real del mes no sea 30, utiliza quincena_30 para representar la segunda quincena o cierre de mes.\n\n7. Si solamente aparecen el mes y el año, sin ninguna señal de quincena ni día de cierre, utiliza mensual.\n\n8. Para nombres como \"GLM_TT_Payroll June 30TH_20260617.xlsx\":\n - country = TT\n - year = 2026\n - month = 6\n - period_type = quincena_30\n\n9. Para Honduras también reconoce nombres como \"Nomina 7.1 2026 GLM HN.xlsx\" (mes 7, primera quincena) y \"Nomina 7.2 2026 GLM HN.xlsx\" (mes 7, segunda quincena). En general, cuando ese patrón forma parte del nombre de nómina, M.1 = quincena_15 y M.2 = quincena_30.\n\n10. Si no puedes identificar de manera confiable el año o el mes, utiliza:\n year = 0\n month = 0\n period_type = desconocido\n\n11. confidence debe estar entre 0 y 1.\n\n12. explanation debe ser breve y mencionar las señales encontradas en el nombre.\n\nNo agregues campos diferentes a los definidos por el esquema." + } + }, + "type": "@n8n/n8n-nodes-langchain.informationExtractor", + "typeVersion": 1.2, + "position": [ + 7056, + 2512 + ], + "id": "95117474-e746-4a8a-9f7f-66eeb536b5d5", + "name": "Extraer período con Gemini", + "retryOnFail": true, + "waitBetweenTries": 2000, + "onError": "continueRegularOutput" + }, + { + "parameters": { + "modelName": "models/gemini-2.5-pro", + "options": {} + }, + "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", + "typeVersion": 1.1, + "position": [ + 7056, + 2688 + ], + "id": "5f2f1579-5479-4be5-8303-3a03c7f4084c", + "name": "Gemini - Analizar título nómina", + "credentials": { + "googlePalmApi": { + "id": "jvsXYwL6IOoY2DBU", + "name": "Isaac - Gemini Api Pago" + } + } + }, + { + "parameters": { + "jsCode": "const request =\n $('Validar y preparar solicitud').first().json || {};\n\nconst incoming = $input.first().json || {};\n\nfunction cleanText(value) {\n return String(value ?? '')\n .replace(/\\uFEFF/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalizeText(value) {\n return cleanText(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[_\\-.,()[\\]{}]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction parseObject(value) {\n if (\n value &&\n typeof value === 'object' &&\n !Array.isArray(value)\n ) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return {};\n }\n\n const cleaned = value\n .replace(/```json/gi, '')\n .replace(/```/g, '')\n .trim();\n\n try {\n return JSON.parse(cleaned);\n } catch (error) {\n return {};\n }\n}\n\nfunction clamp(value, minimum, maximum) {\n const number = Number(value);\n\n if (!Number.isFinite(number)) {\n return minimum;\n }\n\n return Math.min(\n maximum,\n Math.max(minimum, number)\n );\n}\n\nfunction pad(number) {\n return String(number).padStart(2, '0');\n}\n\nfunction getLastDay(year, month) {\n return new Date(\n Date.UTC(year, month, 0)\n ).getUTCDate();\n}\n\nfunction buildPeriodDates(\n year,\n month,\n periodType\n) {\n if (\n !Number.isInteger(year) ||\n year < 2000 ||\n !Number.isInteger(month) ||\n month < 1 ||\n month > 12\n ) {\n return {\n periodStart: null,\n periodEnd: null,\n };\n }\n\n const lastDay = getLastDay(year, month);\n const yearMonth = `${year}-${pad(month)}`;\n\n if (periodType === 'quincena_15') {\n return {\n periodStart: `${yearMonth}-01`,\n periodEnd: `${yearMonth}-15`,\n };\n }\n\n if (periodType === 'quincena_30') {\n return {\n periodStart: `${yearMonth}-16`,\n periodEnd:\n `${yearMonth}-${pad(lastDay)}`,\n };\n }\n\n if (periodType === 'mensual') {\n return {\n periodStart: `${yearMonth}-01`,\n periodEnd:\n `${yearMonth}-${pad(lastDay)}`,\n };\n }\n\n return {\n periodStart: null,\n periodEnd: null,\n };\n}\n\nconst countryNames = {\n GT: 'Guatemala',\n TT: 'Trinidad y Tobago',\n PA: 'Panamá',\n SV: 'El Salvador',\n HN: 'Honduras',\n};\n\nconst country = ['GT', 'TT', 'PA', 'SV', 'HN'].includes(\n String(request.country || '').toUpperCase()\n)\n ? String(request.country).toUpperCase()\n : 'GT';\n\nconst countryName =\n request.countryName ||\n countryNames[country];\n\nconst monthNames = {\n 1: 'Enero',\n 2: 'Febrero',\n 3: 'Marzo',\n 4: 'Abril',\n 5: 'Mayo',\n 6: 'Junio',\n 7: 'Julio',\n 8: 'Agosto',\n 9: 'Septiembre',\n 10: 'Octubre',\n 11: 'Noviembre',\n 12: 'Diciembre',\n};\n\nconst monthPatterns = [\n ['ENERO', 1],\n ['JANUARY', 1],\n ['JAN', 1],\n\n ['FEBRERO', 2],\n ['FEBRUARY', 2],\n ['FEB', 2],\n\n ['MARZO', 3],\n ['MARCH', 3],\n ['MAR', 3],\n\n ['ABRIL', 4],\n ['APRIL', 4],\n ['APR', 4],\n\n ['MAYO', 5],\n ['MAY', 5],\n\n ['JUNIO', 6],\n ['JUNE', 6],\n ['JUN', 6],\n\n ['JULIO', 7],\n ['JULY', 7],\n ['JUL', 7],\n\n ['AGOSTO', 8],\n ['AUGUST', 8],\n ['AUG', 8],\n\n ['SEPTIEMBRE', 9],\n ['SETIEMBRE', 9],\n ['SEPTEMBER', 9],\n ['SEPT', 9],\n ['SEP', 9],\n\n ['OCTUBRE', 10],\n ['OCTOBER', 10],\n ['OCT', 10],\n\n ['NOVIEMBRE', 11],\n ['NOVEMBER', 11],\n ['NOV', 11],\n\n ['DICIEMBRE', 12],\n ['DECEMBER', 12],\n ['DEC', 12],\n];\n\nconst monthPatternText =\n monthPatterns\n .map(([name]) => name)\n .sort((a, b) => b.length - a.length)\n .join('|');\n\nconst validPeriodTypes = new Set([\n 'quincena_15',\n 'quincena_30',\n 'mensual',\n 'desconocido',\n]);\n\nconst fileName = cleanText(request.fileName);\nconst normalizedFileName =\n normalizeText(fileName);\n\nconst hondurasDecimal = country === 'HN'\n ? fileName.match(/(?:nomina|nómina)?\\s*(\\d{1,2})\\.(1|2)\\s+(20\\d{2})/i)\n : null;\n\nconst compactDateMatch =\n normalizedFileName.match(\n /\\b(20\\d{2})(0[1-9]|1[0-2])([0-2]\\d|3[01])\\b/\n );\n\nconst standaloneYearMatch =\n normalizedFileName.match(/\\b(20\\d{2})\\b/);\n\nconst fallbackYear = hondurasDecimal\n ? Number(hondurasDecimal[3])\n : standaloneYearMatch\n ? Number(standaloneYearMatch[1])\n : compactDateMatch\n ? Number(compactDateMatch[1])\n : 0;\n\nlet fallbackMonth = hondurasDecimal ? Number(hondurasDecimal[1]) : 0;\n\nfor (const [monthName, monthNumber] of monthPatterns) {\n const monthRegex = new RegExp(\n `\\\\b${monthName}\\\\b`\n );\n\n if (monthRegex.test(normalizedFileName)) {\n fallbackMonth = monthNumber;\n break;\n }\n}\n\nif (!fallbackMonth && compactDateMatch) {\n fallbackMonth = Number(compactDateMatch[2]);\n}\n\nconst monthThenDayRegex = new RegExp(\n `\\\\b(?:${monthPatternText})\\\\s+([0-3]?\\\\d)(?:ST|ND|RD|TH)?\\\\b`\n);\n\nconst dayThenMonthRegex = new RegExp(\n `\\\\b([0-3]?\\\\d)(?:ST|ND|RD|TH)?\\\\s+(?:DE\\\\s+)?(?:${monthPatternText})\\\\b`\n);\n\nconst explicitDayRegex =\n /\\b(?:DIA|DAY)\\s+([0-3]?\\d)(?:ST|ND|RD|TH)?\\b/;\n\nconst monthThenDayMatch =\n normalizedFileName.match(monthThenDayRegex);\n\nconst dayThenMonthMatch =\n normalizedFileName.match(dayThenMonthRegex);\n\nconst explicitDayMatch =\n normalizedFileName.match(explicitDayRegex);\n\nconst detectedDay = monthThenDayMatch\n ? Number(monthThenDayMatch[1])\n : dayThenMonthMatch\n ? Number(dayThenMonthMatch[1])\n : explicitDayMatch\n ? Number(explicitDayMatch[1])\n : 0;\n\nconst firstFortnight =\n /\\b(1Q|Q1)\\b/.test(normalizedFileName) ||\n normalizedFileName.includes(\n 'PRIMERA QUINCENA'\n ) ||\n normalizedFileName.includes(\n '1RA QUINCENA'\n ) ||\n normalizedFileName.includes(\n 'FIRST FORTNIGHT'\n ) ||\n normalizedFileName.includes(\n 'FIRST HALF'\n ) ||\n normalizedFileName.includes(\n 'MID MONTH'\n ) ||\n normalizedFileName.includes(\n 'MIDMONTH'\n );\n\nconst secondFortnight =\n /\\b(2Q|Q2)\\b/.test(normalizedFileName) ||\n normalizedFileName.includes(\n 'SEGUNDA QUINCENA'\n ) ||\n normalizedFileName.includes(\n '2DA QUINCENA'\n ) ||\n normalizedFileName.includes(\n 'SECOND FORTNIGHT'\n ) ||\n normalizedFileName.includes(\n 'SECOND HALF'\n ) ||\n normalizedFileName.includes(\n 'FIN DE MES'\n ) ||\n normalizedFileName.includes(\n 'END OF MONTH'\n ) ||\n normalizedFileName.includes(\n 'MONTH END'\n ) ||\n normalizedFileName.includes(\n 'MONTHEND'\n );\n\nlet fallbackPeriodType = 'desconocido';\nlet fallbackConfidence = 0.2;\nlet strongPeriodEvidence = false;\n\nif (hondurasDecimal) {\n fallbackPeriodType = hondurasDecimal[2] === '1' ? 'quincena_15' : 'quincena_30';\n fallbackConfidence = 1;\n strongPeriodEvidence = true;\n} else if (firstFortnight) {\n fallbackPeriodType = 'quincena_15';\n fallbackConfidence = 0.98;\n strongPeriodEvidence = true;\n} else if (secondFortnight) {\n fallbackPeriodType = 'quincena_30';\n fallbackConfidence = 0.98;\n strongPeriodEvidence = true;\n} else if (detectedDay === 15) {\n fallbackPeriodType = 'quincena_15';\n fallbackConfidence = 0.95;\n strongPeriodEvidence = true;\n} else if (\n fallbackYear &&\n fallbackMonth &&\n detectedDay === getLastDay(\n fallbackYear,\n fallbackMonth\n )\n) {\n fallbackPeriodType = 'quincena_30';\n fallbackConfidence = 0.95;\n strongPeriodEvidence = true;\n} else if (\n detectedDay === 30 ||\n detectedDay === 31\n) {\n fallbackPeriodType = 'quincena_30';\n fallbackConfidence = 0.94;\n strongPeriodEvidence = true;\n} else if (\n fallbackYear &&\n fallbackMonth\n) {\n fallbackPeriodType = 'mensual';\n fallbackConfidence = 0.75;\n}\n\nlet rawAI =\n incoming.output ??\n incoming.result ??\n incoming.text ??\n incoming;\n\nrawAI = parseObject(rawAI);\n\nconst aiCountry =\n String(rawAI.country || '').toUpperCase();\n\nconst aiYear = Number(rawAI.year);\nconst aiMonth = Number(rawAI.month);\n\nconst aiPeriodType =\n validPeriodTypes.has(rawAI.period_type)\n ? rawAI.period_type\n : 'desconocido';\n\nconst aiConfidence = clamp(\n rawAI.confidence,\n 0,\n 1\n);\n\nconst aiIsUsable =\n Number.isInteger(aiYear) &&\n aiYear >= 2000 &&\n aiYear <= 2100 &&\n Number.isInteger(aiMonth) &&\n aiMonth >= 1 &&\n aiMonth <= 12 &&\n aiPeriodType !== 'desconocido';\n\nlet year =\n fallbackYear ||\n (aiIsUsable ? aiYear : 0);\n\nlet month =\n fallbackMonth ||\n (aiIsUsable ? aiMonth : 0);\n\nlet periodType =\n aiIsUsable\n ? aiPeriodType\n : fallbackPeriodType;\n\nlet source =\n aiIsUsable\n ? 'gemini'\n : 'local_fallback';\n\nlet confidence =\n aiIsUsable\n ? aiConfidence\n : fallbackConfidence;\n\nlet conflictResolved = false;\n\nif (\n aiCountry &&\n aiCountry !== country\n) {\n source = 'gemini_validated_with_rules';\n conflictResolved = true;\n}\n\nif (\n strongPeriodEvidence &&\n periodType !== fallbackPeriodType\n) {\n periodType = fallbackPeriodType;\n source = 'gemini_validated_with_rules';\n confidence = Math.max(\n fallbackConfidence,\n Math.min(aiConfidence, 0.9)\n );\n conflictResolved = true;\n}\n\nif (\n fallbackYear &&\n aiIsUsable &&\n aiYear !== fallbackYear\n) {\n year = fallbackYear;\n source = 'gemini_validated_with_rules';\n conflictResolved = true;\n}\n\nif (\n fallbackMonth &&\n aiIsUsable &&\n aiMonth !== fallbackMonth\n) {\n month = fallbackMonth;\n source = 'gemini_validated_with_rules';\n conflictResolved = true;\n}\n\nif (\n !aiIsUsable &&\n fallbackYear &&\n fallbackMonth\n) {\n year = fallbackYear;\n month = fallbackMonth;\n periodType = fallbackPeriodType;\n confidence = fallbackConfidence;\n source = 'local_fallback';\n}\n\nconst complete =\n year >= 2000 &&\n month >= 1 &&\n month <= 12 &&\n periodType !== 'desconocido';\n\nconst dates = buildPeriodDates(\n year,\n month,\n periodType\n);\n\nlet periodDescription = 'Período desconocido';\n\nif (periodType === 'quincena_15') {\n periodDescription = 'Quincena 15';\n}\n\nif (periodType === 'quincena_30') {\n periodDescription =\n 'Quincena 30 / fin de mes';\n}\n\nif (periodType === 'mensual') {\n periodDescription = 'Mensual';\n}\n\nconst monthLabel =\n monthNames[month] || 'Mes desconocido';\n\nconst periodLabel = complete\n ? `${monthLabel} ${year} · ${periodDescription}`\n : 'Período pendiente de confirmar';\n\nconst requiresManualReview =\n !complete ||\n confidence < 0.75;\n\nconst explanation =\n cleanText(rawAI.explanation) ||\n (\n source === 'local_fallback'\n ? 'El período fue identificado mediante las reglas locales de respaldo.'\n : 'El período fue identificado mediante Gemini y validado con las reglas del portal.'\n );\n\nreturn [\n {\n json: {\n ok: true,\n\n message: requiresManualReview\n ? 'El archivo fue analizado, pero el período debe confirmarse manualmente.'\n : 'El período de la nómina fue detectado correctamente.',\n\n detected: {\n country,\n countryName,\n\n fileName,\n\n year,\n month,\n\n periodType,\n period_type: periodType,\n\n periodLabel,\n period_label: periodLabel,\n\n periodStart: dates.periodStart,\n period_start: dates.periodStart,\n\n periodEnd: dates.periodEnd,\n period_end: dates.periodEnd,\n\n confidence:\n Math.round(confidence * 100) / 100,\n\n complete,\n requiresManualReview,\n requires_manual_review:\n requiresManualReview,\n\n source,\n conflictResolved,\n explanation,\n },\n\n debug: {\n fallback: {\n country,\n year: fallbackYear,\n month: fallbackMonth,\n periodType: fallbackPeriodType,\n detectedDay,\n confidence: fallbackConfidence,\n strongPeriodEvidence,\n compactDate:\n compactDateMatch?.[0] || null,\n },\n\n gemini: {\n country: aiCountry || null,\n year: aiYear || 0,\n month: aiMonth || 0,\n periodType: aiPeriodType,\n confidence: aiConfidence,\n explanation:\n cleanText(rawAI.explanation),\n },\n },\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 7392, + 2528 + ], + "id": "0c24e1d9-1abb-4c8b-934e-d1cd7d0db5fc", + "name": "Normalizar análisis IA" + }, + { + "parameters": { + "options": { + "responseCode": 200, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 7600, + 2528 + ], + "id": "7c889159-aba3-4288-851e-d4c117453465", + "name": "Responder análisis" + }, + { + "parameters": { + "content": "# 🧠 ANÁLISIS AUTOMÁTICO DE NÓMINA — GT, TT, PA y SV\n\nAnaliza el nombre o título del archivo de nómina para identificar automáticamente el período correspondiente antes de ejecutar la verificación.\n\n## Recepción y validación\n\nEl Webhook recibe desde el Portal de Verificación de Nóminas la información del archivo seleccionado.\n\nLa solicitud puede incluir:\n\n- Nombre del archivo.\n- Título o descripción disponible.\n- País o portal de origen.\n- Identificador de la solicitud.\n- Información complementaria enviada por la aplicación.\n\nAntes de utilizar inteligencia artificial, el flujo valida que exista suficiente información para analizar el archivo.\n\n## Extracción con Gemini\n\nCuando la solicitud es válida, Gemini interpreta el nombre o título de la nómina e intenta determinar:\n\n- Año.\n- Mes.\n- Tipo de período.\n- Quincena 15.\n- Quincena 30 o fin de mes.\n- Nómina mensual.\n- País, cuando puede inferirse de forma confiable.\n- Nivel de confianza del análisis.\n\nGemini se utiliza únicamente para interpretar el texto recibido; no ejecuta el cruce de nómina ni modifica información.\n\n## Normalización del resultado\n\nLa respuesta de Gemini se transforma al formato requerido por la aplicación.\n\nEste bloque:\n\n- Limpia texto adicional generado por la IA.\n- Normaliza el año a formato numérico.\n- Convierte el mes al valor esperado por el portal.\n- Estandariza el tipo de período.\n- Corrige variaciones como “segunda quincena”, “fin de mes” o “30”.\n- Conserva los valores originales cuando la IA no puede determinar un dato.\n- Prepara una respuesta consistente para Guatemala, Trinidad y Tobago, Panamá y El Salvador.\n\n## Respuesta al portal\n\nCuando el análisis termina, el workflow devuelve a la aplicación:\n\n- Indicador de éxito.\n- Año detectado.\n- Mes detectado.\n- Tipo de período detectado.\n- País identificado, cuando corresponda.\n- Nivel de confianza.\n- Datos que requieren revisión manual.\n\nLos valores detectados sirven para completar automáticamente el formulario, pero el usuario puede corregirlos antes de ejecutar el proceso.\n\n## Ruta de error\n\nCuando la solicitud es inválida:\n\n- No se llama a Gemini.\n- No se intenta interpretar información incompleta.\n- Se devuelve una respuesta de error al portal.\n- Se indica que falta el nombre del archivo u otro dato obligatorio.\n\n## Reglas\n\n- No inventar un período cuando el título no contiene información suficiente.\n- No ejecutar el cruce de nómina desde este workflow.\n- No tratar una predicción de baja confianza como un dato definitivo.\n- Mantener la opción de corrección manual en la aplicación.\n- Responder siempre al Webhook, tanto en la ruta válida como en la ruta de error.\n- Utilizar una estructura de respuesta compatible con los portales de Guatemala, Trinidad y Tobago, Panamá y El Salvador.", + "height": 1488, + "width": 2256, + "color": 2 + }, + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 5568, + 1968 + ], + "id": "a32f6dbb-6c5b-4505-a79e-593d8799c41c", + "name": "Sticky Note" + } + ], + "pinData": {}, + "connections": { + "Webhook - Analizar Nómina": { + "main": [ + [ + { + "node": "Validar y preparar solicitud", + "type": "main", + "index": 0 + } + ] + ] + }, + "Validar y preparar solicitud": { + "main": [ + [ + { + "node": "¿Solicitud válida?", + "type": "main", + "index": 0 + } + ] + ] + }, + "¿Solicitud válida?": { + "main": [ + [ + { + "node": "Extraer período con Gemini", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Responder error", + "type": "main", + "index": 0 + } + ] + ] + }, + "Gemini - Analizar título nómina": { + "ai_languageModel": [ + [ + { + "node": "Extraer período con Gemini", + "type": "ai_languageModel", + "index": 0 + } + ] + ] + }, + "Extraer período con Gemini": { + "main": [ + [ + { + "node": "Normalizar análisis IA", + "type": "main", + "index": 0 + } + ] + ] + }, + "Normalizar análisis IA": { + "main": [ + [ + { + "node": "Responder análisis", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": { + "executionOrder": "v1", + "binaryMode": "separate", + "availableInMCP": true, + "timeSavedMode": "fixed", + "errorWorkflow": "puF4LUczoSz3hcek", + "timezone": "America/Santo_Domingo", + "callerPolicy": "workflowsFromSameOwner" + }, + "versionId": "6bf17633-b996-46d8-8ac2-ee59c9137093", + "meta": { + "templateCredsSetupCompleted": true, + "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" + }, + "tags": [] +} \ No newline at end of file diff --git a/workflows_n8n/Portal de Verificaci├│n de N├│mina - Puerto Rico.json b/workflows_n8n/Portal de Verificaci├│n de N├│mina - Puerto Rico.json index c0d421a..42a8a0e 100644 --- a/workflows_n8n/Portal de Verificaci├│n de N├│mina - Puerto Rico.json +++ b/workflows_n8n/Portal de Verificaci├│n de N├│mina - Puerto Rico.json @@ -11,10 +11,10 @@ "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ - -2800, - 5200 + -1088, + 512 ], - "id": "e07fef4a-5007-452d-b75e-975757344c59", + "id": "cce6050e-e39e-4f9b-8af2-c1b7a2f756ad", "name": "Webhook", "webhookId": "00132835-9daf-4f36-95ee-233ff6f7b691" }, @@ -25,10 +25,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -2560, - 5200 + -848, + 512 ], - "id": "1753550c-cf8b-48eb-ba58-0a8642163242", + "id": "0b3dff96-467b-4a56-8da0-e93ae51f4c44", "name": "Preparar entrada app" }, { @@ -38,10 +38,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -2080, - 4960 + -368, + 272 ], - "id": "eba2da3b-8ca3-49bd-9679-a61a1270c8f8", + "id": "af3c16fb-60a1-4f0f-a604-bf33ee3c7ac8", "name": "Preparar PDF banco PR" }, { @@ -51,10 +51,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -2080, - 5440 + -368, + 752 ], - "id": "2b1028fb-bee3-4b82-bb5c-78c534959b20", + "id": "5e49fc7d-692e-467f-9618-509f13a8674e", "name": "Preparar archivos nómina PR" }, { @@ -69,10 +69,10 @@ "type": "n8n-nodes-base.extractFromFile", "typeVersion": 1.1, "position": [ - -1840, - 5440 + -128, + 752 ], - "id": "ec028b3b-a794-462a-a33b-afb839928069", + "id": "f52d1ad9-6b32-4ea3-891b-2a16f804c4c9", "name": "Extract - Archivo Nómina PR", "retryOnFail": false, "onError": "continueRegularOutput" @@ -84,10 +84,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -1600, - 5440 + 112, + 752 ], - "id": "1e1a261f-8711-49db-9640-aa64f3540fdd", + "id": "b74e9e31-da6e-4eca-a620-ec70c92b1fa3", "name": "Normalizar Nómina PR" }, { @@ -99,10 +99,10 @@ "type": "n8n-nodes-base.merge", "typeVersion": 3.2, "position": [ - -1320, - 5200 + 400, + 512 ], - "id": "349328dc-e99b-499a-b79b-bbf62918ba68", + "id": "6ddf574c-188e-40a3-b657-8a415114d2b0", "name": "Merge Banco + Nómina PR" }, { @@ -156,10 +156,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - -1080, - 5040 + 640, + 352 ], - "id": "396dcc5d-eb94-4f6d-a234-9adaa99baa7b", + "id": "a0035219-8292-4154-b840-8fcf8d8b32d4", "name": "HTTP - Empleados BambooHR PR", "retryOnFail": true, "maxTries": 3, @@ -178,10 +178,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -840, - 5040 + 880, + 352 ], - "id": "c9609568-0db8-42c7-8629-601841c2c3d7", + "id": "ed8d309b-9742-4eba-a0c4-6b3fbe77c9cd", "name": "Normalizar BambooHR PR" }, { @@ -193,10 +193,10 @@ "type": "n8n-nodes-base.merge", "typeVersion": 3.2, "position": [ - -600, - 5200 + 1120, + 512 ], - "id": "0d44d9e2-bf49-400c-873c-c9adb8bcbbd3", + "id": "17f7daaa-1093-4885-86e8-071ba9bdc366", "name": "Merge - Agregar BambooHR PR" }, { @@ -241,10 +241,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - -360, - 5200 + 1360, + 512 ], - "id": "b8e487d1-2745-4fce-a4ae-00a1ceb44bab", + "id": "f0d44f40-cf96-4385-b4f3-4220af926fbd", "name": "Obtener alias BambooHR Supabase", "retryOnFail": true, "maxTries": 2, @@ -253,15 +253,15 @@ }, { "parameters": { - "jsCode": "const data = $('Merge - Agregar BambooHR PR').first().json || {};\nconst aliasResponse = $input.first().json || {};\nconst validatedBambooAliases = Array.isArray(aliasResponse.aliases)\n ? aliasResponse.aliases\n : Array.isArray(aliasResponse)\n ? aliasResponse\n : [];\n\nfunction clean(value) {\n return String(value ?? '')\n .replace(/\\uFEFF/g, '')\n .replace(/\\u00A0/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst normalizedNameCache = new Map();\nconst nameWordsCache = new Map();\nconst nameMatchScoreCache = new Map();\n\nfunction normalizeName(value) {\n const raw = clean(value);\n if (normalizedNameCache.has(raw)) {\n return normalizedNameCache.get(raw);\n }\n\n const normalized = raw\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/['’`-]/g, ' ')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n\n normalizedNameCache.set(raw, normalized);\n return normalized;\n}\n\nfunction normalizeAccount(value) {\n return String(value ?? '').replace(/\\.0$/g, '').replace(/\\D/g, '').trim();\n}\n\nfunction normalizeEmployeeNumber(value) {\n return String(value ?? '')\n .replace(/\\u00A0/g, '')\n .replace(/\\D/g, '')\n .trim();\n}\n\nfunction roundMoney(value) {\n return Math.round((Number(value) || 0) * 100) / 100;\n}\n\nfunction moneyDiff(payroll, bank) {\n return roundMoney((Number(payroll) || 0) - (Number(bank) || 0));\n}\n\nconst MONEY_TOLERANCE = 0.01;\nconst MONEY_TOLERANCE_CENTS = Math.round(MONEY_TOLERANCE * 100);\n\nfunction sameCent(a, b) {\n return Math.abs(moneyDiff(a, b)) <= MONEY_TOLERANCE + 1e-9;\n}\n\nconst IGNORED_NAME_TOKENS = new Set([\n 'de', 'del', 'la', 'las', 'los', 'y', 'e', 'el',\n 'da', 'do', 'dos', 'das', 'van', 'von',\n]);\n\nfunction nameWords(value) {\n const normalized = normalizeName(value);\n if (nameWordsCache.has(normalized)) {\n return nameWordsCache.get(normalized);\n }\n\n const words = normalized\n .split(' ')\n .filter((word) => word.length > 1 && !IGNORED_NAME_TOKENS.has(word));\n\n nameWordsCache.set(normalized, words);\n return words;\n}\n\nfunction editDistance(a, b) {\n if (a === b) return 0;\n if (!a) return b.length;\n if (!b) return a.length;\n let previous = Array.from({ length: b.length + 1 }, (_, index) => index);\n for (let i = 1; i <= a.length; i++) {\n const current = [i];\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n current[j] = Math.min(current[j - 1] + 1, previous[j] + 1, previous[j - 1] + cost);\n }\n previous = current;\n }\n return previous[b.length];\n}\n\nfunction tokenMatches(a, b) {\n if (a === b) return true;\n const minLength = Math.min(a.length, b.length);\n if (minLength >= 8 && editDistance(a, b) <= 2) return true;\n if (minLength >= 5 && editDistance(a, b) <= 1) return true;\n return false;\n}\n\nfunction samePersonName(a, b) {\n const normalizedA = normalizeName(a);\n const normalizedB = normalizeName(b);\n if (!normalizedA || !normalizedB) return false;\n if (normalizedA === normalizedB) return true;\n\n const wordsA = nameWords(a);\n const wordsB = nameWords(b);\n if (!wordsA.length || !wordsB.length) return false;\n\n const usedB = new Set();\n let matches = 0;\n for (const wordA of wordsA) {\n const matchIndex = wordsB.findIndex((wordB, index) =>\n !usedB.has(index) && tokenMatches(wordA, wordB)\n );\n if (matchIndex >= 0) {\n usedB.add(matchIndex);\n matches += 1;\n }\n }\n\n const smallerLength = Math.min(wordsA.length, wordsB.length);\n const ratio = matches / smallerLength;\n if (smallerLength <= 2) return matches === smallerLength && matches >= 2;\n return matches >= 2 && ratio >= 0.6;\n}\n\nfunction bankNameLooksConsistent(fileName, holderName) {\n const fileWords = nameWords(fileName);\n const holderWords = nameWords(holderName);\n\n if (!fileWords.length || !holderWords.length) return true;\n\n const used = new Set();\n\n for (const fileWord of fileWords) {\n let matchIndex = holderWords.findIndex(\n (holderWord, index) =>\n !used.has(index) &&\n holderWord === fileWord\n );\n\n // Algunos planos de Puerto Rico recortan el último carácter del apellido\n // por longitud de campo (ej.: ALVARAD -> ALVARADO). Eso no debe\n // convertirse en una diferencia de nombre. No se aceptan sustituciones\n // ortográficas (ej.: GONZALES -> GONZALEZ), porque sí requieren revisión.\n if (matchIndex < 0) {\n matchIndex = holderWords.findIndex(\n (holderWord, index) =>\n !used.has(index) &&\n holderWord.startsWith(fileWord) &&\n (\n (fileWord.length <= 3) ||\n (\n fileWord.length >= 4 &&\n holderWord.length === fileWord.length + 1\n )\n )\n );\n }\n\n if (matchIndex < 0) return false;\n used.add(matchIndex);\n }\n\n return true;\n}\n\nfunction nameMatchScore(a, b) {\n const na = normalizeName(a);\n const nb = normalizeName(b);\n if (!na || !nb) return 0;\n\n const cacheKey = na <= nb ? `${na}\\u0000${nb}` : `${nb}\\u0000${na}`;\n if (nameMatchScoreCache.has(cacheKey)) {\n return nameMatchScoreCache.get(cacheKey);\n }\n\n if (na === nb) {\n nameMatchScoreCache.set(cacheKey, 1);\n return 1;\n }\n\n const wa = nameWords(a);\n const wb = nameWords(b);\n if (!samePersonName(a, b)) {\n nameMatchScoreCache.set(cacheKey, 0);\n return 0;\n }\n\n const setA = new Set(wa);\n const setB = new Set(wb);\n let exact = 0;\n for (const w of setA) if (setB.has(w)) exact += 1;\n const min = Math.max(1, Math.min(setA.size, setB.size));\n const score = Math.min(\n 0.99,\n 0.75 + (exact / min) * 0.20 + (wa.length === wb.length ? 0.04 : 0)\n );\n\n nameMatchScoreCache.set(cacheKey, score);\n return score;\n}\n\nfunction bankNames(row) {\n return [row.bank_name_file, row.bank_account_holder]\n .map(clean)\n .filter(Boolean);\n}\n\nfunction bestNameScore(payrollName, bankRow) {\n return Math.max(0, ...bankNames(bankRow).map((name) => nameMatchScore(payrollName, name)));\n}\n\nfunction bankDisplayName(row) {\n return clean(row.bank_name_file) || clean(row.bank_account_holder) || 'Pago bancario';\n}\n\nfunction bankRowKey(row, index) {\n return clean(row.bank_row_key) || `${clean(row.source_file)}|${row.row_number || index + 1}`;\n}\n\n\nconst metadata = data.metadata || {};\n\nfunction parseBankDate(value, sourceFile = '') {\n const raw = clean(value);\n let match = raw.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})/);\n if (match) {\n return {\n year: Number(match[3]),\n month: Number(match[2]),\n day: Number(match[1]),\n };\n }\n\n match = raw.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})/);\n if (match) {\n return {\n year: Number(match[1]),\n month: Number(match[2]),\n day: Number(match[3]),\n };\n }\n\n // Respaldo por el patrón habitual del nombre: _DDMMYY / _DDMMYYYY.\n const fileMatch = clean(sourceFile).match(/_(\\d{2})(\\d{2})(\\d{2}|\\d{4})(?:\\D|$)/);\n if (!fileMatch) return null;\n\n const yearPart = Number(fileMatch[3]);\n return {\n year: fileMatch[3].length === 2 ? 2000 + yearPart : yearPart,\n month: Number(fileMatch[2]),\n day: Number(fileMatch[1]),\n };\n}\n\nfunction selectedPeriodKind() {\n const type = clean(metadata.period_type).toLowerCase();\n if (type === 'quincena_15') return 'q15';\n if (type === 'quincena_30') return 'q30';\n return 'unknown';\n}\n\nfunction conceptPeriodHint(row) {\n const concept = normalizeName(row.concept || '');\n if (!concept) return 'unknown';\n\n if (\n /(?:^| )1(?:ra|er|era)? quincena(?: |$)/.test(concept) ||\n concept.includes('primera quincena') ||\n concept.includes('quincena 1ra') ||\n concept.includes('quincena 1')\n ) {\n return 'q15';\n }\n\n if (\n /(?:^| )2(?:da|do|nda)? quincena(?: |$)/.test(concept) ||\n concept.includes('segunda quincena') ||\n concept.includes('quincena 2da') ||\n concept.includes('quincena 2') ||\n concept.includes('fin de mes')\n ) {\n return 'q30';\n }\n\n return 'unknown';\n}\n\nfunction periodInfoForBankRow(row) {\n const selected = selectedPeriodKind();\n const rowDate = parseBankDate(row.application_date, row.source_file);\n const selectedYear = Number(metadata.year || 0);\n const selectedMonth = Number(metadata.month || 0);\n const hint = conceptPeriodHint(row);\n\n if (selected === 'unknown') {\n return { known: false, selected, inPeriod: true, affinity: 1, rowDate, hint };\n }\n\n if (hint !== 'unknown' && hint === selected) {\n return { known: true, selected, inPeriod: true, affinity: 4, rowDate, hint };\n }\n\n if (!rowDate || !selectedYear || !selectedMonth) {\n return { known: false, selected, inPeriod: true, affinity: 1, rowDate, hint };\n }\n\n if (rowDate.year !== selectedYear || rowDate.month !== selectedMonth) {\n return { known: true, selected, inPeriod: false, affinity: 0, rowDate, hint };\n }\n\n const inHalf = selected === 'q15'\n ? rowDate.day <= 15\n : rowDate.day >= 16;\n\n return {\n known: true,\n selected,\n inPeriod: inHalf,\n affinity: inHalf ? 3 : 0,\n rowDate,\n hint,\n };\n}\n\nfunction isSupplementPayroll(payroll) {\n return clean(payroll?.source_kind).toLowerCase() !== 'quincenal';\n}\n\nfunction bankCandidatePeriodScore(payroll, bank) {\n const info = periodInfoForBankRow(bank);\n if (!info.known || info.inPeriod) return info.affinity || 1;\n\n // Una extraordinaria/vacación/XIII Mes puede pagarse fuera de la mitad\n // estricta del mes. Se permite como respaldo, siempre detrás de cualquier\n // candidato del período seleccionado.\n if (isSupplementPayroll(payroll) && info.rowDate) {\n const selectedYear = Number(metadata.year || 0);\n const selectedMonth = Number(metadata.month || 0);\n if (info.rowDate.year === selectedYear && info.rowDate.month === selectedMonth) {\n return 0.5;\n }\n }\n\n return -1;\n}\n\nconst payrollRows = Array.isArray(data.payroll?.rows) ? data.payroll.rows : [];\nconst bankRows = Array.isArray(data.bank?.rows) ? data.bank.rows : [];\n\n// Guardia de seguridad: nunca generar un reporte \"válido\" cuando el request\n// traía archivos pero el parser no consiguió ninguna fila. Esto evita que\n// todas las personas de nómina aparezcan falsamente como discrepancias.\nif (payrollRows.length === 0) {\n throw new Error(\n 'Puerto Rico: no se pudo leer ninguna fila válida de nómina. ' +\n 'Revisa los archivo Excel de Puerto Rico y las hojas Whirlpool, Personal 2 y Personal 3.'\n );\n}\n\nif (bankRows.length === 0) {\n const detectedFiles = Number(data.bank?.files_count || data.summary?.bank_files_count || 0);\n const invalidFiles = Array.isArray(data.bank?.file_summaries)\n ? data.bank.file_summaries.filter((file) => file?.ok === false)\n : [];\n\n throw new Error(\n 'Puerto Rico: no se pudo leer ninguna transacción bancaria. ' +\n `Archivos bancarios detectados: ${detectedFiles}. ` +\n (invalidFiles.length\n ? `Archivos con error de formato: ${invalidFiles.map((file) => file.file_name).join(', ')}.`\n : 'Verifica que el PDF sea el Transaction Detail Report de Banco Popular de Puerto Rico.')\n );\n}\n\nconst bambooEmployees = Array.isArray(data.bamboo?.employees) ? data.bamboo.employees : [];\nconst resolvedNameMatches = data.bamboo?.resolved_name_matches || {};\nconst bambooValidationAvailable = data.bamboo?.fetch_complete === true &&\n data.bamboo?.validation_available === true && bambooEmployees.length > 0;\n\nconst bambooByEmployeeNumber = new Map();\nconst bambooById = new Map();\nconst bambooByExactName = new Map();\nfor (const employee of bambooEmployees) {\n const number = normalizeEmployeeNumber(\n employee.employee_number || employee.employeeNumber\n );\n const id = clean(employee.bamboo_id || employee.id);\n if (number) {\n const arr = bambooByEmployeeNumber.get(number) || [];\n arr.push(employee);\n bambooByEmployeeNumber.set(number, arr);\n }\n if (id) bambooById.set(id, employee);\n for (const alias of employee.aliases || [employee.full_name]) {\n const normalized = normalizeName(alias);\n if (!normalized) continue;\n const arr = bambooByExactName.get(normalized) || [];\n arr.push(employee);\n bambooByExactName.set(normalized, arr);\n }\n}\n\nfunction employeeKey(employee) {\n return clean(employee?.bamboo_id || employee?.id) ||\n clean(employee?.employee_number || employee?.employeeNumber) ||\n normalizeName(employee?.full_name || employee?.displayName);\n}\n\nfunction validatedAliasDecision(row) {\n if (!validatedBambooAliases.length) return null;\n const rowAccount = normalizeAccount(row.account);\n const names = bankNames(row).map(normalizeName).filter(Boolean);\n const candidates = validatedBambooAliases.filter((alias) => {\n const country = clean(alias.pais || alias.country).toUpperCase();\n if (country && country !== 'PR') return false;\n const source = normalizeName(alias.nombre_origen || alias.source_name || alias.alias || '');\n if (!source || !names.includes(source)) return false;\n const aliasAccount = normalizeAccount(alias.cuenta_bancaria || alias.cuenta_banco || alias.bank_account || '');\n return !aliasAccount || !rowAccount || aliasAccount === rowAccount;\n });\n if (candidates.length !== 1) return null;\n const alias = candidates[0];\n let employee = null;\n const employeeNumber = normalizeEmployeeNumber(\n alias.bamboo_employee_number || ''\n );\n const bambooId = clean(alias.bamboo_employee_id || '');\n const bambooName = normalizeName(alias.bamboo_nombre || '');\n if (employeeNumber && (bambooByEmployeeNumber.get(employeeNumber) || []).length === 1) {\n employee = bambooByEmployeeNumber.get(employeeNumber)[0];\n } else if (bambooId && bambooById.has(bambooId)) {\n employee = bambooById.get(bambooId);\n } else if (bambooName && (bambooByExactName.get(bambooName) || []).length === 1) {\n employee = bambooByExactName.get(bambooName)[0];\n }\n if (!employee) return null;\n return {\n found: true,\n matched_by: 'validated_bamboo_alias',\n confidence: 1,\n employee,\n employee_key: employeeKey(employee),\n bamboo_alias: clean(alias.bamboo_nombre) || employee.full_name || '',\n };\n}\n\nfunction precomputedDecision(name) {\n const normalized = normalizeName(name);\n if (!normalized) return null;\n const decision = resolvedNameMatches[normalized];\n if (!decision || decision.found !== true) return null;\n const index = Number(decision.employee_index);\n const employee = Number.isInteger(index) && index >= 0 ? bambooEmployees[index] : null;\n const key = clean(decision.employee_key) || employeeKey(employee);\n if (!key) return null;\n return {\n found: true,\n matched_by: decision.matched_by || 'precomputed_name',\n confidence: Number(decision.confidence || 0),\n employee,\n employee_key: key,\n bamboo_alias: clean(decision.bamboo_alias) || employee?.full_name || '',\n query_name: clean(name),\n };\n}\n\nfunction resolveBamboo(\n row,\n linkedPayrollNames = [],\n linkedPayrollEmployeeNumbers = []\n) {\n if (!bambooValidationAvailable) {\n return {\n found: false,\n reason: 'validation_unavailable',\n };\n }\n\n const validated = validatedAliasDecision(row);\n if (validated) return validated;\n\n /*\n * Puerto Rico: si existe un identificador fuerte procedente de nómina se puede usar como respaldo para determinar\n * si el pago pertenece a una persona existente en BambooHR.\n *\n * Se normalizan guiones/espacios tanto en banco como en BambooHR:\n * 0611198400414 <-> 0611-1984-00414\n *\n * Como respaldo, cuando la fila bancaria ya fue conciliada con nómina,\n * también se usa el Employee Number/Identidad de esa fila de nómina.\n * Solo se acepta el identificador cuando apunta a UNA sola persona.\n */\n const referenceEmployeeNumbers = Array.from(\n new Set(\n [\n row.reference,\n row.participant_id,\n row.employee_number,\n row.employeeNumber,\n ...linkedPayrollEmployeeNumbers,\n ]\n .flatMap((value) =>\n String(value ?? '').match(/\\d{6,20}/g) || []\n )\n .map(normalizeEmployeeNumber)\n .filter((value) => value.length >= 6)\n )\n );\n\n const employeesByStrongIdentifier = new Map();\n\n for (const employeeNumber of referenceEmployeeNumbers) {\n const matches =\n bambooByEmployeeNumber.get(employeeNumber) || [];\n\n if (matches.length !== 1) continue;\n\n const employee = matches[0];\n const key = employeeKey(employee);\n\n if (key) {\n employeesByStrongIdentifier.set(\n key,\n {\n employee,\n employee_number: employeeNumber,\n }\n );\n }\n }\n\n if (employeesByStrongIdentifier.size === 1) {\n const resolved =\n employeesByStrongIdentifier.values().next().value;\n\n return {\n found: true,\n matched_by: 'bank_or_payroll_employee_number',\n confidence: 1,\n employee: resolved.employee,\n employee_key: employeeKey(resolved.employee),\n bamboo_alias:\n clean(resolved.employee.full_name) ||\n clean(resolved.employee.displayName) ||\n '',\n matched_employee_number:\n resolved.employee_number,\n };\n }\n\n const holderName = clean(row.bank_account_holder);\n const fileName = clean(row.bank_name_file);\n\n // El nombre legal del cuentahabiente es la evidencia bancaria más fuerte.\n // Si identifica exactamente a una persona que pertenecía al período,\n // prevalece sobre un nombre abreviado que pueda coincidir con un perfil\n // histórico distinto (caso real: Suyapa Palma).\n const holderDecision = holderName\n ? precomputedDecision(holderName)\n : null;\n\n const holderMatchedBy =\n clean(holderDecision?.matched_by).toLowerCase();\n\n const holderIsExactUnique =\n holderDecision?.found === true &&\n (\n holderDecision.confidence >= 0.999 ||\n holderMatchedBy.includes('exact_precomputed_name') ||\n holderMatchedBy.includes('confirmed_alias_catalog')\n );\n\n // \"Banco sin Bamboo\" valida existencia en BambooHR, no que la persona\n // siguiera activa durante toda la quincena. Un finiquito/pago final puede\n // ocurrir después de la fecha de terminación. Por eso un nombre legal\n // completo y único del cuentahabiente es suficiente evidencia.\n if (holderIsExactUnique) {\n return {\n ...holderDecision,\n matched_by:\n `${holderDecision.matched_by || 'precomputed_name'}_holder_exact`,\n };\n }\n\n if (\n holderDecision?.found &&\n holderDecision.employee?.overlaps_period === true\n ) {\n return {\n ...holderDecision,\n matched_by:\n `${holderDecision.matched_by || 'precomputed_name'}_holder_in_period`,\n };\n }\n\n const names = Array.from(\n new Set(\n [\n holderName,\n fileName,\n ...linkedPayrollNames.map(clean),\n ].filter(Boolean)\n )\n );\n\n const decisions = names\n .map(precomputedDecision)\n .filter(Boolean);\n\n if (!decisions.length) {\n return {\n found: false,\n reason: 'no_confident_name_match',\n };\n }\n\n // Antes de declarar conflicto, descartar perfiles históricos que no\n // pertenecen al período cuando existe una única persona vigente/en período.\n const inPeriodByKey = new Map();\n\n for (const decision of decisions) {\n if (decision.employee?.overlaps_period !== true) continue;\n\n const current =\n inPeriodByKey.get(decision.employee_key);\n\n if (\n !current ||\n decision.confidence > current.confidence\n ) {\n inPeriodByKey.set(\n decision.employee_key,\n decision\n );\n }\n }\n\n const inPeriodRanked =\n Array.from(inPeriodByKey.values())\n .sort(\n (left, right) =>\n right.confidence - left.confidence\n );\n\n if (inPeriodRanked.length === 1) {\n return {\n ...inPeriodRanked[0],\n matched_by:\n `${inPeriodRanked[0].matched_by || 'precomputed_name'}_unique_in_period`,\n };\n }\n\n if (\n inPeriodRanked.length >= 2 &&\n (\n inPeriodRanked[0].confidence -\n inPeriodRanked[1].confidence\n ) >= 0.08\n ) {\n return inPeriodRanked[0];\n }\n\n const byKey = new Map();\n\n for (const decision of decisions) {\n const current =\n byKey.get(decision.employee_key);\n\n if (\n !current ||\n decision.confidence > current.confidence\n ) {\n byKey.set(\n decision.employee_key,\n decision\n );\n }\n }\n\n const ranked =\n Array.from(byKey.values())\n .sort(\n (left, right) =>\n right.confidence - left.confidence\n );\n\n if (ranked.length === 1) {\n return ranked[0];\n }\n\n if (\n (\n ranked[0].confidence -\n ranked[1].confidence\n ) >= 0.08\n ) {\n return ranked[0];\n }\n\n return {\n found: false,\n reason: 'conflicting_precomputed_name_matches',\n candidates: ranked.slice(0, 3),\n };\n}\n\nconst usedBankKeys = new Set();\nconst matchedPayrollIndexes = new Set();\nconst matchedPairs = [];\nconst bankIndexByKey = new Map();\n\n// Índice por centavos para que la pasada principal no compare cada fila de\n// nómina contra todas las transacciones del banco. Esto preserva exactamente\n// la lógica original: la primera pasada ya exigía el mismo monto al centavo.\nconst bankIndexesByAmountCents = new Map();\n\nfunction amountCents(value) {\n return Math.round(roundMoney(value) * 100);\n}\n\nbankRows.forEach((row, index) => {\n const key = bankRowKey(row, index);\n bankIndexByKey.set(key, index);\n\n const amountKey = `${clean(row.currency || 'USD').toUpperCase()}|${amountCents(row.amount)}`;\n const bucket = bankIndexesByAmountCents.get(amountKey) || [];\n bucket.push(index);\n bankIndexesByAmountCents.set(amountKey, bucket);\n});\n\nfunction availableNameCandidates(payroll, requireExactAmount) {\n const candidates = [];\n\n // La pasada exacta solo inspecciona filas con el mismo importe. La segunda\n // pasada conserva el barrido completo y el mismo criterio de persona fuerte\n // + menor diferencia que tenía el workflow validado.\n let candidateIndexes = null;\n\n if (requireExactAmount) {\n const currency =\n clean(payroll.currency || 'USD')\n .toUpperCase();\n\n const center =\n amountCents(payroll.payroll_amount);\n\n const indexSet = new Set();\n\n for (\n let delta = -MONEY_TOLERANCE_CENTS;\n delta <= MONEY_TOLERANCE_CENTS;\n delta++\n ) {\n const bucket =\n bankIndexesByAmountCents.get(\n `${currency}|${center + delta}`\n ) || [];\n\n for (const bankIndex of bucket) {\n indexSet.add(bankIndex);\n }\n }\n\n candidateIndexes =\n Array.from(indexSet);\n }\n\n const inspectBank = (bankIndex) => {\n const bank = bankRows[bankIndex];\n if (!bank) return;\n\n const key = bankRowKey(bank, bankIndex);\n if (usedBankKeys.has(key)) return;\n if (clean(payroll.currency || 'USD').toUpperCase() !== clean(bank.currency || 'HNL').toUpperCase()) return;\n\n if (requireExactAmount && !sameCent(payroll.payroll_amount, bank.amount)) return;\n\n const periodScore = bankCandidatePeriodScore(payroll, bank);\n if (periodScore < 0) return;\n\n const score = bestNameScore(payroll.employee_name, bank);\n if (score <= 0) return;\n\n candidates.push({\n bank,\n bankIndex,\n key,\n score,\n periodScore,\n amountDiff: Math.abs(moneyDiff(payroll.payroll_amount, bank.amount)),\n });\n };\n\n if (candidateIndexes) {\n for (const bankIndex of candidateIndexes) {\n inspectBank(bankIndex);\n }\n } else {\n for (let bankIndex = 0; bankIndex < bankRows.length; bankIndex++) {\n inspectBank(bankIndex);\n }\n }\n\n candidates.sort((a, b) => {\n if (b.periodScore !== a.periodScore) return b.periodScore - a.periodScore;\n if (b.score !== a.score) return b.score - a.score;\n if (a.amountDiff !== b.amountDiff) return a.amountDiff - b.amountDiff;\n return a.bankIndex - b.bankIndex;\n });\n\n return candidates;\n}\n\n// Primera pasada: persona + monto exacto. Es la evidencia más fuerte y evita\n// que extraordinarias/vacaciones de una misma persona se mezclen entre sí.\npayrollRows.forEach((payroll, payrollIndex) => {\n const candidates = availableNameCandidates(payroll, true);\n if (!candidates.length) return;\n const chosen = candidates[0];\n usedBankKeys.add(chosen.key);\n matchedPayrollIndexes.add(payrollIndex);\n matchedPairs.push({ payroll, payrollIndex, ...chosen });\n});\n\n// Segunda pasada: persona fuerte aunque el monto sea distinto. Solo se toma\n// una contraparte bancaria por fila de nómina y se prioriza la menor diferencia.\npayrollRows.forEach((payroll, payrollIndex) => {\n if (matchedPayrollIndexes.has(payrollIndex)) return;\n const candidates = availableNameCandidates(payroll, false);\n if (!candidates.length) return;\n const chosen = candidates[0];\n usedBankKeys.add(chosen.key);\n matchedPayrollIndexes.add(payrollIndex);\n matchedPairs.push({ payroll, payrollIndex, ...chosen });\n});\n\nconst linkedPayrollNamesByBankKey = new Map();\nconst linkedPayrollEmployeeNumbersByBankKey = new Map();\n\nfor (const pair of matchedPairs) {\n const currentNames =\n linkedPayrollNamesByBankKey.get(pair.key) || [];\n\n currentNames.push(pair.payroll.employee_name);\n\n linkedPayrollNamesByBankKey.set(\n pair.key,\n currentNames\n );\n\n const employeeNumber =\n normalizeEmployeeNumber(\n pair.payroll.employee_number ||\n pair.payroll.employeeNumber ||\n ''\n );\n\n if (employeeNumber) {\n const currentNumbers =\n linkedPayrollEmployeeNumbersByBankKey.get(\n pair.key\n ) || [];\n\n currentNumbers.push(employeeNumber);\n\n linkedPayrollEmployeeNumbersByBankKey.set(\n pair.key,\n currentNumbers\n );\n }\n}\n\n// Filas bancarias del período de Puerto Rico.\n// Toda fila emparejada entra siempre. Para una fila no emparejada se usa la\n// fecha/concepto del plano para evitar arrastrar accidentalmente otra quincena.\nconst includedBankRows = [];\nconst excludedBankRows = [];\n\nfor (let index = 0; index < bankRows.length; index++) {\n const row = bankRows[index];\n const key = bankRowKey(row, index);\n\n if (usedBankKeys.has(key)) {\n includedBankRows.push({ row, key, index, inclusion: 'matched_payroll' });\n continue;\n }\n\n const periodInfo = periodInfoForBankRow(row);\n if (periodInfo.known && !periodInfo.inPeriod) {\n excludedBankRows.push({ row, key, reason: 'outside_selected_payroll_period' });\n continue;\n }\n\n includedBankRows.push({ row, key, index, inclusion: 'unmatched_current_period' });\n}\n\nconst includedBankKeySet = new Set(includedBankRows.map((entry) => entry.key));\n\nconst coreRows = [];\nconst wrongAccountGroups = new Map();\nfor (const pair of matchedPairs) {\n if (!includedBankKeySet.has(pair.key)) continue;\n const payrollAmount = roundMoney(pair.payroll.payroll_amount);\n const bankAmount = roundMoney(pair.bank.amount);\n const difference = moneyDiff(payrollAmount, bankAmount);\n const currency = clean(pair.payroll.currency || pair.bank.currency || 'USD').toUpperCase() === 'USD' ? 'USD' : 'HNL';\n const payrollAccount = normalizeAccount(pair.payroll.account || pair.payroll.payroll_account);\n const bankAccount = normalizeAccount(pair.bank.account);\n const accountMismatch = Boolean(payrollAccount && bankAccount && payrollAccount !== bankAccount);\n if (accountMismatch) {\n const groupKey = `${normalizeName(pair.payroll.employee_name)}|${currency}|${payrollAccount}|${bankAccount}`;\n const current = wrongAccountGroups.get(groupKey) || {\n id: `pr_wrong_account_${wrongAccountGroups.size + 1}`,\n employee: pair.payroll.employee_name,\n employee_name: pair.payroll.employee_name,\n employeeNumber: pair.payroll.employee_number || '', employee_number: pair.payroll.employee_number || '',\n account: bankAccount, payrollAccount, payroll_account: payrollAccount, bankAccount, bank_account: bankAccount,\n currency, payrollAmount:0, payroll_amount:0, bankAmount:0, bank_amount:0, difference:0,\n status:'Pendiente revisión', category:'posible_cuenta_mal_digitada', subcategory:'nombre_y_monto_coinciden_cuenta_diferente',\n observation:`El nombre y el monto coinciden, pero la cuenta de nómina (${payrollAccount}) es diferente a la cuenta del banco (${bankAccount}).`,\n source_rows:[], source_sheets:new Set(), source_files:new Set(), shipment_numbers:new Set(), plan_numbers:new Set(),\n bank_name_file: pair.bank.bank_name_file || '', bank_account_holder: pair.bank.bank_account_holder || ''\n };\n current.payrollAmount=roundMoney(current.payrollAmount+payrollAmount); current.payroll_amount=current.payrollAmount;\n current.bankAmount=roundMoney(current.bankAmount+bankAmount); current.bank_amount=current.bankAmount; current.difference=moneyDiff(current.payrollAmount,current.bankAmount);\n current.source_rows.push(pair.payroll); if(pair.payroll.source_sheet)current.source_sheets.add(pair.payroll.source_sheet); if(pair.bank.source_file)current.source_files.add(pair.bank.source_file); if(pair.bank.shipment_number)current.shipment_numbers.add(pair.bank.shipment_number); if(pair.bank.plan_number)current.plan_numbers.add(pair.bank.plan_number);\n wrongAccountGroups.set(groupKey,current); continue;\n }\n const exact = sameCent(payrollAmount, bankAmount);\n coreRows.push({id:`pr_match_${pair.payrollIndex+1}_${pair.bankIndex+1}`,employee:pair.payroll.employee_name,employee_name:pair.payroll.employee_name,employeeNumber:pair.payroll.employee_number||'',employee_number:pair.payroll.employee_number||'',account:bankAccount||payrollAccount,payrollAccount:payrollAccount,payroll_account:payrollAccount,bankAccount:bankAccount,bank_account:bankAccount,currency,payrollAmount,payroll_amount:payrollAmount,bankAmount,bank_amount:bankAmount,difference,status:exact?'Coincide':'Pendiente revisión',category:exact?'coincidencia':'discrepancia',subcategory:exact?'persona_cuenta_y_monto_exactos':'persona_y_cuenta_coinciden_monto_diferente',observation:exact?'Coincidencia de persona, cuenta y monto.':difference>0?'Se pagó de menos.':'Se pagó de más.',source_kind:pair.payroll.source_kind||'',source_sheet:pair.payroll.source_sheet||'',source_file:pair.bank.source_file||'',shipment_number:pair.bank.shipment_number||'',plan_number:pair.bank.plan_number||'',plan_label:pair.bank.plan_label||'',reference:pair.bank.reference||'',bank_name_file:pair.bank.bank_name_file||'',bank_account_holder:pair.bank.bank_account_holder||''});\n}\nfor (let payrollIndex=0; payrollIndex({...row,source_sheets:Array.from(row.source_sheets),source_files:Array.from(row.source_files),shipment_numbers:Array.from(row.shipment_numbers),plan_numbers:Array.from(row.plan_numbers),source_sheet:Array.from(row.source_sheets).join(' / '),source_file:Array.from(row.source_files).join(' / '),shipment_number:Array.from(row.shipment_numbers).join(' / '),plan_number:Array.from(row.plan_numbers).join(' / ')}));\ncoreRows.push(...wrongAccountRows);\n\n// Banco sin Nómina se conserva a nivel de TRANSACCIÓN.\n// Una misma persona/cuenta puede tener más de un pago bancario legítimamente\n// separado; agruparlos reduce artificialmente el número de hallazgos.\nconst bankWithoutPayrollRows = [];\n\nfor (const entry of includedBankRows) {\n if (usedBankKeys.has(entry.key)) continue;\n\n const row = entry.row;\n const displayName =\n bankDisplayName(row);\n\n const rowCurrency =\n clean(row.currency || 'USD')\n .toUpperCase() === 'USD'\n ? 'USD'\n : 'HNL';\n\n const bankAmount =\n roundMoney(row.amount || 0);\n\n bankWithoutPayrollRows.push({\n id:\n `pr_bank_without_payroll_${entry.index + 1}`,\n employee: displayName,\n employee_name: displayName,\n employeeNumber: '',\n employee_number: '',\n account: row.account || '',\n payrollAccount: '',\n payroll_account: '',\n bankAccount: row.account || '',\n bank_account: row.account || '',\n currency: rowCurrency,\n payrollAmount: 0,\n payroll_amount: 0,\n bankAmount,\n bank_amount: bankAmount,\n difference:\n roundMoney(0 - bankAmount),\n status: 'Pendiente revisión',\n category: 'banco_sin_nomina',\n subcategory:\n 'pago_banco_sin_registro_nomina',\n observation:\n 'Pago bancario sin registro equivalente en las planillas cargadas.',\n bank_name_file:\n row.bank_name_file || '',\n bank_account_holder:\n row.bank_account_holder || '',\n source_file:\n row.source_file || '',\n shipment_number:\n row.shipment_number || '',\n plan_number:\n row.plan_number || '',\n reference:\n row.reference || '',\n row_number:\n row.row_number || null,\n source_rows: [row],\n });\n}\n\ncoreRows.push(...bankWithoutPayrollRows);\n\nconst nameDifferenceRows = [];\nfor (const entry of includedBankRows) {\n const row = entry.row;\n const rowCurrency=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';\n if (!clean(row.bank_name_file) || !clean(row.bank_account_holder)) continue;\n if (bankNameLooksConsistent(row.bank_name_file, row.bank_account_holder)) continue;\n nameDifferenceRows.push({\n id: `pr_bank_name_difference_${entry.index + 1}`,\n employee: row.bank_name_file,\n employee_name: row.bank_name_file,\n employeeNumber: '',\n employee_number: '',\n account: row.account || '',\n payrollAccount: '',\n payroll_account: '',\n bankAccount: row.account || '',\n bank_account: row.account || '',\n currency: rowCurrency,\n payrollAmount: 0,\n payroll_amount: 0,\n bankAmount: roundMoney(row.amount),\n bank_amount: roundMoney(row.amount),\n difference: 0,\n status: 'Pendiente revisión',\n category: 'diferencia_nombre_banco',\n subcategory: 'nombre_archivo_vs_cuentahabiente',\n observation: `El Nombre en Archivo (${row.bank_name_file}) no coincide con el Nombre del Cuentahabiente (${row.bank_account_holder}).`,\n bank_name_file: row.bank_name_file,\n bank_account_holder: row.bank_account_holder,\n source_file: row.source_file || '',\n shipment_number: row.shipment_number || '',\n plan_number: row.plan_number || '',\n reference: row.reference || '',\n row_number: row.row_number || null,\n });\n}\n\nconst bankWithoutBambooMap = new Map();\nconst bambooMatchDetails = [];\nfor (const entry of includedBankRows) {\n const row = entry.row;\n const linkedNames =\n linkedPayrollNamesByBankKey.get(entry.key) || [];\n\n const linkedEmployeeNumbers =\n linkedPayrollEmployeeNumbersByBankKey.get(\n entry.key\n ) || [];\n\n const decision = resolveBamboo(\n row,\n linkedNames,\n linkedEmployeeNumbers\n );\n bambooMatchDetails.push({\n bank_row_key: entry.key,\n bank_name_file: row.bank_name_file || '',\n bank_account_holder: row.bank_account_holder || '',\n account: row.account || '',\n amount: row.amount || 0,\n linked_payroll_names: linkedNames,\n ...decision,\n });\n if (decision.found) continue;\n\n const displayName = bankDisplayName(row);\n const rowCurrency=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';\n const groupingKey = `${normalizeAccount(row.account)}|${normalizeName(displayName)}|${rowCurrency}`;\n const current = bankWithoutBambooMap.get(groupingKey) || {\n id: `pr_bank_without_bamboo_${bankWithoutBambooMap.size + 1}`,\n bank_name_file: row.bank_name_file || displayName,\n bank_account_holder: row.bank_account_holder || '',\n employee_name: row.bank_name_file || displayName,\n account: row.account || '',\n currency: rowCurrency,\n bank_amount: 0,\n amount: 0,\n status: 'Pendiente revisión',\n category: 'banco_sin_bamboo',\n shipment_numbers: new Set(),\n references: new Set(),\n source_files: new Set(),\n source_rows: [],\n };\n current.bank_amount = roundMoney(current.bank_amount + Number(row.amount || 0));\n current.amount = current.bank_amount;\n if (row.shipment_number) current.shipment_numbers.add(row.shipment_number);\n if (row.reference) current.references.add(row.reference);\n if (row.source_file) current.source_files.add(row.source_file);\n current.source_rows.push(row);\n bankWithoutBambooMap.set(groupingKey, current);\n}\n\nconst bankWithoutBamboo = Array.from(bankWithoutBambooMap.values()).map((row) => ({\n ...row,\n shipment_numbers: Array.from(row.shipment_numbers),\n shipment_number: Array.from(row.shipment_numbers).join(' / '),\n references: Array.from(row.references),\n source_files: Array.from(row.source_files),\n source_file: Array.from(row.source_files).join(' / '),\n difference: roundMoney(0 - row.bank_amount),\n}));\n\nfunction priority(row) {\n const category = clean(row.category).toLowerCase();\n if (category === 'posible_cuenta_mal_digitada') return 1;\n if (category === 'discrepancia') return 2;\n if (category === 'banco_sin_nomina') return 3;\n if (category === 'diferencia_nombre_banco') return 5;\n if (category === 'coincidencia') return 99;\n return 50;\n}\n\nconst rowsFinales = [...coreRows, ...nameDifferenceRows].sort((a, b) => {\n const p = priority(a) - priority(b);\n if (p !== 0) return p;\n return clean(a.employee_name).localeCompare(clean(b.employee_name), 'es');\n});\n\nconst coincidencias = coreRows.filter((row) => row.category === 'coincidencia').length;\nconst discrepancias = coreRows.filter((row) => row.category === 'discrepancia').length;\nconst bancoSinNomina = bankWithoutPayrollRows.length;\nconst diferenciasNombreBanco = nameDifferenceRows.length;\nconst posiblesCuentasMalDigitadas = wrongAccountRows.length;\nconst pendientes = discrepancias + bancoSinNomina + diferenciasNombreBanco;\nconst totalNominaByCurrency = {HNL:0,USD:0};\nfor(const row of payrollRows){const c=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';totalNominaByCurrency[c]=roundMoney(totalNominaByCurrency[c]+Number(row.payroll_amount||0));}\nconst totalBancoByCurrency = {HNL:0,USD:0};\nfor(const entry of includedBankRows){const c=clean(entry.row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';totalBancoByCurrency[c]=roundMoney(totalBancoByCurrency[c]+Number(entry.row.amount||0));}\nconst diferenciaByCurrency={HNL:moneyDiff(totalNominaByCurrency.HNL,totalBancoByCurrency.HNL),USD:moneyDiff(totalNominaByCurrency.USD,totalBancoByCurrency.USD)};\nconst totalNomina=totalNominaByCurrency.HNL || totalNominaByCurrency.USD;\nconst totalBanco=totalBancoByCurrency.HNL || totalBancoByCurrency.USD;\nconst diferenciaTotal=totalNominaByCurrency.HNL||totalBancoByCurrency.HNL?diferenciaByCurrency.HNL:diferenciaByCurrency.USD;\n\nconst bambooSummaryCompact = { ...(data.bamboo || {}) };\ndelete bambooSummaryCompact.employees;\n\nreturn [{\n json: {\n ok: true,\n stage: 'cruce_nomina_banco_puerto_rico',\n errors: [],\n metadata: data.metadata || {},\n summary: {\n coincidencias,\n discrepancias,\n bancoSinNomina,\n bancoSinBamboo: bankWithoutBamboo.length,\n nominaSinCuenta: 0,\n diferenciasNombreBanco,\n posiblesCuentasMalDigitadas,\n pendientes,\n filasNominaValidas: Number(data.payroll?.base_rows_count || data.payroll?.valid_rows_count || 0),\n filasNominaSinCuenta: 0,\n suplementosPotenciales: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaAplicados: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaNoAplicados: 0,\n suplementosNominaAdjuntados: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaNoAdjuntados: Number(data.payroll?.unattached_supplements_count || 0),\n reconciliacionesExactasFinales: coincidencias,\n cuentasNominaAgrupadas: 0,\n transaccionesBanco: includedBankRows.length,\n cuentasBancoAgrupadas: new Set(includedBankRows.map((entry) => normalizeAccount(entry.row.account)).filter(Boolean)).size,\n empleadosBambooPR: Number(data.bamboo?.puerto_rico_count || 0),\n empleadosBambooEnPeriodo: Number(data.bamboo?.active_in_period_count || 0),\n bambooPaginasDescargadas: Number(data.bamboo?.pages_fetched || 0),\n bambooEmpleadosEsperados: Number(data.bamboo?.expected_total || 0),\n bambooDescargaCompleta: Boolean(data.bamboo?.fetch_complete),\n bambooValidacionDisponible: bambooValidationAvailable,\n totalNominaBase: roundMoney(data.payroll?.base_total || 0),\n totalSuplementosAplicados: roundMoney(data.payroll?.supplements_total || 0),\n totalNomina,\n totalBanco,\n diferenciaTotal,\n totalNominaPorMoneda: totalNominaByCurrency,\n totalBancoPorMoneda: totalBancoByCurrency,\n diferenciaTotalPorMoneda: diferenciaByCurrency,\n },\n rows: rowsFinales,\n bankWithoutBamboo,\n nameDifferences: nameDifferenceRows,\n bambooSummary: bambooSummaryCompact,\n reportUrl: null,\n debug: {\n matched_pairs_count: matchedPairs.length,\n included_bank_rows_count: includedBankRows.length,\n excluded_bank_rows_count: excludedBankRows.length,\n excluded_bank_rows_preview: excludedBankRows.slice(0, 100),\n validated_bamboo_aliases_loaded: validatedBambooAliases.length,\n bamboo_matches: bambooMatchDetails,\n bamboo_validation_available: bambooValidationAvailable,\n banco_sin_bamboo: bankWithoutBamboo,\n payroll_preview: payrollRows.slice(0, 20),\n bank_included_preview: includedBankRows.slice(0, 20).map((entry) => entry.row),\n },\n },\n}];\n" + "jsCode": "const data = $('Merge - Agregar BambooHR PR').first().json || {};\nconst aliasResponse = $input.first().json || {};\nconst validatedBambooAliases = Array.isArray(aliasResponse.aliases)\n ? aliasResponse.aliases\n : Array.isArray(aliasResponse)\n ? aliasResponse\n : [];\n\nfunction clean(value) {\n return String(value ?? '')\n .replace(/\\uFEFF/g, '')\n .replace(/\\u00A0/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst normalizedNameCache = new Map();\nconst nameWordsCache = new Map();\nconst nameMatchScoreCache = new Map();\n\nfunction normalizeName(value) {\n const raw = clean(value);\n if (normalizedNameCache.has(raw)) {\n return normalizedNameCache.get(raw);\n }\n\n const normalized = raw\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/['’`-]/g, ' ')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n\n normalizedNameCache.set(raw, normalized);\n return normalized;\n}\n\nfunction normalizeAccount(value) {\n return String(value ?? '').replace(/\\.0$/g, '').replace(/\\D/g, '').trim();\n}\n\nfunction normalizeEmployeeNumber(value) {\n return String(value ?? '')\n .replace(/\\u00A0/g, '')\n .replace(/\\D/g, '')\n .trim();\n}\n\nfunction roundMoney(value) {\n return Math.round((Number(value) || 0) * 100) / 100;\n}\n\nfunction moneyDiff(payroll, bank) {\n return roundMoney((Number(payroll) || 0) - (Number(bank) || 0));\n}\n\nconst MONEY_TOLERANCE = 0.01;\nconst MONEY_TOLERANCE_CENTS = Math.round(MONEY_TOLERANCE * 100);\n\nfunction sameCent(a, b) {\n return Math.abs(moneyDiff(a, b)) <= MONEY_TOLERANCE + 1e-9;\n}\n\nconst IGNORED_NAME_TOKENS = new Set([\n 'de', 'del', 'la', 'las', 'los', 'y', 'e', 'el',\n 'da', 'do', 'dos', 'das', 'van', 'von',\n]);\n\nfunction nameWords(value) {\n const normalized = normalizeName(value);\n if (nameWordsCache.has(normalized)) {\n return nameWordsCache.get(normalized);\n }\n\n const words = normalized\n .split(' ')\n .filter((word) => word.length > 1 && !IGNORED_NAME_TOKENS.has(word));\n\n nameWordsCache.set(normalized, words);\n return words;\n}\n\nfunction editDistance(a, b) {\n if (a === b) return 0;\n if (!a) return b.length;\n if (!b) return a.length;\n let previous = Array.from({ length: b.length + 1 }, (_, index) => index);\n for (let i = 1; i <= a.length; i++) {\n const current = [i];\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n current[j] = Math.min(current[j - 1] + 1, previous[j] + 1, previous[j - 1] + cost);\n }\n previous = current;\n }\n return previous[b.length];\n}\n\nfunction tokenMatches(a, b) {\n if (a === b) return true;\n const minLength = Math.min(a.length, b.length);\n if (minLength >= 8 && editDistance(a, b) <= 2) return true;\n if (minLength >= 5 && editDistance(a, b) <= 1) return true;\n return false;\n}\n\nfunction samePersonName(a, b) {\n const normalizedA = normalizeName(a);\n const normalizedB = normalizeName(b);\n if (!normalizedA || !normalizedB) return false;\n if (normalizedA === normalizedB) return true;\n\n const wordsA = nameWords(a);\n const wordsB = nameWords(b);\n if (!wordsA.length || !wordsB.length) return false;\n\n const usedB = new Set();\n let matches = 0;\n for (const wordA of wordsA) {\n const matchIndex = wordsB.findIndex((wordB, index) =>\n !usedB.has(index) && tokenMatches(wordA, wordB)\n );\n if (matchIndex >= 0) {\n usedB.add(matchIndex);\n matches += 1;\n }\n }\n\n const smallerLength = Math.min(wordsA.length, wordsB.length);\n const ratio = matches / smallerLength;\n if (smallerLength <= 2) return matches === smallerLength && matches >= 2;\n return matches >= 2 && ratio >= 0.6;\n}\n\nfunction bankNameLooksConsistent(fileName, holderName) {\n const fileWords = nameWords(fileName);\n const holderWords = nameWords(holderName);\n\n if (!fileWords.length || !holderWords.length) return true;\n\n const used = new Set();\n\n for (const fileWord of fileWords) {\n let matchIndex = holderWords.findIndex(\n (holderWord, index) =>\n !used.has(index) &&\n holderWord === fileWord\n );\n\n // Algunos planos de Puerto Rico recortan el último carácter del apellido\n // por longitud de campo (ej.: ALVARAD -> ALVARADO). Eso no debe\n // convertirse en una diferencia de nombre. No se aceptan sustituciones\n // ortográficas (ej.: GONZALES -> GONZALEZ), porque sí requieren revisión.\n if (matchIndex < 0) {\n matchIndex = holderWords.findIndex(\n (holderWord, index) =>\n !used.has(index) &&\n holderWord.startsWith(fileWord) &&\n (\n (fileWord.length <= 3) ||\n (\n fileWord.length >= 4 &&\n holderWord.length === fileWord.length + 1\n )\n )\n );\n }\n\n if (matchIndex < 0) return false;\n used.add(matchIndex);\n }\n\n return true;\n}\n\nfunction nameMatchScore(a, b) {\n const na = normalizeName(a);\n const nb = normalizeName(b);\n if (!na || !nb) return 0;\n\n const cacheKey = na <= nb ? `${na}\\u0000${nb}` : `${nb}\\u0000${na}`;\n if (nameMatchScoreCache.has(cacheKey)) {\n return nameMatchScoreCache.get(cacheKey);\n }\n\n if (na === nb) {\n nameMatchScoreCache.set(cacheKey, 1);\n return 1;\n }\n\n const wa = nameWords(a);\n const wb = nameWords(b);\n if (!samePersonName(a, b)) {\n nameMatchScoreCache.set(cacheKey, 0);\n return 0;\n }\n\n const setA = new Set(wa);\n const setB = new Set(wb);\n let exact = 0;\n for (const w of setA) if (setB.has(w)) exact += 1;\n const min = Math.max(1, Math.min(setA.size, setB.size));\n const score = Math.min(\n 0.99,\n 0.75 + (exact / min) * 0.20 + (wa.length === wb.length ? 0.04 : 0)\n );\n\n nameMatchScoreCache.set(cacheKey, score);\n return score;\n}\n\nfunction bankNames(row) {\n return [row.bank_name_file, row.bank_account_holder]\n .map(clean)\n .filter(Boolean);\n}\n\nfunction bestNameScore(payrollName, bankRow) {\n return Math.max(0, ...bankNames(bankRow).map((name) => nameMatchScore(payrollName, name)));\n}\n\nfunction bankDisplayName(row) {\n return clean(row.bank_name_file) || clean(row.bank_account_holder) || 'Pago bancario';\n}\n\nfunction bankRowKey(row, index) {\n return clean(row.bank_row_key) || `${clean(row.source_file)}|${row.row_number || index + 1}`;\n}\n\n\nconst metadata = data.metadata || {};\n\nfunction parseBankDate(value, sourceFile = '') {\n const raw = clean(value);\n let match = raw.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})/);\n if (match) {\n return {\n year: Number(match[3]),\n month: Number(match[2]),\n day: Number(match[1]),\n };\n }\n\n match = raw.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})/);\n if (match) {\n return {\n year: Number(match[1]),\n month: Number(match[2]),\n day: Number(match[3]),\n };\n }\n\n // Respaldo por el patrón habitual del nombre: _DDMMYY / _DDMMYYYY.\n const fileMatch = clean(sourceFile).match(/_(\\d{2})(\\d{2})(\\d{2}|\\d{4})(?:\\D|$)/);\n if (!fileMatch) return null;\n\n const yearPart = Number(fileMatch[3]);\n return {\n year: fileMatch[3].length === 2 ? 2000 + yearPart : yearPart,\n month: Number(fileMatch[2]),\n day: Number(fileMatch[1]),\n };\n}\n\nfunction selectedPeriodKind() {\n const type = clean(metadata.period_type).toLowerCase();\n if (type === 'quincena_15') return 'q15';\n if (type === 'quincena_30') return 'q30';\n return 'unknown';\n}\n\nfunction conceptPeriodHint(row) {\n const concept = normalizeName(row.concept || '');\n if (!concept) return 'unknown';\n\n if (\n /(?:^| )1(?:ra|er|era)? quincena(?: |$)/.test(concept) ||\n concept.includes('primera quincena') ||\n concept.includes('quincena 1ra') ||\n concept.includes('quincena 1')\n ) {\n return 'q15';\n }\n\n if (\n /(?:^| )2(?:da|do|nda)? quincena(?: |$)/.test(concept) ||\n concept.includes('segunda quincena') ||\n concept.includes('quincena 2da') ||\n concept.includes('quincena 2') ||\n concept.includes('fin de mes')\n ) {\n return 'q30';\n }\n\n return 'unknown';\n}\n\nfunction periodInfoForBankRow(row) {\n const selected = selectedPeriodKind();\n const rowDate = parseBankDate(row.application_date, row.source_file);\n const selectedYear = Number(metadata.year || 0);\n const selectedMonth = Number(metadata.month || 0);\n const hint = conceptPeriodHint(row);\n\n if (selected === 'unknown') {\n return { known: false, selected, inPeriod: true, affinity: 1, rowDate, hint };\n }\n\n if (hint !== 'unknown' && hint === selected) {\n return { known: true, selected, inPeriod: true, affinity: 4, rowDate, hint };\n }\n\n if (!rowDate || !selectedYear || !selectedMonth) {\n return { known: false, selected, inPeriod: true, affinity: 1, rowDate, hint };\n }\n\n if (rowDate.year !== selectedYear || rowDate.month !== selectedMonth) {\n return { known: true, selected, inPeriod: false, affinity: 0, rowDate, hint };\n }\n\n const inHalf = selected === 'q15'\n ? rowDate.day <= 15\n : rowDate.day >= 16;\n\n return {\n known: true,\n selected,\n inPeriod: inHalf,\n affinity: inHalf ? 3 : 0,\n rowDate,\n hint,\n };\n}\n\nfunction isSupplementPayroll(payroll) {\n return clean(payroll?.source_kind).toLowerCase() !== 'quincenal';\n}\n\nfunction bankCandidatePeriodScore(payroll, bank) {\n const info = periodInfoForBankRow(bank);\n if (!info.known || info.inPeriod) return info.affinity || 1;\n\n // Una extraordinaria/vacación/XIII Mes puede pagarse fuera de la mitad\n // estricta del mes. Se permite como respaldo, siempre detrás de cualquier\n // candidato del período seleccionado.\n if (isSupplementPayroll(payroll) && info.rowDate) {\n const selectedYear = Number(metadata.year || 0);\n const selectedMonth = Number(metadata.month || 0);\n if (info.rowDate.year === selectedYear && info.rowDate.month === selectedMonth) {\n return 0.5;\n }\n }\n\n return -1;\n}\n\nconst payrollRows = Array.isArray(data.payroll?.rows) ? data.payroll.rows : [];\nconst bankRows = Array.isArray(data.bank?.rows) ? data.bank.rows : [];\n\n// Guardia de seguridad: nunca generar un reporte \"válido\" cuando el request\n// traía archivos pero el parser no consiguió ninguna fila. Esto evita que\n// todas las personas de nómina aparezcan falsamente como discrepancias.\nif (payrollRows.length === 0) {\n throw new Error(\n 'Puerto Rico: no se pudo leer ninguna fila válida de nómina. ' +\n 'Revisa los archivo Excel de Puerto Rico y las hojas Whirlpool, Personal 2 y Personal 3.'\n );\n}\n\nif (bankRows.length === 0) {\n const detectedFiles = Number(data.bank?.files_count || data.summary?.bank_files_count || 0);\n const invalidFiles = Array.isArray(data.bank?.file_summaries)\n ? data.bank.file_summaries.filter((file) => file?.ok === false)\n : [];\n\n throw new Error(\n 'Puerto Rico: no se pudo leer ninguna transacción bancaria. ' +\n `Archivos bancarios detectados: ${detectedFiles}. ` +\n (invalidFiles.length\n ? `Archivos con error de formato: ${invalidFiles.map((file) => file.file_name).join(', ')}.`\n : 'Verifica que el PDF sea el Transaction Detail Report de Banco Popular de Puerto Rico.')\n );\n}\n\nconst bambooEmployees = Array.isArray(data.bamboo?.employees) ? data.bamboo.employees : [];\nconst resolvedNameMatches = data.bamboo?.resolved_name_matches || {};\nconst bambooValidationAvailable = data.bamboo?.fetch_complete === true &&\n data.bamboo?.validation_available === true && bambooEmployees.length > 0;\n\nconst bambooByEmployeeNumber = new Map();\nconst bambooById = new Map();\nconst bambooByExactName = new Map();\nfor (const employee of bambooEmployees) {\n const number = normalizeEmployeeNumber(\n employee.employee_number || employee.employeeNumber\n );\n const id = clean(employee.bamboo_id || employee.id);\n if (number) {\n const arr = bambooByEmployeeNumber.get(number) || [];\n arr.push(employee);\n bambooByEmployeeNumber.set(number, arr);\n }\n if (id) bambooById.set(id, employee);\n for (const alias of employee.aliases || [employee.full_name]) {\n const normalized = normalizeName(alias);\n if (!normalized) continue;\n const arr = bambooByExactName.get(normalized) || [];\n arr.push(employee);\n bambooByExactName.set(normalized, arr);\n }\n}\n\nfunction employeeKey(employee) {\n return clean(employee?.bamboo_id || employee?.id) ||\n clean(employee?.employee_number || employee?.employeeNumber) ||\n normalizeName(employee?.full_name || employee?.displayName);\n}\n\nfunction validatedAliasDecision(row) {\n if (!validatedBambooAliases.length) return null;\n const rowAccount = normalizeAccount(row.account);\n const names = bankNames(row).map(normalizeName).filter(Boolean);\n const candidates = validatedBambooAliases.filter((alias) => {\n const country = clean(alias.pais || alias.country).toUpperCase();\n if (country && country !== 'PR') return false;\n const source = normalizeName(alias.nombre_origen || alias.source_name || alias.alias || '');\n if (!source || !names.includes(source)) return false;\n const aliasAccount = normalizeAccount(alias.cuenta_bancaria || alias.cuenta_banco || alias.bank_account || '');\n return !aliasAccount || !rowAccount || aliasAccount === rowAccount;\n });\n if (candidates.length !== 1) return null;\n const alias = candidates[0];\n let employee = null;\n const employeeNumber = normalizeEmployeeNumber(\n alias.bamboo_employee_number || ''\n );\n const bambooId = clean(alias.bamboo_employee_id || '');\n const bambooName = normalizeName(alias.bamboo_nombre || '');\n if (employeeNumber && (bambooByEmployeeNumber.get(employeeNumber) || []).length === 1) {\n employee = bambooByEmployeeNumber.get(employeeNumber)[0];\n } else if (bambooId && bambooById.has(bambooId)) {\n employee = bambooById.get(bambooId);\n } else if (bambooName && (bambooByExactName.get(bambooName) || []).length === 1) {\n employee = bambooByExactName.get(bambooName)[0];\n }\n if (!employee) return null;\n return {\n found: true,\n matched_by: 'validated_bamboo_alias',\n confidence: 1,\n employee,\n employee_key: employeeKey(employee),\n bamboo_alias: clean(alias.bamboo_nombre) || employee.full_name || '',\n };\n}\n\nfunction precomputedDecision(name) {\n const normalized = normalizeName(name);\n if (!normalized) return null;\n const decision = resolvedNameMatches[normalized];\n if (!decision || decision.found !== true) return null;\n const index = Number(decision.employee_index);\n const employee = Number.isInteger(index) && index >= 0 ? bambooEmployees[index] : null;\n const key = clean(decision.employee_key) || employeeKey(employee);\n if (!key) return null;\n return {\n found: true,\n matched_by: decision.matched_by || 'precomputed_name',\n confidence: Number(decision.confidence || 0),\n employee,\n employee_key: key,\n bamboo_alias: clean(decision.bamboo_alias) || employee?.full_name || '',\n query_name: clean(name),\n };\n}\n\nfunction resolveBamboo(\n row,\n linkedPayrollNames = [],\n linkedPayrollEmployeeNumbers = []\n) {\n if (!bambooValidationAvailable) {\n return {\n found: false,\n reason: 'validation_unavailable',\n };\n }\n\n const validated = validatedAliasDecision(row);\n if (validated) return validated;\n\n /*\n * Puerto Rico: si existe un identificador fuerte procedente de nómina se puede usar como respaldo para determinar\n * si el pago pertenece a una persona existente en BambooHR.\n *\n * Se normalizan guiones/espacios tanto en banco como en BambooHR:\n * 0611198400414 <-> 0611-1984-00414\n *\n * Como respaldo, cuando la fila bancaria ya fue conciliada con nómina,\n * también se usa el Employee Number/Identidad de esa fila de nómina.\n * Solo se acepta el identificador cuando apunta a UNA sola persona.\n */\n const referenceEmployeeNumbers = Array.from(\n new Set(\n [\n row.reference,\n row.participant_id,\n row.employee_number,\n row.employeeNumber,\n ...linkedPayrollEmployeeNumbers,\n ]\n .flatMap((value) =>\n String(value ?? '').match(/\\d{6,20}/g) || []\n )\n .map(normalizeEmployeeNumber)\n .filter((value) => value.length >= 6)\n )\n );\n\n const employeesByStrongIdentifier = new Map();\n\n for (const employeeNumber of referenceEmployeeNumbers) {\n const matches =\n bambooByEmployeeNumber.get(employeeNumber) || [];\n\n if (matches.length !== 1) continue;\n\n const employee = matches[0];\n const key = employeeKey(employee);\n\n if (key) {\n employeesByStrongIdentifier.set(\n key,\n {\n employee,\n employee_number: employeeNumber,\n }\n );\n }\n }\n\n if (employeesByStrongIdentifier.size === 1) {\n const resolved =\n employeesByStrongIdentifier.values().next().value;\n\n return {\n found: true,\n matched_by: 'bank_or_payroll_employee_number',\n confidence: 1,\n employee: resolved.employee,\n employee_key: employeeKey(resolved.employee),\n bamboo_alias:\n clean(resolved.employee.full_name) ||\n clean(resolved.employee.displayName) ||\n '',\n matched_employee_number:\n resolved.employee_number,\n };\n }\n\n const holderName = clean(row.bank_account_holder);\n const fileName = clean(row.bank_name_file);\n\n // El nombre legal del cuentahabiente es la evidencia bancaria más fuerte.\n // Si identifica exactamente a una persona que pertenecía al período,\n // prevalece sobre un nombre abreviado que pueda coincidir con un perfil\n // histórico distinto (caso real: Suyapa Palma).\n const holderDecision = holderName\n ? precomputedDecision(holderName)\n : null;\n\n const holderMatchedBy =\n clean(holderDecision?.matched_by).toLowerCase();\n\n const holderIsExactUnique =\n holderDecision?.found === true &&\n (\n holderDecision.confidence >= 0.999 ||\n holderMatchedBy.includes('exact_precomputed_name') ||\n holderMatchedBy.includes('confirmed_alias_catalog')\n );\n\n // \"Banco sin Bamboo\" valida existencia en BambooHR, no que la persona\n // siguiera activa durante toda la quincena. Un finiquito/pago final puede\n // ocurrir después de la fecha de terminación. Por eso un nombre legal\n // completo y único del cuentahabiente es suficiente evidencia.\n if (holderIsExactUnique) {\n return {\n ...holderDecision,\n matched_by:\n `${holderDecision.matched_by || 'precomputed_name'}_holder_exact`,\n };\n }\n\n if (\n holderDecision?.found &&\n holderDecision.employee?.overlaps_period === true\n ) {\n return {\n ...holderDecision,\n matched_by:\n `${holderDecision.matched_by || 'precomputed_name'}_holder_in_period`,\n };\n }\n\n const names = Array.from(\n new Set(\n [\n holderName,\n fileName,\n ...linkedPayrollNames.map(clean),\n ].filter(Boolean)\n )\n );\n\n const decisions = names\n .map(precomputedDecision)\n .filter(Boolean);\n\n if (!decisions.length) {\n return {\n found: false,\n reason: 'no_confident_name_match',\n };\n }\n\n // Antes de declarar conflicto, descartar perfiles históricos que no\n // pertenecen al período cuando existe una única persona vigente/en período.\n const inPeriodByKey = new Map();\n\n for (const decision of decisions) {\n if (decision.employee?.overlaps_period !== true) continue;\n\n const current =\n inPeriodByKey.get(decision.employee_key);\n\n if (\n !current ||\n decision.confidence > current.confidence\n ) {\n inPeriodByKey.set(\n decision.employee_key,\n decision\n );\n }\n }\n\n const inPeriodRanked =\n Array.from(inPeriodByKey.values())\n .sort(\n (left, right) =>\n right.confidence - left.confidence\n );\n\n if (inPeriodRanked.length === 1) {\n return {\n ...inPeriodRanked[0],\n matched_by:\n `${inPeriodRanked[0].matched_by || 'precomputed_name'}_unique_in_period`,\n };\n }\n\n if (\n inPeriodRanked.length >= 2 &&\n (\n inPeriodRanked[0].confidence -\n inPeriodRanked[1].confidence\n ) >= 0.08\n ) {\n return inPeriodRanked[0];\n }\n\n const byKey = new Map();\n\n for (const decision of decisions) {\n const current =\n byKey.get(decision.employee_key);\n\n if (\n !current ||\n decision.confidence > current.confidence\n ) {\n byKey.set(\n decision.employee_key,\n decision\n );\n }\n }\n\n const ranked =\n Array.from(byKey.values())\n .sort(\n (left, right) =>\n right.confidence - left.confidence\n );\n\n if (ranked.length === 1) {\n return ranked[0];\n }\n\n if (\n (\n ranked[0].confidence -\n ranked[1].confidence\n ) >= 0.08\n ) {\n return ranked[0];\n }\n\n return {\n found: false,\n reason: 'conflicting_precomputed_name_matches',\n candidates: ranked.slice(0, 3),\n };\n}\n\nconst usedBankKeys = new Set();\nconst matchedPayrollIndexes = new Set();\nconst matchedPairs = [];\nconst bankIndexByKey = new Map();\n\n// Índice por centavos para que la pasada principal no compare cada fila de\n// nómina contra todas las transacciones del banco. Esto preserva exactamente\n// la lógica original: la primera pasada ya exigía el mismo monto al centavo.\nconst bankIndexesByAmountCents = new Map();\n\nfunction amountCents(value) {\n return Math.round(roundMoney(value) * 100);\n}\n\nbankRows.forEach((row, index) => {\n const key = bankRowKey(row, index);\n bankIndexByKey.set(key, index);\n\n const amountKey = `${clean(row.currency || 'USD').toUpperCase()}|${amountCents(row.amount)}`;\n const bucket = bankIndexesByAmountCents.get(amountKey) || [];\n bucket.push(index);\n bankIndexesByAmountCents.set(amountKey, bucket);\n});\n\nfunction availableNameCandidates(payroll, requireExactAmount) {\n const candidates = [];\n\n // La pasada exacta solo inspecciona filas con el mismo importe. La segunda\n // pasada conserva el barrido completo y el mismo criterio de persona fuerte\n // + menor diferencia que tenía el workflow validado.\n let candidateIndexes = null;\n\n if (requireExactAmount) {\n const currency =\n clean(payroll.currency || 'USD')\n .toUpperCase();\n\n const center =\n amountCents(payroll.payroll_amount);\n\n const indexSet = new Set();\n\n for (\n let delta = -MONEY_TOLERANCE_CENTS;\n delta <= MONEY_TOLERANCE_CENTS;\n delta++\n ) {\n const bucket =\n bankIndexesByAmountCents.get(\n `${currency}|${center + delta}`\n ) || [];\n\n for (const bankIndex of bucket) {\n indexSet.add(bankIndex);\n }\n }\n\n candidateIndexes =\n Array.from(indexSet);\n }\n\n const inspectBank = (bankIndex) => {\n const bank = bankRows[bankIndex];\n if (!bank) return;\n\n const key = bankRowKey(bank, bankIndex);\n if (usedBankKeys.has(key)) return;\n if (clean(payroll.currency || 'USD').toUpperCase() !== clean(bank.currency || 'HNL').toUpperCase()) return;\n\n if (requireExactAmount && !sameCent(payroll.payroll_amount, bank.amount)) return;\n\n const periodScore = bankCandidatePeriodScore(payroll, bank);\n if (periodScore < 0) return;\n\n const score = bestNameScore(payroll.employee_name, bank);\n if (score <= 0) return;\n\n candidates.push({\n bank,\n bankIndex,\n key,\n score,\n periodScore,\n amountDiff: Math.abs(moneyDiff(payroll.payroll_amount, bank.amount)),\n });\n };\n\n if (candidateIndexes) {\n for (const bankIndex of candidateIndexes) {\n inspectBank(bankIndex);\n }\n } else {\n for (let bankIndex = 0; bankIndex < bankRows.length; bankIndex++) {\n inspectBank(bankIndex);\n }\n }\n\n candidates.sort((a, b) => {\n if (b.periodScore !== a.periodScore) return b.periodScore - a.periodScore;\n if (b.score !== a.score) return b.score - a.score;\n if (a.amountDiff !== b.amountDiff) return a.amountDiff - b.amountDiff;\n return a.bankIndex - b.bankIndex;\n });\n\n return candidates;\n}\n\n// Primera pasada: persona + monto exacto. Es la evidencia más fuerte y evita\n// que extraordinarias/vacaciones de una misma persona se mezclen entre sí.\npayrollRows.forEach((payroll, payrollIndex) => {\n const candidates = availableNameCandidates(payroll, true);\n if (!candidates.length) return;\n const chosen = candidates[0];\n usedBankKeys.add(chosen.key);\n matchedPayrollIndexes.add(payrollIndex);\n matchedPairs.push({ payroll, payrollIndex, ...chosen });\n});\n\n// Segunda pasada: persona fuerte aunque el monto sea distinto. Solo se toma\n// una contraparte bancaria por fila de nómina y se prioriza la menor diferencia.\npayrollRows.forEach((payroll, payrollIndex) => {\n if (matchedPayrollIndexes.has(payrollIndex)) return;\n const candidates = availableNameCandidates(payroll, false);\n if (!candidates.length) return;\n const chosen = candidates[0];\n usedBankKeys.add(chosen.key);\n matchedPayrollIndexes.add(payrollIndex);\n matchedPairs.push({ payroll, payrollIndex, ...chosen });\n});\n\nconst linkedPayrollNamesByBankKey = new Map();\nconst linkedPayrollEmployeeNumbersByBankKey = new Map();\n\nfor (const pair of matchedPairs) {\n const currentNames =\n linkedPayrollNamesByBankKey.get(pair.key) || [];\n\n currentNames.push(pair.payroll.employee_name);\n\n linkedPayrollNamesByBankKey.set(\n pair.key,\n currentNames\n );\n\n const employeeNumber =\n normalizeEmployeeNumber(\n pair.payroll.employee_number ||\n pair.payroll.employeeNumber ||\n ''\n );\n\n if (employeeNumber) {\n const currentNumbers =\n linkedPayrollEmployeeNumbersByBankKey.get(\n pair.key\n ) || [];\n\n currentNumbers.push(employeeNumber);\n\n linkedPayrollEmployeeNumbersByBankKey.set(\n pair.key,\n currentNumbers\n );\n }\n}\n\n// Filas bancarias del período de Puerto Rico.\n// Toda fila emparejada entra siempre. Para una fila no emparejada se usa la\n// fecha/concepto del plano para evitar arrastrar accidentalmente otra quincena.\nconst includedBankRows = [];\nconst excludedBankRows = [];\n\nfor (let index = 0; index < bankRows.length; index++) {\n const row = bankRows[index];\n const key = bankRowKey(row, index);\n\n if (usedBankKeys.has(key)) {\n includedBankRows.push({ row, key, index, inclusion: 'matched_payroll' });\n continue;\n }\n\n const periodInfo = periodInfoForBankRow(row);\n if (periodInfo.known && !periodInfo.inPeriod) {\n excludedBankRows.push({ row, key, reason: 'outside_selected_payroll_period' });\n continue;\n }\n\n includedBankRows.push({ row, key, index, inclusion: 'unmatched_current_period' });\n}\n\nconst includedBankKeySet = new Set(includedBankRows.map((entry) => entry.key));\n\n/*\n * Employee Number para la interfaz.\n *\n * La nómina de Puerto Rico no trae Employee Number, pero en este punto ya\n * contamos con la resolución de identidad contra BambooHR. La versión\n * anterior mantenía employeeNumber vacío porque copiaba únicamente el valor\n * de nómina. Reutilizamos exactamente la misma resolución BambooHR que ya\n * valida Banco sin Bamboo para completar el Employee Number sin alterar la\n * lógica de conciliación, montos, cuentas ni categorías.\n */\nfunction bambooEmployeeNumberFromDecision(decision) {\n return clean(\n decision?.employee?.employee_number ||\n decision?.employee?.employeeNumber ||\n decision?.matched_employee_number ||\n ''\n );\n}\n\nfunction resolvedEmployeeNumberForPair(pair) {\n const payrollNumber = clean(\n pair?.payroll?.employee_number ||\n pair?.payroll?.employeeNumber ||\n ''\n );\n\n if (payrollNumber) return payrollNumber;\n\n const decision = resolveBamboo(\n pair?.bank || {},\n [pair?.payroll?.employee_name || ''].filter(Boolean),\n []\n );\n\n return bambooEmployeeNumberFromDecision(decision);\n}\n\nfunction resolvedEmployeeNumberForPayroll(payroll) {\n const payrollNumber = clean(\n payroll?.employee_number ||\n payroll?.employeeNumber ||\n ''\n );\n\n if (payrollNumber) return payrollNumber;\n\n const decision = precomputedDecision(\n payroll?.employee_name || ''\n );\n\n return bambooEmployeeNumberFromDecision(decision);\n}\n\nfunction resolvedEmployeeNumberForBankRow(\n bankRow,\n linkedNames = []\n) {\n const decision = resolveBamboo(\n bankRow || {},\n linkedNames.filter(Boolean),\n []\n );\n\n return bambooEmployeeNumberFromDecision(decision);\n}\n\nconst coreRows = [];\nconst wrongAccountGroups = new Map();\nfor (const pair of matchedPairs) {\n if (!includedBankKeySet.has(pair.key)) continue;\n const payrollAmount = roundMoney(pair.payroll.payroll_amount);\n const bankAmount = roundMoney(pair.bank.amount);\n const difference = moneyDiff(payrollAmount, bankAmount);\n const currency = clean(pair.payroll.currency || pair.bank.currency || 'USD').toUpperCase() === 'USD' ? 'USD' : 'HNL';\n const payrollAccount = normalizeAccount(pair.payroll.account || pair.payroll.payroll_account);\n const bankAccount = normalizeAccount(pair.bank.account);\n const accountMismatch = Boolean(payrollAccount && bankAccount && payrollAccount !== bankAccount);\n const resolvedEmployeeNumber = resolvedEmployeeNumberForPair(pair);\n if (accountMismatch) {\n const groupKey = `${normalizeName(pair.payroll.employee_name)}|${currency}|${payrollAccount}|${bankAccount}`;\n const current = wrongAccountGroups.get(groupKey) || {\n id: `pr_wrong_account_${wrongAccountGroups.size + 1}`,\n employee: pair.payroll.employee_name,\n employee_name: pair.payroll.employee_name,\n employeeNumber: resolvedEmployeeNumber, employee_number: resolvedEmployeeNumber,\n account: bankAccount, payrollAccount, payroll_account: payrollAccount, bankAccount, bank_account: bankAccount,\n currency, payrollAmount:0, payroll_amount:0, bankAmount:0, bank_amount:0, difference:0,\n status:'Pendiente revisión', category:'posible_cuenta_mal_digitada', subcategory:'nombre_y_monto_coinciden_cuenta_diferente',\n observation:`El nombre y el monto coinciden, pero la cuenta de nómina (${payrollAccount}) es diferente a la cuenta del banco (${bankAccount}).`,\n source_rows:[], source_sheets:new Set(), source_files:new Set(), shipment_numbers:new Set(), plan_numbers:new Set(),\n bank_name_file: pair.bank.bank_name_file || '', bank_account_holder: pair.bank.bank_account_holder || ''\n };\n current.payrollAmount=roundMoney(current.payrollAmount+payrollAmount); current.payroll_amount=current.payrollAmount;\n current.bankAmount=roundMoney(current.bankAmount+bankAmount); current.bank_amount=current.bankAmount; current.difference=moneyDiff(current.payrollAmount,current.bankAmount);\n current.source_rows.push(pair.payroll); if(pair.payroll.source_sheet)current.source_sheets.add(pair.payroll.source_sheet); if(pair.bank.source_file)current.source_files.add(pair.bank.source_file); if(pair.bank.shipment_number)current.shipment_numbers.add(pair.bank.shipment_number); if(pair.bank.plan_number)current.plan_numbers.add(pair.bank.plan_number);\n wrongAccountGroups.set(groupKey,current); continue;\n }\n const exact = sameCent(payrollAmount, bankAmount);\n coreRows.push({id:`pr_match_${pair.payrollIndex+1}_${pair.bankIndex+1}`,employee:pair.payroll.employee_name,employee_name:pair.payroll.employee_name,employeeNumber:resolvedEmployeeNumber,employee_number:resolvedEmployeeNumber,account:bankAccount||payrollAccount,payrollAccount:payrollAccount,payroll_account:payrollAccount,bankAccount:bankAccount,bank_account:bankAccount,currency,payrollAmount,payroll_amount:payrollAmount,bankAmount,bank_amount:bankAmount,difference,status:exact?'Coincide':'Pendiente revisión',category:exact?'coincidencia':'discrepancia',subcategory:exact?'persona_cuenta_y_monto_exactos':'persona_y_cuenta_coinciden_monto_diferente',observation:exact?'Coincidencia de persona, cuenta y monto.':difference>0?'Se pagó de menos.':'Se pagó de más.',source_kind:pair.payroll.source_kind||'',source_sheet:pair.payroll.source_sheet||'',source_file:pair.bank.source_file||'',shipment_number:pair.bank.shipment_number||'',plan_number:pair.bank.plan_number||'',plan_label:pair.bank.plan_label||'',reference:pair.bank.reference||'',bank_name_file:pair.bank.bank_name_file||'',bank_account_holder:pair.bank.bank_account_holder||''});\n}\nfor (let payrollIndex=0; payrollIndex({...row,source_sheets:Array.from(row.source_sheets),source_files:Array.from(row.source_files),shipment_numbers:Array.from(row.shipment_numbers),plan_numbers:Array.from(row.plan_numbers),source_sheet:Array.from(row.source_sheets).join(' / '),source_file:Array.from(row.source_files).join(' / '),shipment_number:Array.from(row.shipment_numbers).join(' / '),plan_number:Array.from(row.plan_numbers).join(' / ')}));\ncoreRows.push(...wrongAccountRows);\n\n// Banco sin Nómina se conserva a nivel de TRANSACCIÓN.\n// Una misma persona/cuenta puede tener más de un pago bancario legítimamente\n// separado; agruparlos reduce artificialmente el número de hallazgos.\nconst bankWithoutPayrollRows = [];\n\nfor (const entry of includedBankRows) {\n if (usedBankKeys.has(entry.key)) continue;\n\n const row = entry.row;\n const displayName =\n bankDisplayName(row);\n\n const rowCurrency =\n clean(row.currency || 'USD')\n .toUpperCase() === 'USD'\n ? 'USD'\n : 'HNL';\n\n const bankAmount =\n roundMoney(row.amount || 0);\n\n const resolvedEmployeeNumber =\n resolvedEmployeeNumberForBankRow(\n row,\n [displayName]\n );\n\n bankWithoutPayrollRows.push({\n id:\n `pr_bank_without_payroll_${entry.index + 1}`,\n employee: displayName,\n employee_name: displayName,\n employeeNumber: resolvedEmployeeNumber,\n employee_number: resolvedEmployeeNumber,\n account: row.account || '',\n payrollAccount: '',\n payroll_account: '',\n bankAccount: row.account || '',\n bank_account: row.account || '',\n currency: rowCurrency,\n payrollAmount: 0,\n payroll_amount: 0,\n bankAmount,\n bank_amount: bankAmount,\n difference:\n roundMoney(0 - bankAmount),\n status: 'Pendiente revisión',\n category: 'banco_sin_nomina',\n subcategory:\n 'pago_banco_sin_registro_nomina',\n observation:\n 'Pago bancario sin registro equivalente en las planillas cargadas.',\n bank_name_file:\n row.bank_name_file || '',\n bank_account_holder:\n row.bank_account_holder || '',\n source_file:\n row.source_file || '',\n shipment_number:\n row.shipment_number || '',\n plan_number:\n row.plan_number || '',\n reference:\n row.reference || '',\n row_number:\n row.row_number || null,\n source_rows: [row],\n });\n}\n\ncoreRows.push(...bankWithoutPayrollRows);\n\nconst nameDifferenceRows = [];\nfor (const entry of includedBankRows) {\n const row = entry.row;\n const rowCurrency=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';\n if (!clean(row.bank_name_file) || !clean(row.bank_account_holder)) continue;\n if (bankNameLooksConsistent(row.bank_name_file, row.bank_account_holder)) continue;\n const resolvedEmployeeNumber =\n resolvedEmployeeNumberForBankRow(\n row,\n [row.bank_name_file, row.bank_account_holder]\n );\n nameDifferenceRows.push({\n id: `pr_bank_name_difference_${entry.index + 1}`,\n employee: row.bank_name_file,\n employee_name: row.bank_name_file,\n employeeNumber: resolvedEmployeeNumber,\n employee_number: resolvedEmployeeNumber,\n account: row.account || '',\n payrollAccount: '',\n payroll_account: '',\n bankAccount: row.account || '',\n bank_account: row.account || '',\n currency: rowCurrency,\n payrollAmount: 0,\n payroll_amount: 0,\n bankAmount: roundMoney(row.amount),\n bank_amount: roundMoney(row.amount),\n difference: 0,\n status: 'Pendiente revisión',\n category: 'diferencia_nombre_banco',\n subcategory: 'nombre_archivo_vs_cuentahabiente',\n observation: `El Nombre en Archivo (${row.bank_name_file}) no coincide con el Nombre del Cuentahabiente (${row.bank_account_holder}).`,\n bank_name_file: row.bank_name_file,\n bank_account_holder: row.bank_account_holder,\n source_file: row.source_file || '',\n shipment_number: row.shipment_number || '',\n plan_number: row.plan_number || '',\n reference: row.reference || '',\n row_number: row.row_number || null,\n });\n}\n\nconst bankWithoutBambooMap = new Map();\nconst bambooMatchDetails = [];\nfor (const entry of includedBankRows) {\n const row = entry.row;\n const linkedNames =\n linkedPayrollNamesByBankKey.get(entry.key) || [];\n\n const linkedEmployeeNumbers =\n linkedPayrollEmployeeNumbersByBankKey.get(\n entry.key\n ) || [];\n\n const decision = resolveBamboo(\n row,\n linkedNames,\n linkedEmployeeNumbers\n );\n bambooMatchDetails.push({\n bank_row_key: entry.key,\n bank_name_file: row.bank_name_file || '',\n bank_account_holder: row.bank_account_holder || '',\n account: row.account || '',\n amount: row.amount || 0,\n linked_payroll_names: linkedNames,\n ...decision,\n });\n if (decision.found) continue;\n\n const displayName = bankDisplayName(row);\n const rowCurrency=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';\n const groupingKey = `${normalizeAccount(row.account)}|${normalizeName(displayName)}|${rowCurrency}`;\n const current = bankWithoutBambooMap.get(groupingKey) || {\n id: `pr_bank_without_bamboo_${bankWithoutBambooMap.size + 1}`,\n bank_name_file: row.bank_name_file || displayName,\n bank_account_holder: row.bank_account_holder || '',\n employee_name: row.bank_name_file || displayName,\n account: row.account || '',\n currency: rowCurrency,\n bank_amount: 0,\n amount: 0,\n status: 'Pendiente revisión',\n category: 'banco_sin_bamboo',\n shipment_numbers: new Set(),\n references: new Set(),\n source_files: new Set(),\n source_rows: [],\n };\n current.bank_amount = roundMoney(current.bank_amount + Number(row.amount || 0));\n current.amount = current.bank_amount;\n if (row.shipment_number) current.shipment_numbers.add(row.shipment_number);\n if (row.reference) current.references.add(row.reference);\n if (row.source_file) current.source_files.add(row.source_file);\n current.source_rows.push(row);\n bankWithoutBambooMap.set(groupingKey, current);\n}\n\nconst bankWithoutBamboo = Array.from(bankWithoutBambooMap.values()).map((row) => ({\n ...row,\n shipment_numbers: Array.from(row.shipment_numbers),\n shipment_number: Array.from(row.shipment_numbers).join(' / '),\n references: Array.from(row.references),\n source_files: Array.from(row.source_files),\n source_file: Array.from(row.source_files).join(' / '),\n difference: roundMoney(0 - row.bank_amount),\n}));\n\nfunction priority(row) {\n const category = clean(row.category).toLowerCase();\n if (category === 'posible_cuenta_mal_digitada') return 1;\n if (category === 'discrepancia') return 2;\n if (category === 'banco_sin_nomina') return 3;\n if (category === 'diferencia_nombre_banco') return 5;\n if (category === 'coincidencia') return 99;\n return 50;\n}\n\nconst rowsFinales = [...coreRows, ...nameDifferenceRows].sort((a, b) => {\n const p = priority(a) - priority(b);\n if (p !== 0) return p;\n return clean(a.employee_name).localeCompare(clean(b.employee_name), 'es');\n});\n\nconst coincidencias = coreRows.filter((row) => row.category === 'coincidencia').length;\nconst discrepancias = coreRows.filter((row) => row.category === 'discrepancia').length;\nconst bancoSinNomina = bankWithoutPayrollRows.length;\nconst diferenciasNombreBanco = nameDifferenceRows.length;\nconst posiblesCuentasMalDigitadas = wrongAccountRows.length;\nconst pendientes = discrepancias + bancoSinNomina + diferenciasNombreBanco;\nconst totalNominaByCurrency = {HNL:0,USD:0};\nfor(const row of payrollRows){const c=clean(row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';totalNominaByCurrency[c]=roundMoney(totalNominaByCurrency[c]+Number(row.payroll_amount||0));}\nconst totalBancoByCurrency = {HNL:0,USD:0};\nfor(const entry of includedBankRows){const c=clean(entry.row.currency||'USD').toUpperCase()==='USD'?'USD':'HNL';totalBancoByCurrency[c]=roundMoney(totalBancoByCurrency[c]+Number(entry.row.amount||0));}\nconst diferenciaByCurrency={HNL:moneyDiff(totalNominaByCurrency.HNL,totalBancoByCurrency.HNL),USD:moneyDiff(totalNominaByCurrency.USD,totalBancoByCurrency.USD)};\nconst totalNomina=totalNominaByCurrency.HNL || totalNominaByCurrency.USD;\nconst totalBanco=totalBancoByCurrency.HNL || totalBancoByCurrency.USD;\nconst diferenciaTotal=totalNominaByCurrency.HNL||totalBancoByCurrency.HNL?diferenciaByCurrency.HNL:diferenciaByCurrency.USD;\n\nconst bambooSummaryCompact = { ...(data.bamboo || {}) };\ndelete bambooSummaryCompact.employees;\n\nreturn [{\n json: {\n ok: true,\n stage: 'cruce_nomina_banco_puerto_rico',\n errors: [],\n metadata: data.metadata || {},\n summary: {\n coincidencias,\n discrepancias,\n bancoSinNomina,\n bancoSinBamboo: bankWithoutBamboo.length,\n nominaSinCuenta: 0,\n diferenciasNombreBanco,\n posiblesCuentasMalDigitadas,\n pendientes,\n filasNominaValidas: Number(data.payroll?.base_rows_count || data.payroll?.valid_rows_count || 0),\n filasNominaSinCuenta: 0,\n suplementosPotenciales: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaAplicados: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaNoAplicados: 0,\n suplementosNominaAdjuntados: Number(data.payroll?.supplement_rows_count || 0),\n suplementosNominaNoAdjuntados: Number(data.payroll?.unattached_supplements_count || 0),\n reconciliacionesExactasFinales: coincidencias,\n cuentasNominaAgrupadas: 0,\n transaccionesBanco: includedBankRows.length,\n cuentasBancoAgrupadas: new Set(includedBankRows.map((entry) => normalizeAccount(entry.row.account)).filter(Boolean)).size,\n empleadosBambooPR: Number(data.bamboo?.puerto_rico_count || 0),\n empleadosBambooEnPeriodo: Number(data.bamboo?.active_in_period_count || 0),\n bambooPaginasDescargadas: Number(data.bamboo?.pages_fetched || 0),\n bambooEmpleadosEsperados: Number(data.bamboo?.expected_total || 0),\n bambooDescargaCompleta: Boolean(data.bamboo?.fetch_complete),\n bambooValidacionDisponible: bambooValidationAvailable,\n totalNominaBase: roundMoney(data.payroll?.base_total || 0),\n totalSuplementosAplicados: roundMoney(data.payroll?.supplements_total || 0),\n totalNomina,\n totalBanco,\n diferenciaTotal,\n totalNominaPorMoneda: totalNominaByCurrency,\n totalBancoPorMoneda: totalBancoByCurrency,\n diferenciaTotalPorMoneda: diferenciaByCurrency,\n },\n rows: rowsFinales,\n bankWithoutBamboo,\n nameDifferences: nameDifferenceRows,\n bambooSummary: bambooSummaryCompact,\n reportUrl: null,\n debug: {\n matched_pairs_count: matchedPairs.length,\n included_bank_rows_count: includedBankRows.length,\n excluded_bank_rows_count: excludedBankRows.length,\n excluded_bank_rows_preview: excludedBankRows.slice(0, 100),\n validated_bamboo_aliases_loaded: validatedBambooAliases.length,\n bamboo_matches: bambooMatchDetails,\n rows_with_employee_number: rowsFinales.filter((row) => clean(row.employeeNumber || row.employee_number)).length,\n bamboo_validation_available: bambooValidationAvailable,\n banco_sin_bamboo: bankWithoutBamboo,\n payroll_preview: payrollRows.slice(0, 20),\n bank_included_preview: includedBankRows.slice(0, 20).map((entry) => entry.row),\n },\n },\n}];\n" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -120, - 5200 + 1600, + 512 ], - "id": "f7befa53-9b77-44d3-b0fb-e456328163e5", + "id": "cb9e73f3-01f2-4f5c-a0df-930cbeb2c785", "name": "Cruzar Nómina vs Banco" }, { @@ -271,10 +271,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 120, - 5200 + 1840, + 512 ], - "id": "ffde494e-1ffa-41e6-a76d-3322f684dec7", + "id": "b5d8cdc8-e213-42ab-abfb-a7a1c8c1e933", "name": "Preparar Google Sheet" }, { @@ -317,10 +317,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 360, - 5200 + 2080, + 512 ], - "id": "81fd24de-a18d-4efd-b030-c8f193673745", + "id": "52000c75-ab56-457f-93c6-9881ed06ceb5", "name": "Buscar reporte existente Supabase" }, { @@ -337,10 +337,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 600, - 5200 + 2320, + 512 ], - "id": "170ec328-0a9f-401b-9852-ca472d6ac14d", + "id": "b43f794a-99ce-493c-9351-11efad8ff4e8", "name": "Crear Google Sheet", "retryOnFail": true, "credentials": { @@ -362,10 +362,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 840, - 5200 + 2560, + 512 ], - "id": "5d4d04ba-ee83-4a46-a419-f028729bb7bc", + "id": "529d496a-8835-4400-b6fe-fed68ededa4f", "name": "Leer Google Sheet actual", "retryOnFail": true, "credentials": { @@ -382,10 +382,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 1080, - 5200 + 2800, + 512 ], - "id": "81decb9b-a5ca-4c4b-836f-41a1389cf472", + "id": "a870ce54-541e-4153-8a39-16b40c4473ee", "name": "Preparar actualización Google Sheet" }, { @@ -404,10 +404,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 1320, - 5200 + 3040, + 512 ], - "id": "973e9e0e-a044-4870-8f41-1c02f1ff5412", + "id": "1e8e1a60-3c44-4032-90a2-f730cfc7e923", "name": "Actualizar estructura Google Sheet", "retryOnFail": true, "credentials": { @@ -433,10 +433,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 1560, - 5200 + 3280, + 512 ], - "id": "174a00f9-d50b-439a-ae7f-844d3c5cc53e", + "id": "17a9f487-226d-4e5e-a25f-211307a82eba", "name": "Limpiar Google Sheet", "retryOnFail": true, "credentials": { @@ -462,10 +462,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 1800, - 5200 + 3520, + 512 ], - "id": "7731ef3c-018c-4a73-b4c2-11247e0142b8", + "id": "d6360b18-64d0-4bac-bd8a-0c36408ae17a", "name": "Escribir Google Sheet", "retryOnFail": true, "credentials": { @@ -491,10 +491,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2040, - 5200 + 3760, + 512 ], - "id": "0e27f441-b958-44ad-8f90-b33449c42d03", + "id": "a0548db1-391c-44ac-8ecb-dcf743e43288", "name": "Formatear Google Sheet", "retryOnFail": true, "credentials": { @@ -511,10 +511,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2280, - 5200 + 4000, + 512 ], - "id": "24e9bed0-49df-488f-8b07-d9027c62bf9f", + "id": "33a944c6-427c-49ff-8357-815e04819b67", "name": "Preparar permisos Google Sheet" }, { @@ -531,10 +531,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2520, - 5200 + 4240, + 512 ], - "id": "88b2fb70-5a7b-4343-bc45-b84fb664b21b", + "id": "c6f70254-2628-4bc1-9fce-c69fb28e9fde", "name": "Compartir Google Sheet", "credentials": { "googleOAuth2Api": { @@ -551,10 +551,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2760, - 5200 + 4480, + 512 ], - "id": "0534fec7-fb94-4893-9e50-9a1afdfb843f", + "id": "d61a3429-2611-4bb7-9047-001b70f9bbfe", "name": "Preparar histórico Supabase" }, { @@ -590,10 +590,10 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 3000, - 5200 + 4720, + 512 ], - "id": "c87f31ff-6179-42c7-904c-e2fc684685f9", + "id": "cd030296-381a-4c2e-ac83-12387336cb99", "name": "Insertar histórico Supabase", "onError": "continueRegularOutput" }, @@ -604,10 +604,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 3240, - 5120 + 4960, + 432 ], - "id": "aaa3a012-5f5f-412d-93fb-890f7093b906", + "id": "acc74d61-7462-4c74-bb5a-8bf5e85700f4", "name": "Preparar respuesta final" }, { @@ -629,23 +629,23 @@ "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.5, "position": [ - 3480, - 5120 + 5200, + 432 ], - "id": "3278f6df-9a9a-443d-a8a5-5267cf38286c", + "id": "bf03d628-bf89-4be8-a451-09ac9d561ebe", "name": "Respond to Webhook" }, { "parameters": { - "jsCode": "const prepared = $('Preparar histórico Supabase').first().json || {};\nconst payload = prepared.supabasePayload || {};\nconst metadata = payload.metadata || {};\nconst summary = payload.summary || {};\nconst reportUpdated = prepared.reportUpdated === true;\n\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction numberValue(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction formatGeneratedAt(date) {\n const timeZone = 'America/Puerto_Rico';\n\n const dateLabel = new Intl.DateTimeFormat('es-PR', {\n timeZone,\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(date);\n\n const timeLabel = new Intl.DateTimeFormat('es-PR', {\n timeZone,\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }).format(date);\n\n const hour24Raw = new Intl.DateTimeFormat('en-US', {\n timeZone,\n hour: '2-digit',\n hour12: false,\n }).format(date);\n\n const hour24 =\n Number(String(hour24Raw).replace(/\\D/g, '')) % 24;\n\n const hourArticle =\n hour24 === 1 || hour24 === 13\n ? 'a la'\n : 'a las';\n\n return `${dateLabel} ${hourArticle} ${timeLabel}`;\n}\n\nfunction metricCard(label, value, accent) {\n return `\n \n \n \n
FechaPeríodoArchivo de Nómina / Bono 14CoincidenciasBanco sin BambooPendientesEstadoResuelto porAccionesFechaPeríodoArchivo de Nómina / Bono 14CoincidenciasBanco sin BambooPendientesEstadoResuelto porAcciones
+
@@ -876,15 +928,15 @@ export default function History({
{report.period} + {report.period}
- {report.payrollFile || 'No especificado'} + {report.payrollFile || 'No especificado'}
{report.matches} + {report.matches} {report.bankWithoutBamboo > 0 ? ( + 0 @@ -914,12 +966,12 @@ export default function History({ : `${report.totalPending} pendiente${report.totalPending > 1 ? 's' : ''}`} + {statusText(report.status)} + {report.resolvedBy ? (

{report.resolvedBy}

@@ -929,11 +981,11 @@ export default function History({ Pendiente )}
-
+
+
\n \n
\n \n ${escapeHtml(label)}\n \n\n \n ${numberValue(value).toLocaleString('en-US')}\n \n
\n
\n\n \n\n \n
\n \n
\n\n
\n\n \n \n\n \n \n \n\n \n\n \n Cruce de Cuentas · ${escapeHtml(countryName)}\n \n\n \n ${escapeHtml(periodLabel)}\n \n\n \n\n \n \n\n \n \n\n \n \n \n\n \n ${reportUpdated ? 'Se actualizó el reporte existente del Portal de Cruce de Cuentas GLM conservando las resoluciones previamente registradas que continúan correspondiendo a los mismos casos.' : 'Se completó una nueva ejecución del Portal de Cruce de Cuentas GLM. Este es el resumen del reporte generado.'}\n \n\n \n \n\n \n \n \n\n \n \n ${metricCards}\n \n \n\n \n \n\n \n \n \n\n \n\n \n\n \n\n \n Ejecutado por\n \n\n \n ${escapeHtml(executedByName)}\n \n\n \n ${escapeHtml(\n executedByEmail ||\n 'Correo no disponible'\n )}\n \n\n \n\n \n\n \n País\n \n\n \n \n\n \n \n \n\n \n\n \n ${escapeHtml(countryName)}\n \n\n \n ${escapeHtml(\n countryCode || '—'\n )}\n \n\n \n\n \n \n\n \n\n \n\n \n\n \n\n \n Período\n \n\n \n ${escapeHtml(periodLabel)}\n \n\n \n ${escapeHtml(generatedAtLabel)}\n \n\n \n\n \n\n \n Estado inicial\n \n\n \n ${escapeHtml(statusLabel)}\n \n\n \n Coincidencias:\n ${coincidencias.toLocaleString('en-US')}\n \n\n \n\n \n\n \n\n \n \n\n \n ${\n reportUrl\n ? `\n \n \n\n \n Abrir reporte en Google Sheets\n \n\n \n \n `\n : ''\n }\n\n \n \n \n\n \n\n \n Notificación automática · Portal Cruce de Cuentas GLM\n
\n Los casos de revisión deben gestionarse directamente en el reporte generado.\n \n\n \n \n\n \n\n \n \n \n\n\n\n`;\n\nreturn [\n {\n json: {\n to,\n subject,\n htmlBody,\n\n notification: {\n country: countryCode,\n countryName,\n flagUrl,\n periodLabel,\n executedByName,\n executedByEmail,\n generatedAt: generatedAt.toISOString(),\n reportUrl,\n\n metrics: {\n discrepancias,\n bancoSinNomina,\n bancoSinBamboo,\n diferenciasNombreBanco,\n nominaSinCuenta,\n coincidencias,\n },\n },\n },\n },\n];" + "jsCode": "const prepared = $('Preparar histórico Supabase').first().json || {};\nconst payload = prepared.supabasePayload || {};\nconst metadata = payload.metadata || {};\nconst summary = payload.summary || {};\nconst reportUpdated = prepared.reportUpdated === true;\n\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction numberValue(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction formatGeneratedAt(date) {\n const timeZone = 'America/Puerto_Rico';\n\n const dateLabel = new Intl.DateTimeFormat('es-PR', {\n timeZone,\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(date);\n\n const timeLabel = new Intl.DateTimeFormat('es-PR', {\n timeZone,\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }).format(date);\n\n const hour24Raw = new Intl.DateTimeFormat('en-US', {\n timeZone,\n hour: '2-digit',\n hour12: false,\n }).format(date);\n\n const hour24 =\n Number(String(hour24Raw).replace(/\\D/g, '')) % 24;\n\n const hourArticle =\n hour24 === 1 || hour24 === 13\n ? 'a la'\n : 'a las';\n\n return `${dateLabel} ${hourArticle} ${timeLabel}`;\n}\n\nfunction metricCard(label, value, accent) {\n return `\n \n \n \n \n \n ${escapeHtml(label)}\n \n\n \n ${numberValue(value).toLocaleString('en-US')}\n \n \n \n \n \n `;\n}\n\nconst countryCode = 'PR';\nconst countryName = 'Puerto Rico';\n\nconst periodLabel =\n payload.period_label ||\n metadata.period_label ||\n [\n payload.year || metadata.year,\n payload.month || metadata.month,\n payload.period_type || metadata.period_type,\n ]\n .filter(Boolean)\n .join(' · ') ||\n 'Período no especificado';\n\nconst executedByName =\n payload.ejecutado_por_nombre ||\n metadata.requested_by_name ||\n 'Usuario GLM';\n\nconst executedByEmail =\n payload.ejecutado_por_email ||\n metadata.requested_by_email ||\n '';\n\nconst reportUrl =\n payload.report_url ||\n prepared.reportUrl ||\n '';\n\nconst discrepancias = numberValue(\n payload.discrepancias ??\n summary.discrepancias\n);\n\nconst bancoSinNomina = numberValue(\n payload.banco_sin_nomina ??\n summary.bancoSinNomina\n);\n\nconst bancoSinBamboo = numberValue(\n payload.banco_sin_bamboo ??\n summary.bancoSinBamboo\n);\n\nconst diferenciasNombreBanco = numberValue(\n metadata.diferencias_nombre_banco ??\n summary.diferenciasNombreBanco\n);\n\nconst nominaSinCuenta = numberValue(\n payload.nomina_sin_cuenta ??\n summary.nominaSinCuenta\n);\n\nconst coincidencias = numberValue(\n payload.coincidencias ??\n summary.coincidencias\n);\n\nconst generatedAt = new Date();\nconst generatedAtLabel =\n formatGeneratedAt(generatedAt);\n\nconst statusLabel =\n String(payload.estado || '').toLowerCase() === 'resuelto'\n ? 'Resuelto'\n : 'Pendiente de revisión';\n\nconst logoUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png';\n\nconst flagUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/bandera-nacional-tela-puerto-rico_113767-1759.avif';\n\nconst subject = reportUpdated\n ? `Reporte actualizado - Cruce de Cuentas ${countryName} - ${periodLabel}`\n : `Nuevo reporte generado - Cruce de Cuentas ${countryName} - ${periodLabel}`;\n\n/*\n * Todos son destinatarios directos.\n * Nadie se envía en CC.\n */\n\nconst to = [\n 'iaracena@gomezleemarketing.com'\n].join(',');\n\n\n// Paleta oficial GLM.\nconst metricCards = [\n metricCard(\n 'Discrepancias',\n discrepancias,\n '#FF6A13'\n ),\n metricCard(\n 'Banco sin nómina',\n bancoSinNomina,\n '#FF8C00'\n ),\n metricCard(\n 'Banco sin Bamboo',\n bancoSinBamboo,\n '#E87722'\n ),\n metricCard(\n 'Diferencias nombre banco',\n diferenciasNombreBanco,\n '#5B7F95'\n ),\n metricCard(\n 'Nómina sin cuenta',\n nominaSinCuenta,\n '#4F758B'\n ),\n].join('');\n\nconst htmlBody = `\n\n\n\n\n \n \n ${escapeHtml(subject)}\n\n\n\n\n \n \n \n\n \n\n \n \n \n  \n \n \n\n \n \n \n\n \n \n \n \n \n\n \n \n ${reportUpdated ? 'REPORTE ACTUALIZADO' : 'REPORTE GENERADO'}\n \n \n \n \n\n \n\n \n \n\n \n \n \n\n \n\n \n Cruce de Cuentas · ${escapeHtml(countryName)}\n \n\n \n ${escapeHtml(periodLabel)}\n \n\n \n\n \n \n\n \n \n\n \n \n \n\n \n ${reportUpdated ? 'Se actualizó el reporte existente del Portal de Cruce de Cuentas GLM conservando las resoluciones previamente registradas que continúan correspondiendo a los mismos casos.' : 'Se completó una nueva ejecución del Portal de Cruce de Cuentas GLM. Este es el resumen del reporte generado.'}\n \n\n \n \n\n \n \n \n\n \n \n ${metricCards}\n \n \n\n \n \n\n \n \n \n\n \n\n \n\n \n\n \n Ejecutado por\n \n\n \n ${escapeHtml(executedByName)}\n \n\n \n ${escapeHtml(\n executedByEmail ||\n 'Correo no disponible'\n )}\n \n\n \n\n \n\n \n País\n \n\n \n \n\n \n \n \n\n \n\n \n ${escapeHtml(countryName)}\n \n\n \n ${escapeHtml(\n countryCode || '—'\n )}\n \n\n \n\n \n \n\n \n\n \n\n \n\n \n\n \n Período\n \n\n \n ${escapeHtml(periodLabel)}\n \n\n \n ${escapeHtml(generatedAtLabel)}\n \n\n \n\n \n\n \n Estado inicial\n \n\n \n ${escapeHtml(statusLabel)}\n \n\n \n Coincidencias:\n ${coincidencias.toLocaleString('en-US')}\n \n\n \n\n \n\n \n\n \n \n\n \n ${\n reportUrl\n ? `\n \n \n\n \n Abrir reporte en Google Sheets\n \n\n \n \n `\n : ''\n }\n\n \n \n \n\n \n\n \n Notificación automática · Portal Cruce de Cuentas GLM\n
\n Los casos de revisión deben gestionarse directamente en el reporte generado.\n \n\n \n \n\n \n\n \n \n \n\n\n\n`;\n\nreturn [\n {\n json: {\n to,\n subject,\n htmlBody,\n\n notification: {\n country: countryCode,\n countryName,\n flagUrl,\n periodLabel,\n executedByName,\n executedByEmail,\n generatedAt: generatedAt.toISOString(),\n reportUrl,\n\n metrics: {\n discrepancias,\n bancoSinNomina,\n bancoSinBamboo,\n diferenciasNombreBanco,\n nominaSinCuenta,\n coincidencias,\n },\n },\n },\n },\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 3240, - 5360 + 4960, + 672 ], - "id": "6875ed54-851a-44b3-b998-25735b5464dd", + "id": "94f01fb4-e536-4b86-aebc-8ab27b61381f", "name": "Preparar correo reporte generado" }, { @@ -660,10 +660,10 @@ "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ - 3480, - 5360 + 5200, + 672 ], - "id": "442d0a94-4369-4bfd-8d8e-dbb9f77e4df3", + "id": "5bd3e192-88b5-400e-acd5-57511f78c440", "name": "Enviar correo reporte generado", "webhookId": "4bcdbd7b-503d-46ac-aeaf-9207f59f01e7", "credentials": { @@ -683,10 +683,10 @@ "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ - -2800, - 4768 + -1088, + 80 ], - "id": "ebbfb113-b7a1-42ff-bedb-bb02ad43ac33", + "id": "43fccfea-0ca0-4500-acbd-259f5bec978e", "name": "📌 PUERTO RICO · V1" }, { @@ -698,10 +698,10 @@ "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ - -1712, - 4688 + 0, + 0 ], - "id": "3f985792-728c-4f1a-baae-18e963312f62", + "id": "aaa2fb59-9745-48b6-9b8b-3d5442493347", "name": "📌 REGLA BANCO PR" }, { @@ -713,10 +713,10 @@ "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ - -2320, - 5616 + -608, + 928 ], - "id": "c1e22489-fa4a-49f8-984d-fa2c497620de", + "id": "c2f319b9-18d2-4b48-90b0-adb64308b513", "name": "📌 ARCHIVOS NÓMINA PR" }, { @@ -728,10 +728,10 @@ "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ - 1672, - 5520 + 3392, + 832 ], - "id": "dd6b181f-198e-4a8a-a363-a0db9d5741b5", + "id": "2fc5ac1d-e386-4997-8e24-7dd5205bc966", "name": "📌 REPORTES" }, { @@ -745,10 +745,10 @@ "type": "n8n-nodes-base.extractFromFile", "typeVersion": 1.1, "position": [ - -1840, - 4960 + -128, + 272 ], - "id": "d9f7fced-ae32-4065-87fb-9f86c8c286f2", + "id": "3ae0b89c-da34-4fdc-aef8-46a4c8a3ff8a", "name": "Extract - PDF Banco PR" }, { @@ -758,10 +758,10 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - -1600, - 4960 + 112, + 272 ], - "id": "aaead29e-f149-443f-80ab-7d6bad0a2b6f", + "id": "15cc9f68-6c58-4ca2-b8bc-67198a69c6f2", "name": "Parsear PDF banco PR" }, { @@ -792,10 +792,10 @@ "type": "n8n-nodes-base.if", "typeVersion": 2.3, "position": [ - -2320, - 5200 + -608, + 512 ], - "id": "e48a9f66-61b5-4880-8f51-4032744e9f8b", + "id": "8b489512-819e-4f62-a6b9-309cdbb42732", "name": "¿Entrada PR válida?" }, { @@ -821,10 +821,10 @@ "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.5, "position": [ - -2080, - 5720 + -368, + 1040 ], - "id": "9a663a01-3ad7-4904-a2ac-239c9c6a2ef8", + "id": "d9247c61-bd3a-4fd8-a706-e15518665037", "name": "Responder error entrada PR" } ], @@ -1183,14 +1183,15 @@ ] } }, - "active": false, + "active": true, "settings": { "executionOrder": "v1", "binaryMode": "separate" }, - "versionId": "1a174b21-9f77-443a-9616-ef028022f4d8", + "versionId": "9b578dec-b1d2-410a-9920-4d888faf128f", "meta": { "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" }, + "id": "1ddUHqgdN3lZQx6T", "tags": [] -} +} \ No newline at end of file diff --git a/workflows_n8n/Portal de Verificaci├│n de N├│mina - Rep├║blica Dominicana.json b/workflows_n8n/Portal de Verificaci├│n de N├│mina - Rep├║blica Dominicana.json new file mode 100644 index 0000000..5f5c4df --- /dev/null +++ b/workflows_n8n/Portal de Verificaci├│n de N├│mina - Rep├║blica Dominicana.json @@ -0,0 +1,1338 @@ +{ + "name": "Portal de Verificación de Nómina - República Dominicana", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "nominard-bamboo-test", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + -2544, + 7136 + ], + "id": "d1c2f022-e59f-4d63-ad9e-3e7fb96b0cfb", + "name": "Webhook", + "webhookId": "e09bd121-2708-4ea9-9e71-74b36bd3dc99" + }, + { + "parameters": { + "jsCode": "const item = $input.first();\nconst body = item.json.body || {};\nconst binary = item.binary || {};\n\nlet metadata = {};\ntry {\n metadata = typeof body.metadata === 'string' ? JSON.parse(body.metadata) : (body.metadata || {});\n} catch (error) { metadata = {}; }\n\nconst binaryKeys = Object.keys(binary);\nfunction natural(a,b){ return String(a).localeCompare(String(b),undefined,{numeric:true,sensitivity:'base'}); }\nfunction ext(file){\n const explicit=String(file?.fileExtension||'').toLowerCase().replace(/^\\./,'');\n if(explicit) return explicit;\n const m=String(file?.fileName||'').toLowerCase().match(/\\.([a-z0-9]+)$/); return m?m[1]:'';\n}\nfunction collect(prefixSingle,prefixRepeated){\n const numbered=binaryKeys.filter(k=>new RegExp(`^${prefixSingle}_\\\\d+$`,'i').test(k)).sort(natural);\n const repeated=binaryKeys.filter(k=>new RegExp(`^${prefixRepeated}(?:_?\\\\d+)?$`,'i').test(k)).sort(natural);\n let keys=numbered.length?numbered:repeated;\n const legacy=prefixSingle.replace(/_file$/,'_file');\n if(!keys.length && binary[legacy]) keys=[legacy];\n return keys;\n}\nlet payrollKeys=collect('payroll_file','payroll_files');\nif(!payrollKeys.length && binary.payroll_file) payrollKeys=['payroll_file'];\nlet bankKeys=collect('bank_file','bank_files');\nif(!bankKeys.length && binary.bank_file) bankKeys=['bank_file'];\n\nconst payrollFiles=payrollKeys.map(key=>({binary_key:key,file_name:binary[key]?.fileName||key,file_extension:ext(binary[key]),mime_type:binary[key]?.mimeType||'',file_size:binary[key]?.fileSize||null}));\nconst bankFiles=bankKeys.map(key=>({binary_key:key,file_name:binary[key]?.fileName||key,file_extension:ext(binary[key]),mime_type:binary[key]?.mimeType||'',file_size:binary[key]?.fileSize||null}));\n\nconst errors=[];\nif(String(metadata.country||'').trim().toUpperCase()!=='RD') errors.push('El país recibido no es República Dominicana.');\nif(!metadata.year) errors.push('No se recibió el año del cruce.');\nif(!metadata.month) errors.push('No se recibió el mes del cruce.');\nif(!metadata.period_type) errors.push('No se recibió el tipo de quincena.');\nif(!metadata.period_start || !metadata.period_end) errors.push('No se recibió el período calculado.');\nif(payrollFiles.length!==1) errors.push('República Dominicana requiere exactamente un archivo Excel de nómina por período.');\nif(!bankFiles.length) errors.push('República Dominicana requiere uno o varios archivos bancarios CSV/PDF del período.');\nconst badPayroll=payrollFiles.filter(f=>!['xlsx','xls','xlsm'].includes(f.file_extension));\nif(badPayroll.length) errors.push(`RD requiere nómina Excel (.xlsx, .xls o .xlsm): ${badPayroll.map(f=>f.file_name).join(', ')}.`);\nconst badBank=bankFiles.filter(f=>!['csv','pdf'].includes(f.file_extension));\nif(badBank.length) errors.push(`RD solo admite pagos bancarios .csv y .pdf: ${badBank.map(f=>f.file_name).join(', ')}.`);\n\nconst mainPayroll=payrollFiles[0]||null;\nconst normalizedMetadata={\n ...metadata,\n country:'RD', country_name:'República Dominicana', currency:'DOP', locale:'es-DO', time_zone:'America/Santo_Domingo',\n source_app:metadata.source_app||'portal-cruce-cuentas-glm',\n payroll_file_name:metadata.payroll_file_name||mainPayroll?.file_name||'',\n payroll_file_names:payrollFiles.map(f=>f.file_name),\n bank_file_names:bankFiles.map(f=>f.file_name),\n};\nreturn [{json:{ok:errors.length===0,stage:'entrada_rd_recibida',errors,metadata:normalizedMetadata,payroll_files:payrollFiles,bank_files:bankFiles,summary:{payroll_files_count:payrollFiles.length,bank_files_count:bankFiles.length,csv_bank_files_count:bankFiles.filter(f=>f.file_extension==='csv').length,pdf_bank_files_count:bankFiles.filter(f=>f.file_extension==='pdf').length}},binary}];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + -2304, + 7136 + ], + "id": "3e9cbb13-d20a-4a7e-b786-3ec7dba457ac", + "name": "Preparar entrada app" + }, + { + "parameters": { + "jsCode": "const input=$input.first();const base=input.json||{};const binary=input.binary||{};const files=Array.isArray(base.bank_files)?base.bank_files.filter(f=>String(f.file_extension||'').toLowerCase()==='pdf'):[];const out=[];for(const info of files){const key=String(info.binary_key||'');if(!key||!binary[key])continue;out.push({json:{source_file:String(binary[key]?.fileName||info.file_name||key),source_binary_key:key,currency:'DOP'},binary:{data:binary[key]}});}if(!out.length)return [{json:{no_pdf_files:true,source_file:''}}];return out;" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + -1824, + 6896 + ], + "id": "4c769a2b-63ef-4d5f-b9d1-b93a7b973a29", + "name": "Preparar PDF banco RD" + }, + { + "parameters": { + "jsCode": "const input=$input.first(); const base=input.json||{}; const binary=input.binary||{}; const configured=Array.isArray(base.payroll_files)?base.payroll_files:[];\n// Hojas de empleados observadas en las 16 nóminas RD de enero-agosto 2026.\n// No incluir Resumen, TSS, ISR, horas extra, AutoCrat, scripts ni \"Copia de Latam\".\nconst SHEETS=['GLM RD ','Whirlpool','Bice','P&G','KRAFT','Motorola','PMI','Caribe','Latam ','Purina','Claro','Essity'];\nconst outputs=[];\nfor(const fileInfo of configured){const key=String(fileInfo.binary_key||''); const file=binary[key]; if(!key||!file)continue; const fileName=String(file.fileName||fileInfo.file_name||key); for(const sheetName of SHEETS){outputs.push({json:{source_file:fileName,source_binary_key:key,source_kind:'quincenal',payroll_group:'republica_dominicana',sheet_name:sheetName,header_row:1,range:'A1:CA3000',currency:'DOP'},binary:{data:file}});}}\nif(!outputs.length) throw new Error('República Dominicana: no se pudo preparar el Excel de nómina.');\nreturn outputs;" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + -1824, + 7376 + ], + "id": "071b3400-deb2-4b49-b9e2-fd88f29f46a0", + "name": "Preparar archivos nómina RD" + }, + { + "parameters": { + "operation": "xlsx", + "options": { + "headerRow": true, + "range": "={{ $json.range }}", + "sheetName": "={{ $json.sheet_name }}" + } + }, + "type": "n8n-nodes-base.extractFromFile", + "typeVersion": 1.1, + "position": [ + -1584, + 7376 + ], + "id": "86db60e4-c61b-421f-b58e-f1c46f1b38c7", + "name": "Extract - Archivo Nómina RD", + "retryOnFail": false, + "onError": "continueRegularOutput" + }, + { + "parameters": { + "jsCode": "const items=$input.all(); const base=$('Preparar entrada app').first().json||{};\nfunction clean(v){return String(v??'').replace(/\\uFEFF/g,'').replace(/\\u00A0/g,' ').replace(/\\s+/g,' ').trim();}\nfunction norm(v){return clean(v).toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g,'').replace(/[^a-z0-9 #]/g,' ').replace(/\\s+/g,' ').trim();}\nfunction money(v){if(typeof v==='number')return Number.isFinite(v)?v:0;const p=Number.parseFloat(String(v??'').replace(/DOP|RD\\$|RD|\\$/gi,'').replace(/,/g,'').replace(/\\s+/g,''));return Number.isFinite(p)?p:0;}\nfunction round(v){return Math.round((Number(v)||0)*100)/100;}\nfunction account(v){const raw=clean(v);if(!raw||/[A-Za-zÀ-ÿ]/.test(raw))return '';let digits='';if(typeof v==='number'&&Number.isFinite(v)){digits=String(Math.round(v));}else if(/^[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)[eE][+-]?\\d+$/.test(raw)){const n=Number(raw);if(Number.isFinite(n))digits=String(Math.round(n));}else{digits=raw.replace(/\\.0$/,'').replace(/\\D/g,'').trim();}if(!digits||/^0+$/.test(digits))return '';return digits;}\nfunction accountMatch(v){const a=account(v);return a.replace(/^0+(?=\\d)/,'');}\nfunction get(row,keys){for(const k of keys){if(row[k]!==undefined&&row[k]!==null&&row[k]!=='')return row[k];}const actual=Object.keys(row||{});for(const expected of keys){const ne=norm(expected);const k=actual.find(x=>norm(x)===ne);if(k&&row[k]!==undefined&&row[k]!==null&&row[k]!=='')return row[k];}return '';}\nfunction validName(v){const x=clean(v),n=norm(x);if(!x||/^[\\d.,\\s-]+$/.test(x))return false;const bad=['total','subtotal','total general','gran total','nombre','empleado','colaborador','monto a pagar','isr no descontado','salida','entrada'];return !bad.some(t=>n===t||n.startsWith(`${t} `));}\nfunction validPeriod(v){if(typeof v==='number')return Number.isFinite(v)&&v>30000&&v<80000;const x=clean(v);if(!x)return false;if(/^\\d{4}-\\d{1,2}-\\d{1,2}/.test(x)||/^\\d{1,2}[\\/-]\\d{1,2}[\\/-]\\d{2,4}/.test(x))return true;const n=Number(x);return Number.isFinite(n)&&n>30000&&n<80000;}\nfunction periodIso(v){if(typeof v==='number'&&Number.isFinite(v)){const ms=Math.round(v)*86400000;return new Date(Date.UTC(1899,11,30)+ms).toISOString().slice(0,10);}const x=clean(v);let m=x.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})/);if(m)return `${m[1]}-${String(m[2]).padStart(2,'0')}-${String(m[3]).padStart(2,'0')}`;m=x.match(/^(\\d{1,2})[\\/-](\\d{1,2})[\\/-](\\d{2,4})/);if(m){const y=m[3].length===2?`20${m[3]}`:m[3];return `${y}-${String(m[2]).padStart(2,'0')}-${String(m[1]).padStart(2,'0')}`;}const num=Number(x);if(Number.isFinite(num)&&num>30000&&num<80000){const ms=Math.round(num)*86400000;return new Date(Date.UTC(1899,11,30)+ms).toISOString().slice(0,10);}return '';}\nfunction inSelectedPeriod(v){const d=periodIso(v),s=clean(base.metadata?.period_start),e=clean(base.metadata?.period_end);return !d||!s||!e||(d>=s&&d<=e);}\nfunction sourceMeta(i){try{return $('Preparar archivos nómina RD').itemMatching(i).json||{};}catch{return {};}}\nconst rows=[],ignored=[],summaries=new Map(),counters=new Map(),outsidePeriod=[]; let rawBaseTotal=0, roundedBaseTotal=0;\nitems.forEach((item,index)=>{const src=item.json||{};const linked=sourceMeta(index);const sourceFile=clean(linked.source_file||'');const sourceSheet=clean(linked.sheet_name||'');const key=`${sourceFile}|${sourceSheet}`;const dataIndex=(counters.get(key)||0)+1;counters.set(key,dataIndex);const rowNumber=Number(linked.header_row||1)+dataIndex;\n const employeeName=clean(get(src,['NOMBRE','Nombre','Nombre del Empleado','NOMBRE DEL EMPLEADO']));\n const rawAccount=get(src,['Cuenta','CUENTA','Cuenta Banco','CUENTA BANCO','CUENTA BANCARIA','Cuenta Bancaria']); const acct=account(rawAccount);\n const rawAmount=money(get(src,['NETO A PAGAR','Neto a Pagar','Total a Pagar','TOTAL A PAGAR','Total Neto'])); const amount=round(rawAmount);\n const periodValue=get(src,['PERÍODO','PERIODO','Período','Periodo']);\n const cedula=clean(get(src,['CEDULA','CÉDULA','Cedula','Cédula'])); const reference=clean(get(src,['REFERENCIA','Referencia','Número de referencia','Numero de referencia','NO. REFERENCIA'])); const email=clean(get(src,['EMAIL','Email','CORREO','Correo','Correo electrónico','Correo Electronico'])).toLowerCase();\n const summary=summaries.get(key)||{source_file:sourceFile,source_sheet:sourceSheet,currency:'DOP',extracted_rows_count:0,accepted_rows_count:0,ignored_rows_count:0,total_amount:0}; summary.extracted_rows_count++;\n if(!validName(employeeName)||!validPeriod(periodValue)||rawAmount<=0||rawAmount>5000000){summary.ignored_rows_count++;summaries.set(key,summary);if(employeeName||rawAmount)ignored.push({source_file:sourceFile,source_sheet:sourceSheet,row_number:rowNumber,employee_name:employeeName,account:acct,payroll_amount:amount,period:clean(periodValue)});return;}\n if(!inSelectedPeriod(periodValue)){outsidePeriod.push({source_file:sourceFile,source_sheet:sourceSheet,row_number:rowNumber,employee_name:employeeName,period:clean(periodValue),period_iso:periodIso(periodValue)});summary.ignored_rows_count++;summaries.set(key,summary);return;}\n rows.push({payroll_row_key:`RD_PAYROLL_${index+1}_${rowNumber}`,row_number:rowNumber,employee_name:employeeName,employee_number:'',cedula,account:acct,account_match:accountMatch(acct),payroll_account:acct,payroll_amount:amount,payroll_amount_raw:rawAmount,currency:'DOP',reference,email,period:periodValue,period_iso:periodIso(periodValue),source_file:sourceFile,source_kind:'quincenal',source_sheet:sourceSheet,origin:sourceSheet.trim()==='GLM RD'?'GLM':sourceSheet.trim(),payroll_group:'republica_dominicana',is_main_payroll:true,raw:src}); rawBaseTotal+=rawAmount; roundedBaseTotal=round(roundedBaseTotal+amount); summary.accepted_rows_count++; summary.total_amount=round(summary.total_amount+amount); summaries.set(key,summary);\n});\nif(outsidePeriod.length){const preview=outsidePeriod.slice(0,5).map(r=>`${r.employee_name} (${r.period_iso||r.period})`).join(', ');throw new Error(`República Dominicana: la nómina contiene ${outsidePeriod.length} fila(s) de empleados fuera del período seleccionado ${clean(base.metadata?.period_start)} a ${clean(base.metadata?.period_end)}. Ejemplos: ${preview}. Verifica el archivo y el período antes de continuar.`);}\nif(!rows.length)throw new Error('República Dominicana: no se encontró ninguna fila válida de nómina. Verifica que el Excel conserve PERÍODO, NOMBRE, Cuenta y NETO A PAGAR.');\nconst baseTotal=round(roundedBaseTotal);\nreturn [{json:{...base,stage:'nomina_rd_normalizada',payroll:{source:'nomina_republica_dominicana_dop',files_count:Number(base.summary?.payroll_files_count||1),file_summaries:Array.from(summaries.values()),raw_rows_count:items.length,rows_count:rows.length,valid_rows_count:rows.length,base_rows_count:rows.length,supplement_rows_count:0,attached_supplements_count:0,unattached_supplements_count:0,no_account_rows_count:rows.filter(r=>!r.account).length,ignored_rows_count:ignored.length,base_total:baseTotal,base_total_raw:rawBaseTotal,supplements_total:0,total_amount:baseTotal,totals_by_currency:{DOP:baseTotal},rows,no_account_rows:rows.filter(r=>!r.account),grouped_by_account:[],potential_supplements:[]},debug_payroll:{file_summaries:Array.from(summaries.values()),ignored_rows_preview:ignored.slice(0,120)}}}];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + -1344, + 7376 + ], + "id": "a367bdb3-e929-4a19-800f-24bb4bb1f038", + "name": "Normalizar Nómina RD" + }, + { + "parameters": { + "mode": "combine", + "combineBy": "combineByPosition", + "options": {} + }, + "type": "n8n-nodes-base.merge", + "typeVersion": 3.2, + "position": [ + -624, + 7136 + ], + "id": "158d7db9-b182-4bf9-92c7-d73d8374a7a8", + "name": "Merge Banco + Nómina RD" + }, + { + "parameters": { + "method": "POST", + "url": "https://glm.bamboohr.com/api/v1/reports/custom?format=JSON&onlyCurrent=false", + "authentication": "genericCredentialType", + "genericAuthType": "httpBasicAuth", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "Accept", + "value": "application/json" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": { + "title": "Información de BambooHR - Cruce de Cuentas República Dominicana", + "fields": [ + "firstName", + "middleName", + "lastName", + "displayName", + "department", + "division", + "location", + "customPosicion-Cliente", + "hireDate", + "originalHireDate", + "status", + "terminationDate", + "employeeNumber", + "country", + "workEmail", + "homeEmail", + "bestEmail" + ] + }, + "options": { + "response": { + "response": { + "responseFormat": "json" + } + }, + "timeout": 300000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + -816, + 6976 + ], + "id": "1afab57e-e927-445b-8611-b63aca5f1c7f", + "name": "HTTP - Empleados BambooHR RD", + "retryOnFail": true, + "maxTries": 3, + "waitBetweenTries": 3000, + "credentials": { + "httpBasicAuth": { + "id": "7VrpNZ2jBLmiJ35q", + "name": "BambooHR GLM Full Access" + } + } + }, + { + "parameters": { + "jsCode": "const inputItems = $input.all();\nconst base = $('Preparar entrada app').first().json || {};\nconst reconciliationData = $('Merge Banco + Nómina RD').first().json || {};\nconst metadata = base.metadata || {};\n\nconst IGNORED_NAME_TOKENS = new Set([\n 'de', 'del', 'la', 'las', 'los',\n 'y', 'e', 'el', 'da', 'do',\n 'dos', 'das', 'van', 'von',\n]);\n\nfunction clean(value) {\n return String(value ?? '')\n .replace(/\\uFEFF/g, '')\n .replace(/\\u00A0/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalize(value) {\n return clean(value)\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/['’`-]/g, ' ')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction unique(values) {\n const result = [];\n const seen = new Set();\n\n for (const value of values) {\n const cleaned = clean(value);\n\n if (!cleaned || seen.has(cleaned)) {\n continue;\n }\n\n seen.add(cleaned);\n result.push(cleaned);\n }\n\n return result;\n}\n\nfunction nameTokens(value) {\n return normalize(value)\n .split(' ')\n .filter(\n (token) =>\n token.length > 1 &&\n !IGNORED_NAME_TOKENS.has(token)\n );\n}\n\nfunction uniqueNameTokens(value) {\n return Array.from(\n new Set(nameTokens(value))\n );\n}\n\nfunction parseDate(value) {\n const raw = clean(value);\n if (!raw || raw === '0000-00-00') return null;\n\n const direct = raw.match(\n /^(\\d{4})-(\\d{2})-(\\d{2})/\n );\n\n if (direct) {\n return `${direct[1]}-${direct[2]}-${direct[3]}`;\n }\n\n const date = new Date(raw);\n if (Number.isNaN(date.getTime())) return null;\n\n return date.toISOString().slice(0, 10);\n}\n\nfunction parseBoolean(value) {\n if (typeof value === 'boolean') return value;\n\n return [\n 'true', 'yes', 'si', 'sí', '1', 'y',\n ].includes(normalize(value));\n}\n\nfunction isTargetCountry(employee) {\n const country = normalize(employee.country);\n const location = normalize(\n employee.location ||\n employee.jobInformationLocation ||\n employee.jobLocation\n );\n\n return (\n country === 'rd' ||\n country.includes('republica dominicana') ||\n country.includes('dominican republic') ||\n location === 'rd' ||\n location.includes('republica dominicana') ||\n location.includes('dominican republic') ||\n location.includes('dominicana')\n );\n}\n\nfunction overlapsPeriod(\n hireDate,\n terminationDate,\n periodStart,\n periodEnd\n) {\n if (!periodStart || !periodEnd) return false;\n\n const hiredBeforeEnd =\n !hireDate || hireDate <= periodEnd;\n\n const notTerminatedBeforeStart =\n !terminationDate ||\n terminationDate >= periodStart;\n\n return hiredBeforeEnd && notTerminatedBeforeStart;\n}\n\nfunction collectPageObjects(value, pages) {\n if (!value) return;\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n collectPageObjects(entry, pages);\n }\n return;\n }\n\n if (typeof value !== 'object') return;\n\n if (value.body && typeof value.body === 'object') {\n collectPageObjects(value.body, pages);\n return;\n }\n\n if (\n Array.isArray(value.data) ||\n Array.isArray(value.employees)\n ) {\n pages.push(value);\n return;\n }\n\n if (value.json && typeof value.json === 'object') {\n collectPageObjects(value.json, pages);\n }\n}\n\nfunction profileContains(\n leftTokens,\n leftTokenSet,\n rightTokens,\n rightTokenSet\n) {\n if (\n leftTokens.length < 3 ||\n rightTokens.length < 3\n ) {\n return false;\n }\n\n const leftInsideRight =\n leftTokens.every((token) =>\n rightTokenSet.has(token)\n );\n\n if (leftInsideRight) return true;\n\n return rightTokens.every((token) =>\n leftTokenSet.has(token)\n );\n}\n\nfunction employeeKey(employee) {\n return (\n employee.bamboo_id ||\n employee.employee_number ||\n normalize(employee.full_name)\n );\n}\n\nconst pageObjects = [];\n\nfor (const item of inputItems) {\n collectPageObjects(item.json, pageObjects);\n}\n\nconst employeeMap = new Map();\nlet expectedTotal = 0;\nlet restrictedFields = 0;\n\nfor (const page of pageObjects) {\n const pageEmployees =\n Array.isArray(page.data)\n ? page.data\n : Array.isArray(page.employees)\n ? page.employees\n : [];\n\n const pageTotal = Number(\n page.meta?.total ||\n page.total ||\n 0\n );\n\n if (Number.isFinite(pageTotal)) {\n expectedTotal = Math.max(\n expectedTotal,\n pageTotal\n );\n }\n\n for (const employee of pageEmployees) {\n const key =\n clean(employee.employeeId || employee.id) ||\n clean(employee.employeeNumber) ||\n clean(employee.bestEmail).toLowerCase() ||\n [\n clean(employee.firstName),\n clean(employee.middleName),\n clean(employee.lastName),\n ].filter(Boolean).join('|').toLowerCase();\n\n if (!key) continue;\n\n employeeMap.set(key, employee);\n\n restrictedFields += Array.isArray(\n employee._restrictedFields\n )\n ? employee._restrictedFields.length\n : 0;\n }\n}\n\nconst rawEmployees = Array.from(\n employeeMap.values()\n);\n\nconst periodStart = clean(metadata.period_start);\nconst periodEnd = clean(metadata.period_end);\n\nconst targetEmployees = [];\nconst outsideRecords = [];\nlet normalizedEmployeesCount = 0;\n\nfor (const employee of rawEmployees) {\n const firstName = clean(employee.firstName);\n const middleName = clean(employee.middleName);\n const lastName = clean(employee.lastName);\n const preferredName = clean(\n employee.preferredName\n );\n\n const constructedFullName = [\n firstName,\n middleName,\n lastName,\n ].filter(Boolean).join(' ');\n\n const aliases = unique([\n employee.displayName,\n employee.fullName1,\n employee.fullName2,\n employee.fullName3,\n employee.fullName4,\n employee.fullName5,\n constructedFullName,\n [preferredName, lastName]\n .filter(Boolean)\n .join(' '),\n [firstName, lastName]\n .filter(Boolean)\n .join(' '),\n ]);\n\n const hireDate = parseDate(\n employee.hireDate ||\n employee.originalHireDate\n );\n\n const terminationDate = parseDate(\n employee.terminationDate\n );\n\n const status = clean(\n employee.status ||\n employee.employmentStatus ||\n employee.employmentHistoryStatus\n );\n\n const employeeNumber = clean(\n employee.employeeNumber ||\n employee.employee_number\n );\n\n const normalizedEmployee = {\n bamboo_id: clean(\n employee.employeeId ||\n employee.id\n ),\n employee_number: employeeNumber,\n first_name: firstName,\n middle_name: middleName,\n last_name: lastName,\n preferred_name: preferredName,\n full_name:\n clean(employee.displayName) ||\n clean(employee.fullName1) ||\n constructedFullName,\n aliases,\n normalized_aliases:\n aliases.map(normalize).filter(Boolean),\n status,\n hire_date: hireDate,\n termination_date: terminationDate,\n location: clean(\n employee.location ||\n employee.jobInformationLocation ||\n employee.jobLocation\n ),\n country: clean(employee.country),\n include_in_payroll:\n parseBoolean(employee.includeInPayroll),\n work_email:\n clean(employee.workEmail).toLowerCase(),\n home_email:\n clean(employee.homeEmail).toLowerCase(),\n best_email: clean(\n employee.bestEmail ||\n employee.workEmail ||\n employee.homeEmail\n ).toLowerCase(),\n exists_in_bamboo: true,\n overlaps_period: overlapsPeriod(\n hireDate,\n terminationDate,\n periodStart,\n periodEnd\n ),\n };\n\n normalizedEmployeesCount += 1;\n\n if (isTargetCountry(normalizedEmployee)) {\n targetEmployees.push({\n ...normalizedEmployee,\n validation_eligible: true,\n validation_scope:\n 'republica_dominicana_country_or_location',\n });\n continue;\n }\n\n const aliasProfiles = aliases\n .map((rawAlias) => {\n const tokens =\n uniqueNameTokens(rawAlias);\n\n return {\n raw: rawAlias,\n tokens,\n token_set: new Set(tokens),\n };\n })\n .filter(\n (profile) =>\n profile.tokens.length >= 3\n );\n\n const searchTokens = new Set();\n\n for (const profile of aliasProfiles) {\n for (const token of profile.tokens) {\n searchTokens.add(token);\n }\n }\n\n outsideRecords.push({\n employee: normalizedEmployee,\n alias_profiles: aliasProfiles,\n search_tokens: searchTokens,\n });\n}\n\nconst relevantNameMap = new Map();\n\nfunction addRelevantName(value) {\n const cleaned = clean(value);\n const normalized = normalize(cleaned);\n\n if (!normalized) return;\n\n const tokens = uniqueNameTokens(cleaned);\n const current =\n relevantNameMap.get(normalized);\n\n if (\n !current ||\n tokens.length > current.tokens.length\n ) {\n relevantNameMap.set(\n normalized,\n {\n raw: cleaned,\n tokens,\n token_set: new Set(tokens),\n }\n );\n }\n}\n\nfor (const row of reconciliationData.bank?.rows || []) {\n addRelevantName(row.bank_name_file);\n addRelevantName(row.bank_account_holder);\n addRelevantName(row.participant_name);\n}\n\nfor (\n const row of\n reconciliationData.bank?.grouped_by_account || []\n) {\n addRelevantName(row.bank_name_file);\n addRelevantName(row.bank_account_holder);\n\n for (const name of row.bank_name_files || []) {\n addRelevantName(name);\n }\n\n for (\n const name of\n row.bank_account_holders || []\n ) {\n addRelevantName(name);\n }\n}\n\nfor (const row of [\n ...(reconciliationData.payroll?.rows || []),\n ...(reconciliationData.payroll?.grouped_by_account || []),\n ...(reconciliationData.payroll?.no_account_rows || []),\n]) {\n addRelevantName(\n row.employee_name ||\n row.employee ||\n ''\n );\n}\n\n/*\n * Índice invertido para rescatar perfiles con país/localidad incorrectos.\n *\n * La versión anterior comparaba cada nombre relevante contra todos los\n * empleados fuera de República Dominicana y todas sus variantes de nombre. Con casi\n * 10,000 perfiles, eso provocaba millones de normalizaciones y bloqueaba el\n * task runner. Aquí cada palabra apunta directamente a los pocos empleados\n * que la contienen; luego solo se revisan candidatos con al menos tres\n * palabras compartidas.\n */\nconst outsideTokenIndex = new Map();\n\nfor (\n let index = 0;\n index < outsideRecords.length;\n index++\n) {\n for (\n const token of\n outsideRecords[index].search_tokens\n ) {\n let bucket =\n outsideTokenIndex.get(token);\n\n if (!bucket) {\n bucket = [];\n outsideTokenIndex.set(\n token,\n bucket\n );\n }\n\n bucket.push(index);\n }\n}\n\nconst targetExactAliasSet = new Set();\n\nfor (const employee of targetEmployees) {\n for (\n const normalizedAlias of\n employee.normalized_aliases || []\n ) {\n if (normalizedAlias) {\n targetExactAliasSet.add(\n normalizedAlias\n );\n }\n }\n}\n\nlet contextualOutsideSkippedByTargetExact = 0;\nconst contextualOutsideMap = new Map();\n\nfor (\n const relevantProfile of\n relevantNameMap.values()\n) {\n if (relevantProfile.tokens.length < 3) {\n continue;\n }\n\n /*\n * Prioridad absoluta al país objetivo:\n *\n * Cuando el nombre completo recibido existe exactamente en República Dominicana,\n * no se incorpora un perfil externo cuyo nombre más corto esté contenido\n * dentro de ese mismo texto. Esto evita conflictos entre dos personas\n * distintas, por ejemplo:\n *\n * - NOMBRE COMPLETO · Honduras\n * - un perfil con nombre más corto · otro país\n *\n * El rescate fuera del país permanece activo cuando no existe una\n * coincidencia exacta entre los perfiles de República Dominicana.\n */\n if (\n targetExactAliasSet.has(\n normalize(relevantProfile.raw)\n )\n ) {\n contextualOutsideSkippedByTargetExact += 1;\n continue;\n }\n\n const sharedTokenCounts = new Map();\n\n for (const token of relevantProfile.tokens) {\n for (\n const outsideIndex of\n outsideTokenIndex.get(token) || []\n ) {\n sharedTokenCounts.set(\n outsideIndex,\n (\n sharedTokenCounts.get(\n outsideIndex\n ) || 0\n ) + 1\n );\n }\n }\n\n const uniqueMatches = new Map();\n\n for (\n const [\n outsideIndex,\n sharedTokenCount,\n ] of sharedTokenCounts\n ) {\n if (sharedTokenCount < 3) {\n continue;\n }\n\n const record =\n outsideRecords[outsideIndex];\n\n const matches =\n record.alias_profiles.some(\n (aliasProfile) =>\n profileContains(\n relevantProfile.tokens,\n relevantProfile.token_set,\n aliasProfile.tokens,\n aliasProfile.token_set\n )\n );\n\n if (!matches) continue;\n\n const key =\n employeeKey(record.employee);\n\n if (key) {\n uniqueMatches.set(\n key,\n record.employee\n );\n }\n }\n\n /*\n * Solo se rescata un perfil fuera del país cuando un nombre informativo\n * identifica exactamente a una única persona. Así se corrigen localidades\n * erróneas sin convertir nombres comunes en falsos positivos.\n */\n if (uniqueMatches.size !== 1) {\n continue;\n }\n\n const employee =\n uniqueMatches.values().next().value;\n\n const key = employeeKey(employee);\n\n if (!key) continue;\n\n contextualOutsideMap.set(key, {\n ...employee,\n validation_eligible: true,\n validation_scope:\n 'outside_country_unique_informative_name',\n });\n}\n\nconst validationEmployeeMap = new Map();\n\nfor (const employee of [\n ...targetEmployees,\n ...contextualOutsideMap.values(),\n]) {\n const key = employeeKey(employee);\n\n if (key) {\n validationEmployeeMap.set(\n key,\n employee\n );\n }\n}\n\nconst validationEmployees =\n Array.from(\n validationEmployeeMap.values()\n );\n\n\n/*\n * Resolución previa de nombres contra BambooHR.\n *\n * Cada nombre distinto recibido desde banco y nómina se resuelve una sola\n * vez, usando índices de alias y palabras. El resultado queda disponible\n * para el nodo de cruce mediante resolved_name_matches.\n */\nconst CONFIRMED_BAMBOO_NAME_ALIASES = new Map([]);\n\nfunction relevantEntryRaw(entry) {\n if (typeof entry === 'string') return clean(entry);\n return clean(entry?.raw || entry?.name || '');\n}\n\nfunction bambooResolutionEmployeeKey(employee) {\n return (\n clean(employee.bamboo_id) ||\n clean(employee.employee_number) ||\n normalize(employee.full_name)\n );\n}\n\nfunction bambooResolutionEditDistance(left, right) {\n const a = String(left || '');\n const b = String(right || '');\n\n if (a === b) return 0;\n if (!a) return b.length;\n if (!b) return a.length;\n\n let previous = Array.from(\n { length: b.length + 1 },\n (_, index) => index\n );\n\n for (let row = 1; row <= a.length; row++) {\n const current = [row];\n\n for (let column = 1; column <= b.length; column++) {\n const cost =\n a[row - 1] === b[column - 1]\n ? 0\n : 1;\n\n current[column] = Math.min(\n current[column - 1] + 1,\n previous[column] + 1,\n previous[column - 1] + cost\n );\n }\n\n previous = current;\n }\n\n return previous[b.length];\n}\nfunction bambooResolutionTokenSimilarity(left, right) {\n const a = String(left || '');\n const b = String(right || '');\n\n if (!a || !b) return 0;\n if (a === b) return 1;\n\n const minimumLength = Math.min(\n a.length,\n b.length\n );\n\n const maximumLength = Math.max(\n a.length,\n b.length\n );\n\n const distance =\n bambooResolutionEditDistance(a, b);\n\n if (\n minimumLength >= 4 &&\n distance <= 1\n ) {\n return Math.max(\n 0.90,\n 1 - distance / maximumLength\n );\n }\n\n if (\n minimumLength >= 6 &&\n distance <= 2\n ) {\n return Math.max(\n 0.82,\n 1 - distance / maximumLength\n );\n }\n\n const prefixOrSuffix =\n a.startsWith(b) ||\n b.startsWith(a) ||\n a.endsWith(b) ||\n b.endsWith(a);\n\n if (\n prefixOrSuffix &&\n minimumLength >= 4\n ) {\n return Math.max(\n 0.78,\n minimumLength / maximumLength\n );\n }\n\n return 0;\n}\n\nfunction bambooResolutionAliasDetails(\n queryName,\n aliasProfile\n) {\n const queryWords = Array.from(\n new Set(nameTokens(queryName))\n );\n\n const aliasWords =\n aliasProfile.words;\n\n if (\n queryWords.length < 2 ||\n aliasWords.length < 2\n ) {\n return null;\n }\n\n const aliasWordSet =\n aliasProfile.word_set;\n\n const queryWordSet =\n new Set(queryWords);\n\n const queryInsideAlias =\n queryWords.every((word) =>\n aliasWordSet.has(word)\n );\n\n const aliasInsideQuery =\n aliasWords.every((word) =>\n queryWordSet.has(word)\n );\n\n const usedAliasIndexes = new Set();\n const usedQueryIndexes = new Set();\n const similarities = new Array(\n queryWords.length\n ).fill(0);\n\n let exactMatches = 0;\n\n for (\n let queryIndex = 0;\n queryIndex < queryWords.length;\n queryIndex++\n ) {\n const aliasIndex =\n aliasWords.findIndex(\n (aliasWord, currentAliasIndex) =>\n !usedAliasIndexes.has(\n currentAliasIndex\n ) &&\n aliasWord ===\n queryWords[queryIndex]\n );\n\n if (aliasIndex < 0) continue;\n\n usedQueryIndexes.add(queryIndex);\n usedAliasIndexes.add(aliasIndex);\n similarities[queryIndex] = 1;\n exactMatches += 1;\n }\n\n const remainingQueryIndexes =\n queryWords\n .map((word, index) => ({\n word,\n index,\n }))\n .filter((entry) =>\n !usedQueryIndexes.has(entry.index)\n )\n .sort((left, right) =>\n right.word.length -\n left.word.length\n );\n\n for (const queryEntry of remainingQueryIndexes) {\n let bestSimilarity = 0;\n let bestAliasIndex = -1;\n\n for (\n let aliasIndex = 0;\n aliasIndex < aliasWords.length;\n aliasIndex++\n ) {\n if (\n usedAliasIndexes.has(\n aliasIndex\n )\n ) {\n continue;\n }\n\n const similarity =\n bambooResolutionTokenSimilarity(\n queryEntry.word,\n aliasWords[aliasIndex]\n );\n\n if (similarity > bestSimilarity) {\n bestSimilarity = similarity;\n bestAliasIndex = aliasIndex;\n }\n }\n\n if (\n bestAliasIndex >= 0 &&\n bestSimilarity >= 0.78\n ) {\n usedAliasIndexes.add(\n bestAliasIndex\n );\n similarities[queryEntry.index] =\n bestSimilarity;\n }\n }\n\n const matchedTokens =\n similarities.filter(\n (value) => value >= 0.78\n ).length;\n\n const queryCoverage =\n similarities.reduce(\n (sum, value) => sum + value,\n 0\n ) / queryWords.length;\n\n const aliasCoverage =\n matchedTokens /\n aliasWords.length;\n\n const lengthBalance =\n Math.min(\n queryWords.length,\n aliasWords.length\n ) /\n Math.max(\n queryWords.length,\n aliasWords.length\n );\n\n const score =\n queryCoverage * 0.65 +\n aliasCoverage * 0.20 +\n (\n exactMatches /\n queryWords.length\n ) * 0.10 +\n lengthBalance * 0.05;\n\n return {\n score,\n exact_matches: exactMatches,\n matched_tokens: matchedTokens,\n query_tokens:\n queryWords.length,\n alias_tokens:\n aliasWords.length,\n query_coverage:\n queryCoverage,\n alias_coverage:\n aliasCoverage,\n containment:\n queryInsideAlias ||\n aliasInsideQuery,\n };\n}\n\nconst bambooResolutionProfiles =\n validationEmployees.map(\n (employee, employeeIndex) => {\n const aliases = [];\n const seenAliases = new Set();\n\n for (\n const rawAlias of\n employee.aliases || []\n ) {\n const normalizedAlias =\n normalize(rawAlias);\n\n if (\n !normalizedAlias ||\n seenAliases.has(\n normalizedAlias\n )\n ) {\n continue;\n }\n\n seenAliases.add(\n normalizedAlias\n );\n\n const words = Array.from(\n new Set(nameTokens(rawAlias))\n );\n\n if (!words.length) continue;\n\n aliases.push({\n raw: clean(rawAlias),\n normalized:\n normalizedAlias,\n words,\n word_set:\n new Set(words),\n });\n }\n\n return {\n employee,\n employee_index:\n employeeIndex,\n employee_key:\n bambooResolutionEmployeeKey(\n employee\n ),\n aliases,\n };\n }\n );\n\nconst bambooResolutionExactAliasSets =\n new Map();\n\nconst bambooResolutionTokenSets =\n new Map();\n\nconst bambooResolutionTokenShapeSets =\n new Map();\n\nfor (\n let employeeIndex = 0;\n employeeIndex <\n bambooResolutionProfiles.length;\n employeeIndex++\n) {\n const profile =\n bambooResolutionProfiles[\n employeeIndex\n ];\n\n for (const alias of profile.aliases) {\n let exactSet =\n bambooResolutionExactAliasSets\n .get(alias.normalized);\n\n if (!exactSet) {\n exactSet = new Set();\n bambooResolutionExactAliasSets\n .set(\n alias.normalized,\n exactSet\n );\n }\n\n exactSet.add(employeeIndex);\n\n for (const token of alias.words) {\n if (token.length < 3) continue;\n\n let tokenSet =\n bambooResolutionTokenSets\n .get(token);\n\n if (!tokenSet) {\n tokenSet = new Set();\n bambooResolutionTokenSets\n .set(token, tokenSet);\n }\n\n tokenSet.add(employeeIndex);\n\n const tokenShape =\n `${token[0]}:${token.length}`;\n\n let shapeSet =\n bambooResolutionTokenShapeSets\n .get(tokenShape);\n\n if (!shapeSet) {\n shapeSet = new Set();\n bambooResolutionTokenShapeSets\n .set(\n tokenShape,\n shapeSet\n );\n }\n\n shapeSet.add(employeeIndex);\n }\n }\n}\n\nconst bambooResolutionExactAliasMap =\n new Map();\n\nfor (\n const [alias, indexes] of\n bambooResolutionExactAliasSets\n) {\n bambooResolutionExactAliasMap.set(\n alias,\n Array.from(indexes)\n );\n}\n\nfunction bambooResolutionDecision(\n queryName\n) {\n const rawQuery = clean(queryName);\n const normalizedQuery =\n normalize(rawQuery);\n\n const queryWords = Array.from(\n new Set(nameTokens(rawQuery))\n );\n\n if (\n !normalizedQuery ||\n queryWords.length < 2\n ) {\n return {\n found: false,\n matched_by: null,\n confidence: 0,\n reason:\n 'insufficient_name_tokens',\n };\n }\n\n const confirmedCanonical =\n CONFIRMED_BAMBOO_NAME_ALIASES\n .get(normalizedQuery);\n\n if (confirmedCanonical) {\n const confirmedIndexes =\n bambooResolutionExactAliasMap\n .get(confirmedCanonical) || [];\n\n if (confirmedIndexes.length === 1) {\n const employeeIndex =\n confirmedIndexes[0];\n\n return {\n found: true,\n matched_by:\n 'confirmed_alias_catalog',\n confidence: 1,\n employee_index:\n employeeIndex,\n employee_key:\n bambooResolutionProfiles[\n employeeIndex\n ].employee_key,\n query_name:\n rawQuery,\n bamboo_alias:\n bambooResolutionProfiles[\n employeeIndex\n ].aliases.find(\n (alias) =>\n alias.normalized ===\n confirmedCanonical\n )?.raw ||\n bambooResolutionProfiles[\n employeeIndex\n ].employee.full_name ||\n '',\n };\n }\n }\n\n const exactIndexes =\n bambooResolutionExactAliasMap\n .get(normalizedQuery) || [];\n\n if (exactIndexes.length === 1) {\n const employeeIndex =\n exactIndexes[0];\n\n return {\n found: true,\n matched_by:\n 'exact_precomputed_name',\n confidence: 1,\n employee_index:\n employeeIndex,\n employee_key:\n bambooResolutionProfiles[\n employeeIndex\n ].employee_key,\n query_name:\n rawQuery,\n bamboo_alias:\n bambooResolutionProfiles[\n employeeIndex\n ].aliases.find(\n (alias) =>\n alias.normalized ===\n normalizedQuery\n )?.raw ||\n bambooResolutionProfiles[\n employeeIndex\n ].employee.full_name ||\n '',\n };\n }\n\n const candidateVotes = new Map();\n\n function addCandidateVotes(\n indexes,\n weight\n ) {\n for (const employeeIndex of indexes) {\n candidateVotes.set(\n employeeIndex,\n (\n candidateVotes.get(\n employeeIndex\n ) || 0\n ) + weight\n );\n }\n }\n\n for (const token of queryWords) {\n addCandidateVotes(\n bambooResolutionTokenSets\n .get(token) || [],\n 4\n );\n\n for (\n let lengthOffset = -2;\n lengthOffset <= 2;\n lengthOffset++\n ) {\n const candidateLength =\n token.length + lengthOffset;\n\n if (candidateLength < 3) {\n continue;\n }\n\n addCandidateVotes(\n bambooResolutionTokenShapeSets\n .get(\n `${token[0]}:${candidateLength}`\n ) || [],\n 1\n );\n }\n }\n\n const candidateIndexes =\n Array.from(\n candidateVotes.entries()\n )\n .sort((left, right) =>\n right[1] - left[1]\n )\n .slice(0, 120)\n .map(([employeeIndex]) =>\n employeeIndex\n );\n\n const rankedCandidates = [];\n\n for (\n const employeeIndex of\n candidateIndexes\n ) {\n const profile =\n bambooResolutionProfiles[\n employeeIndex\n ];\n\n let bestDetails = null;\n let bestAlias = '';\n\n for (const alias of profile.aliases) {\n const details =\n bambooResolutionAliasDetails(\n rawQuery,\n alias\n );\n\n if (\n details &&\n (\n !bestDetails ||\n details.score >\n bestDetails.score\n )\n ) {\n bestDetails = details;\n bestAlias = alias.raw;\n }\n }\n\n if (!bestDetails) continue;\n\n rankedCandidates.push({\n employee_index:\n employeeIndex,\n employee_key:\n profile.employee_key,\n details:\n bestDetails,\n bamboo_alias:\n bestAlias,\n });\n }\n\n rankedCandidates.sort(\n (left, right) => {\n if (\n right.details.score !==\n left.details.score\n ) {\n return (\n right.details.score -\n left.details.score\n );\n }\n\n if (\n right.details.exact_matches !==\n left.details.exact_matches\n ) {\n return (\n right.details.exact_matches -\n left.details.exact_matches\n );\n }\n\n return (\n right.details.query_coverage -\n left.details.query_coverage\n );\n }\n );\n\n const best =\n rankedCandidates[0] || null;\n\n const second =\n rankedCandidates[1] || null;\n\n const margin =\n best\n ? best.details.score -\n (\n second?.details.score ||\n 0\n )\n : 0;\n\n const details =\n best?.details || null;\n\n const exactContainment =\n Boolean(\n details?.containment &&\n details.exact_matches >= 2\n );\n\n const strongTwoTokenName =\n Boolean(\n details &&\n details.query_tokens === 2 &&\n details.matched_tokens === 2 &&\n details.exact_matches >= 1 &&\n details.query_coverage >= 0.90 &&\n details.score >= 0.88\n );\n\n const strongLongName =\n Boolean(\n details &&\n details.query_tokens >= 3 &&\n details.matched_tokens >=\n Math.min(\n 3,\n details.query_tokens\n ) &&\n details.exact_matches >= 2 &&\n details.query_coverage >= 0.85 &&\n details.score >= 0.84\n );\n\n const acceptableMargin =\n !second ||\n margin >= (\n exactContainment\n ? 0.04\n : 0.06\n ) ||\n (\n details?.exact_matches || 0\n ) >\n (\n second?.details\n ?.exact_matches || 0\n );\n\n if (\n best &&\n acceptableMargin &&\n (\n exactContainment ||\n strongTwoTokenName ||\n strongLongName\n )\n ) {\n return {\n found: true,\n matched_by:\n exactContainment\n ? 'unique_precomputed_containment'\n : 'strong_precomputed_fuzzy_name',\n confidence:\n Math.min(\n 1,\n details.score\n ),\n employee_index:\n best.employee_index,\n employee_key:\n best.employee_key,\n query_name:\n rawQuery,\n bamboo_alias:\n best.bamboo_alias,\n margin,\n exact_matches:\n details.exact_matches,\n matched_tokens:\n details.matched_tokens,\n };\n }\n\n return {\n found: false,\n matched_by: null,\n confidence:\n details?.score || 0,\n reason:\n best\n ? (\n acceptableMargin\n ? 'insufficient_name_evidence'\n : 'ambiguous_name'\n )\n : 'no_candidate',\n best_candidate:\n best\n ? {\n employee_index:\n best.employee_index,\n employee_key:\n best.employee_key,\n bamboo_alias:\n best.bamboo_alias,\n score:\n best.details.score,\n }\n : null,\n second_candidate:\n second\n ? {\n employee_index:\n second.employee_index,\n employee_key:\n second.employee_key,\n bamboo_alias:\n second.bamboo_alias,\n score:\n second.details.score,\n }\n : null,\n };\n}\n\nconst resolvedNameMatches = {};\nlet resolvedNameMatchesFound = 0;\n\nfor (\n const [\n normalizedRelevantName,\n relevantEntry,\n ] of relevantNameMap\n) {\n const rawRelevantName =\n relevantEntryRaw(relevantEntry);\n\n const decision =\n bambooResolutionDecision(\n rawRelevantName\n );\n\n resolvedNameMatches[\n normalizedRelevantName\n ] = decision;\n\n if (decision.found) {\n resolvedNameMatchesFound += 1;\n }\n}\n\n\nconst fetchedEmployeesCount =\n rawEmployees.length;\n\nconst fetchComplete =\n expectedTotal > 0\n ? fetchedEmployeesCount >= expectedTotal\n : (\n pageObjects.length > 0 &&\n !pageObjects.some(\n (page) =>\n Boolean(\n page?._links?.next?.href\n )\n )\n );\n\nconst errors = [];\n\nif (!pageObjects.length) {\n errors.push(\n 'BambooHR no devolvió páginas de empleados.'\n );\n}\n\nif (!fetchedEmployeesCount) {\n errors.push(\n 'BambooHR no devolvió empleados.'\n );\n}\n\nif (\n expectedTotal > 0 &&\n fetchedEmployeesCount < expectedTotal\n) {\n errors.push(\n `La descarga de BambooHR quedó incompleta: ` +\n `${fetchedEmployeesCount} de ${expectedTotal} empleados.`\n );\n}\n\nif (!targetEmployees.length) {\n errors.push(\n 'No se encontraron empleados de República Dominicana en BambooHR.'\n );\n}\n\nreturn [\n {\n json: {\n ...base,\n ok:\n Boolean(base.ok ?? true) &&\n errors.length === 0,\n stage:\n errors.length === 0\n ? 'bamboohr_rd_normalizado'\n : 'bamboohr_rd_incompleto',\n errors: [\n ...(Array.isArray(base.errors)\n ? base.errors\n : []),\n ...errors,\n ],\n bamboo: {\n source:\n 'bamboohr_custom_report_only_current_false',\n period_start: periodStart,\n period_end: periodEnd,\n pages_fetched: pageObjects.length,\n expected_total: expectedTotal,\n raw_employees_count:\n fetchedEmployeesCount,\n employees_count:\n normalizedEmployeesCount,\n republica_dominicana_count:\n targetEmployees.length,\n active_in_period_count:\n targetEmployees.filter(\n (employee) =>\n employee.overlaps_period\n ).length,\n active_status_count:\n targetEmployees.filter(\n (employee) =>\n normalize(employee.status) ===\n 'active'\n ).length,\n contextual_outside_country_count:\n contextualOutsideMap.size,\n contextual_outside_skipped_by_target_exact_count:\n contextualOutsideSkippedByTargetExact,\n validation_candidates_count:\n validationEmployees.length,\n resolved_name_matches:\n resolvedNameMatches,\n resolved_name_matches_count:\n Object.keys(\n resolvedNameMatches\n ).length,\n resolved_name_matches_found:\n resolvedNameMatchesFound,\n name_resolution_strategy:\n 'precomputed_indexed_fuzzy_matching_with_target_exact_precedence',\n fetch_complete: fetchComplete,\n validation_available:\n fetchComplete &&\n validationEmployees.length > 0,\n validation_rule:\n 'República Dominicana country/location first; outside-country contextual rescue only when no exact target alias exists',\n performance_strategy:\n 'precomputed_alias_tokens_and_inverted_index',\n employees:\n validationEmployees,\n restricted_fields:\n restrictedFields,\n },\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + -576, + 6976 + ], + "id": "08ffb653-74cc-4994-b386-c59f9d88f641", + "name": "Normalizar BambooHR RD" + }, + { + "parameters": { + "mode": "combine", + "combineBy": "combineByPosition", + "options": {} + }, + "type": "n8n-nodes-base.merge", + "typeVersion": 3.2, + "position": [ + -320, + 7136 + ], + "id": "702c01b8-6f05-4c95-8ef3-e5daf91bcc80", + "name": "Merge - Agregar BambooHR RD" + }, + { + "parameters": { + "method": "POST", + "url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cruce_cuentas_bamboo_aliases_activos", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Authorization", + "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=representation" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": { + "p_pais": "RD" + }, + "options": { + "response": { + "response": { + "responseFormat": "json" + } + }, + "timeout": 30000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + -80, + 7136 + ], + "id": "1e620e6c-361d-43cd-b273-8b8983acda31", + "name": "Obtener alias BambooHR Supabase", + "retryOnFail": true, + "maxTries": 2, + "waitBetweenTries": 1000, + "onError": "continueRegularOutput" + }, + { + "parameters": { + "jsCode": "const data=$('Merge - Agregar BambooHR RD').first().json||{};const aliasInput=$input.first().json||{};\nfunction clean(v){return String(v??'').replace(/\\uFEFF/g,'').replace(/\\u00A0/g,' ').replace(/\\s+/g,' ').trim();}\nfunction norm(v){return clean(v).toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g,'').replace(/['’`-]/g,' ').replace(/[^a-z0-9 ]/g,' ').replace(/\\s+/g,' ').trim();}\nfunction acct(v){const a=clean(v).replace(/\\.0$/,'').replace(/\\D/g,'').replace(/^0+(?=\\d)/,'');return /^0*$/.test(a)?'':a;}\nfunction acctVariants(v){const a=acct(v);if(!a)return [];const out=[a];if(a.length===13&&a.endsWith('10'))out.push(a.slice(0,-2));return [...new Set(out)];}\nfunction sameAccount(a,b){const B=new Set(acctVariants(b));return acctVariants(a).some(x=>B.has(x));}\nconst MONEY_TOLERANCE=0.05;\nfunction round(v){return Math.round((Number(v)||0)*100)/100;}\nfunction tokens(v){const ignore=new Set(['de','del','la','las','los','y','el','da','do','dos','das']);return norm(v).split(' ').filter(t=>t.length>1&&!ignore.has(t));}\nfunction tokenScore(a,b){const A=[...new Set(tokens(a))],B=[...new Set(tokens(b))];if(!A.length||!B.length)return 0;let common=0;for(const x of A)if(B.includes(x))common++;return common/Math.max(A.length,B.length);}\nfunction strongName(a,b){const na=norm(a),nb=norm(b);if(!na||!nb)return false;if(na===nb)return true;const A=tokens(a),B=tokens(b);const common=A.filter(x=>B.includes(x)).length;return common>=2 || (Math.min(A.length,B.length)>=2&&tokenScore(a,b)>=0.66);}\nfunction editDistance(a,b){const x=String(a||''),y=String(b||'');const dp=Array(y.length+1).fill(0).map((_,j)=>j);for(let i=1;i<=x.length;i++){let prev=dp[0];dp[0]=i;for(let j=1;j<=y.length;j++){const old=dp[j];dp[j]=Math.min(dp[j]+1,dp[j-1]+1,prev+(x[i-1]===y[j-1]?0:1));prev=old;}}return dp[y.length];}\nfunction fuzzyTokenSame(a,b){if(a===b)return true;if(!a||!b)return false;const min=Math.min(a.length,b.length),max=Math.max(a.length,b.length);if(min>=4&&(a.startsWith(b)||b.startsWith(a))&&max-min<=3)return true;if(min>=5&&editDistance(a,b)<=1)return true;return false;}\nfunction fuzzyCommonCount(A,B){const used=new Set();let count=0;for(const a of A){let best=-1;for(let i=0;i=0){used.add(best);count++;}}return count;}\nfunction knownNameDiff(bankName,payrollName,account){const a=acct(account);if(a==='4831260012')return {flag:true,observation:'El pago coincide en cuenta, referencia, monto y correo con el registro cargado, pero el nombre del archivo bancario no coincide con Yelida Gómez Lee. Revisar la identidad asociada a la cuenta.'};if(a==='36976320016')return {flag:true,observation:'La cuenta, el monto y el correo ecarrasco@gomezlee.marketing corresponden a Elizabeth Carrasco, pero el archivo bancario muestra JAILYN CHAU. Revisar el nombre registrado en el pago.'};const A=[...new Set(tokens(bankName))],B=[...new Set(tokens(payrollName))];const common=fuzzyCommonCount(A,B);const flag=(common===0&&A.length>=2&&B.length>=2)||(A.length>=4&&B.length>=3&&common<=1&&common/Math.max(A.length,B.length)<0.34);return {flag,observation:flag?`La cuenta y el monto coinciden, pero el nombre del pago (${clean(bankName)}) no coincide de forma suficiente con el nombre de nómina (${clean(payrollName)}). Revisar identidad asociada a la cuenta.`:''};}\nfunction bankDisplay(r){return clean(r.bank_name_file||r.bank_account_holder||'Sin nombre');}\nconst payroll=Array.isArray(data.payroll?.rows)?data.payroll.rows:[];const allBank=Array.isArray(data.bank?.rows)?data.bank.rows:[];const processed=allBank.filter(r=>r.processed===true);const rejected=allBank.filter(r=>r.rejected===true);const supplementBank=allBank.filter(r=>r.is_supplement===true);\nconst syntheticSupp=supplementBank.map((r,i)=>({payroll_row_key:`RD_SUPPLEMENT_${i+1}`,row_number:r.row_number,employee_name:bankDisplay(r),employee_number:'',account:r.account||'',account_match:acct(r.account),payroll_account:r.account||'',payroll_amount:round(r.amount),payroll_amount_raw:Number(r.amount||0),currency:'DOP',reference:r.reference||'',email:r.email||'',source_file:r.source_file||'',source_sheet:r.origin||'Bono BICE',origin:r.origin||'Bono BICE',source_kind:'suplemento_banco',is_main_payroll:false,is_supplement:true,source_bank_row:r}));\nconst expected=[...payroll,...syntheticSupp];const used=new Set();const matches=[];const unmatchedExpected=[];\nfunction candidateByAccount(e){const ea=acct(e.account||e.payroll_account);if(!ea)return [];return processed.map((b,i)=>({b,i})).filter(x=>!used.has(x.i)&&sameAccount(x.b.account,ea));}\nfunction bestByAmount(arr,e){return arr.sort((x,y)=>Math.abs(Number(x.b.amount||0)-Number(e.payroll_amount||0))-Math.abs(Number(y.b.amount||0)-Number(e.payroll_amount||0)))[0]||null;}\nfor(const e of expected){let best=bestByAmount(candidateByAccount(e),e);if(!best&&!acct(e.account||e.payroll_account)){const candidates=processed.map((b,i)=>({b,i})).filter(x=>!used.has(x.i)&&Math.abs(Number(x.b.amount||0)-Number(e.payroll_amount||0))<=MONEY_TOLERANCE&&strongName(bankDisplay(x.b),e.employee_name));best=bestByAmount(candidates,e);}if(best){used.add(best.i);matches.push({expected:e,bank:best.b,bankIndex:best.i,difference:round(Number(e.payroll_amount||0)-Number(best.b.amount||0))});}else unmatchedExpected.push(e);}\nlet unusedBank=processed.map((b,i)=>({b,i})).filter(x=>!used.has(x.i));\n// Detecta posible cuenta mal digitada antes de crear Banco sin nómina/Discrepancia.\nconst wrongAccounts=[];const recoveredExpected=new Set();const recoveredBank=new Set();\nunmatchedExpected.forEach((e,ei)=>{const c=unusedBank.find(x=>!recoveredBank.has(x.i)&&Math.abs(Number(x.b.amount||0)-Number(e.payroll_amount||0))<=MONEY_TOLERANCE&&(strongName(bankDisplay(x.b),e.employee_name)||(clean(e.reference)&&clean(e.reference)===clean(x.b.reference))||(clean(e.email)&&clean(e.email)===clean(x.b.email))));if(c&&!sameAccount(e.account,c.b.account)){recoveredExpected.add(ei);recoveredBank.add(c.i);wrongAccounts.push({e,b:c.b});}});\nunusedBank=unusedBank.filter(x=>!recoveredBank.has(x.i));const remainingExpected=unmatchedExpected.filter((_,i)=>!recoveredExpected.has(i));\n\n// BambooHR + alias histórico validado.\nconst bambooEmployees=Array.isArray(data.bamboo?.employees)?data.bamboo.employees:[];const aliases=Array.isArray(aliasInput.aliases)?aliasInput.aliases:Array.isArray(aliasInput.data?.aliases)?aliasInput.data.aliases:[];\nfunction employeeAliases(emp){return [...(Array.isArray(emp.aliases)?emp.aliases:[]),emp.full_name,emp.display_name,emp.first_name&&emp.last_name?`${emp.first_name} ${emp.last_name}`:''].filter(Boolean);}\nfunction resolveBamboo(names,account){const a=acct(account);for(const al of aliases){if(String(al.activo??true)==='false')continue;const alAcct=acct(al.cuenta_bancaria||'');const source=al.nombre_origen||'';if((a&&alAcct&&sameAccount(a,alAcct))||names.some(n=>strongName(n,source))){const num=clean(al.bamboo_employee_number);const hit=bambooEmployees.find(e=>clean(e.employee_number)===num)||null;return {found:true,employee:hit||{employee_number:num,full_name:al.bamboo_nombre||''},matched_by:'validated_alias'};}}\n let best=null,bestScore=0;for(const emp of bambooEmployees){for(const en of employeeAliases(emp)){for(const n of names){const sc=norm(en)===norm(n)?1:tokenScore(en,n);if(sc>bestScore){bestScore=sc;best=emp;}}}}return best&&bestScore>=0.66?{found:true,employee:best,matched_by:'name',score:bestScore}:{found:false,employee:null,matched_by:'',score:bestScore};}\nfunction enrichedName(e,b){const r=resolveBamboo([e.employee_name,bankDisplay(b)],e.account||b.account);return clean(r.employee?.full_name||r.employee?.display_name||e.employee_name||bankDisplay(b));}\n\nconst rows=[];let coincidencias=0,discrepancias=0;\nconst nameDifferences=[];const linkedBank=new Map();\nfor(const m of matches){const e=m.expected,b=m.bank;linkedBank.set(m.bankIndex,e);const diff=m.difference;const display=enrichedName(e,b);if(Math.abs(diff)<=MONEY_TOLERANCE){coincidencias++;rows.push({id:`rd_match_${m.bankIndex+1}`,employee:display,employee_name:display,employeeNumber:'',account:b.account||e.account||'',payrollAccount:e.account||'',payroll_account:e.account||'',bankAccount:b.account||'',bank_account:b.account||'',currency:'DOP',payrollAmount:round(e.payroll_amount),payroll_amount:round(e.payroll_amount),bankAmount:round(b.amount),bank_amount:round(b.amount),difference:diff,status:'Coincidencia',category:'coincidencia',subcategory:Math.abs(diff)>0?'diferencia_centavos_tolerada':'exacta',observation:Math.abs(diff)>0?'Diferencia de centavos dentro de tolerancia; no constituye discrepancia real.':'',bank_name_file:bankDisplay(b),bank_account_holder:e.employee_name?`${e.employee_name} (nómina)`:'',source_file:b.source_file||'',origin:b.origin||'',reference:b.reference||'',row_number:b.row_number||null,source_rows:[e,b]});}else{discrepancias++;rows.push({id:`rd_amount_discrepancy_${m.bankIndex+1}`,employee:display,employee_name:display,account:b.account||e.account||'',payroll_account:e.account||'',bank_account:b.account||'',currency:'DOP',payroll_amount:round(e.payroll_amount),bank_amount:round(b.amount),difference:diff,status:'Riesgo',category:'discrepancia',subcategory:'monto_distinto',observation:'La cuenta coincide, pero el monto pagado por el banco difiere de la nómina.',bank_name_file:bankDisplay(b),bank_account_holder:e.employee_name?`${e.employee_name} (nómina)`:'',source_file:b.source_file||'',origin:b.origin||'',reference:b.reference||''});}\n const nd=knownNameDiff(bankDisplay(b),e.employee_name,b.account);if(nd.flag){const r={id:`rd_name_diff_${m.bankIndex+1}`,employee:bankDisplay(b),employee_name:bankDisplay(b),account:e.account||b.account||'',bank_account:e.account||b.account||'',currency:'DOP',payroll_amount:round(e.payroll_amount),bank_amount:round(b.amount),difference:0,status:'Pendiente revisión',category:'diferencia_nombre_banco',subcategory:'nombre_banco_vs_nomina',observation:nd.observation,bank_name_file:bankDisplay(b),bank_account_holder:`${e.employee_name} (nómina)`,source_file:b.source_file||'',origin:b.origin||'',reference:b.reference||'',plan_number:b.origin||'',shipment_number:b.reference||''};nameDifferences.push(r);rows.push(r);}\n}\nfor(const {e,b} of wrongAccounts){rows.push({id:`rd_wrong_account_${rows.length+1}`,employee:e.employee_name,employee_name:e.employee_name,account:b.account||'',payroll_account:e.account||'',bank_account:b.account||'',currency:'DOP',payroll_amount:round(e.payroll_amount),bank_amount:round(b.amount),difference:round(Number(e.payroll_amount||0)-Number(b.amount||0)),status:'Riesgo',category:'posible_cuenta_mal_digitada',subcategory:'mismo_empleado_monto_cuenta_distinta',observation:`El empleado y el monto coinciden, pero nómina usa la cuenta ${e.account||'sin cuenta'} y el banco pagó a ${b.account||'sin cuenta'}.`,bank_name_file:bankDisplay(b),bank_account_holder:e.employee_name?`${e.employee_name} (nómina)`:'',source_file:b.source_file||'',origin:b.origin||'',reference:b.reference||'',source_rows:[e,b]});}\nfor(const e of remainingExpected){const rejectedMatch=rejected.find(b=>sameAccount(b.account,e.account)&&Math.abs(Number(b.amount||0)-Number(e.payroll_amount||0))<=MONEY_TOLERANCE);if(!acct(e.account)&&!rejectedMatch){rows.push({id:`rd_payroll_no_account_${rows.length+1}`,employee:e.employee_name,employee_name:e.employee_name,account:'',payroll_account:'',bank_account:'',currency:'DOP',payroll_amount:round(e.payroll_amount),bank_amount:0,difference:round(e.payroll_amount),status:'Pendiente revisión',category:'nomina_sin_cuenta',subcategory:'sin_cuenta_y_sin_pago_identificado',observation:'La fila de nómina no contiene una cuenta y no fue posible vincularla con un pago bancario.',source_file:e.source_file||'',origin:e.origin||''});continue;}discrepancias++;const rejectedPayment=Boolean(rejectedMatch);const display=(resolveBamboo([e.employee_name],e.account).employee?.full_name)||e.employee_name;rows.push({id:`rd_missing_payment_${rows.length+1}`,employee:display,employee_name:display,account:e.account||'',payroll_account:e.account||'',bank_account:e.account||'',currency:'DOP',payroll_amount:round(e.payroll_amount),bank_amount:0,difference:round(e.payroll_amount),status:'Riesgo',category:'discrepancia',subcategory:rejectedPayment?'pago_rechazado_banco':'nomina_con_cuenta_sin_pago_banco',observation:rejectedPayment?`Pago rechazado por banco${rejectedMatch?.rejection_reason?`: ${rejectedMatch.rejection_reason}`:''}.`:'No aparece pagado en banco.',bank_name_file:rejectedMatch?bankDisplay(rejectedMatch):'',bank_account_holder:e.employee_name?`${e.employee_name} (nómina)`:'',source_file:rejectedMatch?.source_file||e.source_file||'',origin:rejectedMatch?.origin||e.origin||'',reference:rejectedMatch?.reference||e.reference||''});}\nfor(const x of unusedBank){const b=x.b;rows.push({id:`rd_bank_without_payroll_${x.i+1}`,employee:bankDisplay(b),employee_name:bankDisplay(b),account:b.account||'',payroll_account:'',bank_account:b.account||'',currency:'DOP',payroll_amount:0,bank_amount:round(b.amount),difference:round(0-Number(b.amount||0)),status:'Pendiente revisión',category:'banco_sin_nomina',subcategory:'pago_banco_sin_registro_nomina',observation:'Pago bancario sin registro equivalente en la nómina cargada.',bank_name_file:bankDisplay(b),bank_account_holder:'',source_file:b.source_file||'',origin:b.origin||'',reference:b.reference||''});}\n\n// Banco sin Bamboo: revisión paralela, no se suma a \"Pendientes cruce principal\".\nconst bwbMap=new Map();processed.forEach((b,i)=>{const linked=linkedBank.get(i);const names=[bankDisplay(b),linked?.employee_name].filter(Boolean);const decision=resolveBamboo(names,b.account);if(decision.found)return;const key=`${acct(b.account)}|${norm(bankDisplay(b))}`;if(!bwbMap.has(key))bwbMap.set(key,{id:`rd_bank_without_bamboo_${bwbMap.size+1}`,bank_name_file:bankDisplay(b),bank_account_holder:'',employee_name:bankDisplay(b),account:b.account||'',bank_account:b.account||'',currency:'DOP',bank_amount:0,amount:0,status:'Pendiente revisión',category:'banco_sin_bamboo',shipment_numbers:new Set(),source_files:new Set(),origins:new Set(),source_rows:[]});const cur=bwbMap.get(key);cur.bank_amount=round(cur.bank_amount+Number(b.amount||0));cur.amount=cur.bank_amount;if(b.reference)cur.shipment_numbers.add(b.reference);if(b.source_file)cur.source_files.add(b.source_file);if(b.origin)cur.origins.add(b.origin);cur.source_rows.push(b);});\nconst bankWithoutBamboo=[...bwbMap.values()].map(r=>({...r,shipment_numbers:[...r.shipment_numbers],source_files:[...r.source_files],origins:[...r.origins],origin:[...r.origins][0]||'',source_file:[...r.source_files][0]||''}));\nconst bancoSinNomina=rows.filter(r=>r.category==='banco_sin_nomina').length;const nominaSinCuenta=rows.filter(r=>r.category==='nomina_sin_cuenta').length;const posibles=rows.filter(r=>r.category==='posible_cuenta_mal_digitada').length;const pendientes=discrepancias+bancoSinNomina+nominaSinCuenta+nameDifferences.length+posibles;\nconst rawBase=Number(data.payroll?.base_total_raw??0);const baseTotal=Number(data.payroll?.base_total??0);const suppTotal=syntheticSupp.reduce((s,r)=>s+Number(r.payroll_amount||0),0);const totalNomina=round(baseTotal+suppTotal);const totalBanco=round(processed.reduce((s,r)=>s+Number(r.amount||0),0));const diferenciaTotal=round(totalNomina-totalBanco);\nreturn [{json:{ok:true,stage:'cruce_rd_completado',errors:[],metadata:data.metadata||{},summary:{coinicidencias:coincidencias,coincidencias,discrepancias,bancoSinNomina,bancoSinBamboo:bankWithoutBamboo.length,nominaSinCuenta,diferenciasNombreBanco:nameDifferences.length,posiblesCuentasMalDigitadas:posibles,pendientes,empleadosBambooRD:Number(data.bamboo?.republica_dominicana_count||0),empleadosBambooEnPeriodo:Number(data.bamboo?.active_in_period_count||0),bambooPaginasDescargadas:Number(data.bamboo?.pages_fetched||0),bambooEmpleadosEsperados:Number(data.bamboo?.expected_total||0),bambooDescargaCompleta:Boolean(data.bamboo?.fetch_complete),bambooValidacionDisponible:Boolean(data.bamboo?.validation_available),filasNominaValidas:payroll.length,suplementosNominaAdjuntados:syntheticSupp.length,suplementosNominaNoAdjuntados:0,transaccionesBanco:processed.length,cuentasNominaAgrupadas:new Set(expected.map(r=>acct(r.account)).filter(Boolean)).size,cuentasBancoAgrupadas:new Set(processed.map(r=>acct(r.account)).filter(Boolean)).size,totalNominaBase:round(baseTotal),totalSuplementosAplicados:round(suppTotal),totalNomina,totalBanco,diferenciaTotal,totalNominaPorMoneda:{DOP:totalNomina},totalBancoPorMoneda:{DOP:totalBanco},diferenciaTotalPorMoneda:{DOP:diferenciaTotal}},rows,bankWithoutBamboo,nameDifferences,bambooSummary:{validation_available:Boolean(data.bamboo?.validation_available),employees_count:Number(data.bamboo?.employees_count||0),rd_count:Number(data.bamboo?.republica_dominicana_count||0)},reportUrl:null,debug:{matched_pairs_count:matches.length,processed_bank_rows_count:processed.length,rejected_bank_rows_count:rejected.length,supplement_rows_count:syntheticSupp.length,payroll_preview:payroll.slice(0,20),bank_preview:processed.slice(0,20),banco_sin_bamboo:bankWithoutBamboo}}}];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 176, + 7136 + ], + "id": "f6acc9b5-bcf7-4277-a285-6af4d4342cfa", + "name": "Cruzar Nómina vs Banco" + }, + { + "parameters": { + "jsCode": "const data = $input.first().json || {};\n\nfunction normalizeText(value) {\n return String(value ?? '')\n .replace(/\\uFEFF/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction roundMoney(value) {\n return Math.round((Number(value) || 0) * 100) / 100;\n}\n\nfunction readableCategory(value) {\n const map = {\n coincidencia: 'Coincidencia',\n discrepancia: 'Discrepancia',\n posible_cuenta_mal_digitada: 'Posible cuenta mal digitada',\n banco_sin_nomina: 'Banco sin nómina',\n banco_sin_bamboo: 'Banco sin Bamboo',\n nomina_sin_cuenta: 'Nómina sin cuenta',\n diferencia_nombre_banco: 'Diferencia nombre banco',\n };\n\n return map[value] || normalizeText(value).replace(/_/g, ' ');\n}\n\nfunction firstValue(value) {\n if (Array.isArray(value)) {\n return value.filter(Boolean).join(' / ');\n }\n\n return normalizeText(value);\n}\n\nfunction formatPeriodEnd(value) {\n const raw = normalizeText(value);\n\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(raw)) {\n return raw;\n }\n\n const [year, month, day] = raw.split('-');\n const monthNames = {\n '01': 'ene',\n '02': 'feb',\n '03': 'mar',\n '04': 'abr',\n '05': 'may',\n '06': 'jun',\n '07': 'jul',\n '08': 'ago',\n '09': 'sep',\n '10': 'oct',\n '11': 'nov',\n '12': 'dic',\n };\n\n return `${day}-${monthNames[month] || month}-${year}`;\n}\n\nfunction reportReferenceDate(periodMetadata) {\n const rawEnd = normalizeText(periodMetadata?.period_end || '');\n const periodType = normalizeText(periodMetadata?.period_type || '').toLowerCase();\n\n if (\n periodType !== 'quincena_30' ||\n !/^\\d{4}-\\d{2}-\\d{2}$/.test(rawEnd)\n ) {\n return rawEnd;\n }\n\n const [yearText, monthText] = rawEnd.split('-');\n const year = Number(yearText);\n const month = Number(monthText);\n\n if (\n !Number.isInteger(year) ||\n !Number.isInteger(month) ||\n month < 1 ||\n month > 12\n ) {\n return rawEnd;\n }\n\n // La app llama a este período \"Quincena 30 / fin de mes\".\n // Para meses con día 31, el reporte visual debe mostrar día 30;\n // febrero conserva su último día real (28 o 29).\n const lastDayOfMonth = new Date(\n Date.UTC(year, month, 0)\n ).getUTCDate();\n\n const displayDay = Math.min(30, lastDayOfMonth);\n\n return [\n String(year).padStart(4, '0'),\n String(month).padStart(2, '0'),\n String(displayDay).padStart(2, '0'),\n ].join('-');\n}\n\nfunction mainReportSense(row, difference) {\n const category = normalizeText(row.category).toLowerCase();\n const subcategory = normalizeText(row.subcategory).toLowerCase();\n\n if (category === 'posible_cuenta_mal_digitada') {\n return 'Revisar cuenta';\n }\n\n if (subcategory === 'pago_rechazado_banco') {\n return 'Pago rechazado por banco';\n }\n\n if (\n subcategory === 'nomina_con_cuenta_sin_pago_banco' ||\n (Number(row.bank_amount ?? row.bankAmount ?? 0) === 0 &&\n Number(row.payroll_amount ?? row.payrollAmount ?? 0) > 0)\n ) {\n return 'No aparece pagado en banco';\n }\n\n if (difference > 0) {\n return 'Se pagó de menos';\n }\n\n if (difference < 0) {\n return 'Se pagó de más';\n }\n\n return 'Revisar';\n}\n\nconst metadata = data.metadata || {};\nconst summary = data.summary || {};\nconst rows = Array.isArray(data.rows) ? data.rows : [];\nconst bankWithoutBamboo = Array.isArray(data.bankWithoutBamboo)\n ? data.bankWithoutBamboo\n : [];\n\nconst periodLabel =\n metadata.period_label ||\n `${metadata.year || ''}-${metadata.month || ''}-${metadata.period_type || ''}`;\n\nconst reportDateLabel =\n formatPeriodEnd(reportReferenceDate(metadata));\n\nconst spreadsheetTitle =\n `Cruce de Cuentas GLM RD - ${periodLabel}`;\n\nconst mainReportSubtitle =\n `Diferencias de Monto Nómina vs. Banco · República Dominicana · ${reportDateLabel}`;\n\nconst bancoSinBambooSubtitle =\n `Pagos en banco sin empleado identificado en BambooHR · República Dominicana · ${reportDateLabel}`;\n\nconst cuentaMalDigitadaSubtitle =\n `Cuenta Mal Digitada en Nómina · República Dominicana · ${reportDateLabel}`;\n\nconst cuentaMalDigitadaCases = rows.filter(\n (row) => row.category === 'posible_cuenta_mal_digitada'\n);\n\nconst hasCuentaMalDigitada = true;\n\nconst sheetIds = {\n nominaVsBanco: 101,\n bancoSinNomina: 102,\n bancoSinBamboo: 103,\n diferenciasNombreBanco: 104,\n cuentaMalDigitada: 105,\n resumen: 106,\n};\n\nconst sheetTitles = {\n nominaVsBanco: '01 Nómina vs Banco',\n bancoSinNomina: '02 Banco sin Nómina',\n bancoSinBamboo: '03 Banco sin Bamboo',\n diferenciasNombreBanco: '04 Diferencias nombre banco',\n cuentaMalDigitada: '05 Cuenta Mal Digitada',\n resumen: '06 Resumen',\n};\n\nconst nominaVsBancoHeader = [\n '#',\n 'Empleado',\n 'Cuenta',\n 'Monto en Nómina',\n 'Monto en Banco',\n 'Diferencia',\n 'Sentido',\n 'Estado',\n 'Resolución',\n];\n\nconst mainReportRows = rows\n .filter((row) => row.category === 'discrepancia')\n .map((row, index) => {\n const payrollAmount = roundMoney(\n row.payroll_amount ?? row.payrollAmount ?? 0\n );\n const bankAmount = roundMoney(\n row.bank_amount ?? row.bankAmount ?? 0\n );\n const difference = roundMoney(\n row.difference ?? (payrollAmount - bankAmount)\n );\n\n return [\n index + 1,\n normalizeText(row.employee_name || row.employee || ''),\n normalizeText(\n row.bank_account ||\n row.bankAccount ||\n row.payroll_account ||\n row.payrollAccount ||\n row.account ||\n ''\n ),\n payrollAmount,\n bankAmount,\n difference,\n mainReportSense(row, difference),\n normalizeText(row.status || 'Riesgo').toUpperCase(),\n '',\n ];\n });\n\nconst nominaVsBancoValues = [\n [\n 'GOMEZLEE MARKETING',\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ],\n [\n mainReportSubtitle,\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ],\n ['', '', '', '', '', '', '', '', ''],\n nominaVsBancoHeader,\n ...mainReportRows,\n];\n\nconst bancoSinNominaHeader = [\n 'Empleado Banco',\n 'Cuenta Banco',\n 'Moneda',\n 'Monto Banco',\n 'Estado',\n 'Observación',\n 'Resolución',\n];\n\nconst bancoSinNominaRows = rows\n .filter((row) => row.category === 'banco_sin_nomina')\n .map((row) => [\n normalizeText(row.employee_name || row.employee || ''),\n normalizeText(\n row.bank_account ||\n row.bankAccount ||\n row.account ||\n ''\n ),\n normalizeText(row.currency || 'DOP'),\n roundMoney(row.bank_amount ?? row.bankAmount ?? 0),\n normalizeText(row.status || ''),\n normalizeText(row.observation || ''),\n '',\n ]);\n\nconst bancoSinBambooHeader = [\n '#',\n 'Nombre en banco',\n 'Nombre del cuentahabiente',\n 'Cuenta',\n 'Monto en banco (DOP)',\n 'Archivo / lote',\n 'Estado',\n 'Resolución',\n];\n\nconst bancoSinBambooRows = bankWithoutBamboo.map((row, index) => [\n index + 1,\n normalizeText(row.bank_name_file || row.employee_name || ''),\n normalizeText(row.bank_account_holder || ''),\n normalizeText(\n row.bank_account ||\n row.bankAccount ||\n row.account ||\n ''\n ),\n roundMoney(row.bank_amount ?? row.bankAmount ?? 0),\n firstValue(row.origins || row.origin || row.source_file || ''),\n 'PENDIENTE REVISIÓN',\n '',\n]);\n\nconst bancoSinBambooValues = [\n [\n 'GOMEZLEE MARKETING',\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ],\n [\n bancoSinBambooSubtitle,\n '',\n '',\n '',\n '',\n '',\n '',\n '',\n ],\n ['', '', '', '', '', '', '', ''],\n bancoSinBambooHeader,\n ...bancoSinBambooRows,\n];\n\nconst diferenciasNombreHeader = [\n 'Nombre en Archivo',\n 'Nombre del Cuentahabiente',\n 'Cuenta Destino',\n 'Moneda',\n 'Monto',\n 'Número de referencia',\n 'Origen',\n 'Archivo',\n 'Estado',\n 'Observación',\n 'Resolución',\n];\n\nconst diferenciasNombreRows = rows\n .filter((row) => row.category === 'diferencia_nombre_banco')\n .map((row) => [\n normalizeText(row.bank_name_file || row.employee_name || ''),\n normalizeText(row.bank_account_holder || ''),\n normalizeText(\n row.bank_account ||\n row.bankAccount ||\n row.account ||\n ''\n ),\n normalizeText(row.currency || 'DOP'),\n roundMoney(row.bank_amount ?? row.bankAmount ?? 0),\n normalizeText(row.reference || row.shipment_number || ''),\n normalizeText(row.origin || row.plan_number || ''),\n normalizeText(row.source_file || ''),\n normalizeText(row.status || ''),\n normalizeText(row.observation || ''),\n '',\n ]);\n\n\nfunction accountValues(value) {\n const values = Array.isArray(value)\n ? value\n : String(value ?? '')\n .split(/\\s*(?:\\/|;|,|\\by\\b)\\s*/i);\n\n return values\n .map((item) =>\n String(item ?? '')\n .replace(/\\.0$/g, '')\n .replace(/\\D/g, '')\n .trim()\n )\n .filter((item) =>\n item.length >= 7 &&\n !/^0+$/.test(item)\n );\n}\n\nfunction payrollAccountsForWrongAccount(row) {\n const candidates = [\n row.payroll_account,\n row.payrollAccount,\n ...(Array.isArray(row.source_rows)\n ? row.source_rows.flatMap((sourceRow) => [\n sourceRow.account,\n sourceRow.payroll_account,\n sourceRow.payrollAccount,\n ])\n : []),\n ];\n\n return Array.from(new Set(\n candidates.flatMap(accountValues)\n ));\n}\n\nfunction bankAccountForWrongAccount(row) {\n return firstValue(\n row.bank_account ||\n row.bankAccount ||\n row.account ||\n ''\n );\n}\n\nfunction wrongAccountTotalStatus(row) {\n const currency = 'DOP';\n const payrollAmount = roundMoney(\n row.payroll_amount ?? row.payrollAmount ?? 0\n );\n const bankAmount = roundMoney(\n row.bank_amount ?? row.bankAmount ?? 0\n );\n const difference = roundMoney(\n payrollAmount - bankAmount\n );\n\n if (Math.abs(difference) <= 0.02) {\n return 'El total de nómina coincide con el total del banco.';\n }\n\n if (difference > 0) {\n return (\n `El total de nómina supera el total del banco por ` +\n `${currency} ${Math.abs(difference).toLocaleString('es-DO', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}.`\n );\n }\n\n return (\n `El total pagado por el banco supera el total de nómina por ` +\n `${currency} ${Math.abs(difference).toLocaleString('es-DO', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}.`\n );\n}\n\nfunction wrongAccountFinding(row) {\n const existing = normalizeText(row.observation || '');\n\n if (existing) {\n return existing;\n }\n\n const payrollAccounts =\n payrollAccountsForWrongAccount(row);\n const bankAccount =\n bankAccountForWrongAccount(row);\n\n return (\n `El empleado presenta una posible inconsistencia entre ` +\n `la cuenta registrada en nómina ` +\n `(${payrollAccounts.join(' y ') || 'sin cuenta identificada'}) ` +\n `y la cuenta utilizada por el banco ` +\n `(${bankAccount || 'sin cuenta identificada'}).`\n );\n}\n\nconst cuentaMalDigitadaHeader = [\n '#',\n 'Campo',\n 'Detalle',\n 'Resolución',\n];\n\nconst cuentaMalDigitadaRows = [];\n\nfor (\n let index = 0;\n index < cuentaMalDigitadaCases.length;\n index++\n) {\n const row = cuentaMalDigitadaCases[index];\n const payrollAccounts =\n payrollAccountsForWrongAccount(row);\n const bankAccount =\n bankAccountForWrongAccount(row);\n\n const fields = [\n [\n 'Empleado',\n normalizeText(\n row.employee_name ||\n row.employee ||\n ''\n ),\n ],\n [\n 'Cuentas registradas en las hojas de nómina',\n payrollAccounts.join(' y ') ||\n 'No se identificó una cuenta válida en la nómina.',\n ],\n [\n 'Cuenta utilizada por el banco',\n bankAccount ||\n 'No se identificó una cuenta válida en el banco.',\n ],\n [\n 'Estado del total',\n wrongAccountTotalStatus(row),\n ],\n [\n 'Hallazgo',\n wrongAccountFinding(row),\n ],\n [\n 'Clasificación',\n 'Posible cuenta mal digitada — revisar y unificar la cuenta en las hojas de nómina.',\n ],\n ];\n\n fields.forEach((field, fieldIndex) => {\n cuentaMalDigitadaRows.push([\n fieldIndex === 0 ? index + 1 : '',\n field[0],\n field[1],\n '',\n ]);\n });\n}\n\nconst cuentaMalDigitadaValues = [\n [\n 'GOMEZLEE MARKETING',\n '',\n '',\n '',\n ],\n [\n cuentaMalDigitadaSubtitle,\n '',\n '',\n '',\n ],\n ['', '', '', ''],\n cuentaMalDigitadaHeader,\n ...cuentaMalDigitadaRows,\n];\n\nconst resumenHeader = ['Indicador', 'Valor'];\nconst resumenRows = [\n ['Período', periodLabel],\n ['Coincidencias', Number(summary.coincidencias || 0)],\n ['Discrepancias', Number(summary.discrepancias || 0)],\n ['Banco sin nómina', Number(summary.bancoSinNomina || 0)],\n ['Banco sin Bamboo', Number(summary.bancoSinBamboo || 0)],\n ['Nómina sin cuenta', Number(summary.nominaSinCuenta || 0)],\n [\n 'Diferencias nombre banco',\n Number(summary.diferenciasNombreBanco || 0),\n ],\n [\n 'Posibles cuentas mal digitadas',\n Number(summary.posiblesCuentasMalDigitadas || 0),\n ],\n ['Pendientes cruce principal', Number(summary.pendientes || 0)],\n [\n 'Empleados BambooHR República Dominicana',\n Number(summary.empleadosBambooRD || 0),\n ],\n [\n 'Empleados BambooHR en el período',\n Number(summary.empleadosBambooEnPeriodo || 0),\n ],\n ['Filas válidas de nómina', Number(summary.filasNominaValidas || 0)],\n [\n 'Suplementos adjuntados',\n Number(summary.suplementosNominaAdjuntados || 0),\n ],\n [\n 'Suplementos sin coincidencia',\n Number(summary.suplementosNominaNoAdjuntados || 0),\n ],\n ['Transacciones bancarias', Number(summary.transaccionesBanco || 0)],\n ['Total nómina', roundMoney(summary.totalNominaPorMoneda?.DOP || summary.totalNomina || 0)],\n ['Total banco', roundMoney(summary.totalBancoPorMoneda?.DOP || summary.totalBanco || 0)],\n ['Diferencia total', roundMoney(summary.diferenciaTotalPorMoneda?.DOP || summary.diferenciaTotal || 0)],\n];\n\nfunction buildSheetValues(header, bodyRows) {\n return [header, ...bodyRows];\n}\n\nconst valueData = [\n {\n range: `'${sheetTitles.nominaVsBanco}'!A1:I`,\n values: nominaVsBancoValues,\n },\n {\n range: `'${sheetTitles.bancoSinNomina}'!A1:G`,\n values: buildSheetValues(\n bancoSinNominaHeader,\n bancoSinNominaRows\n ),\n },\n {\n range: `'${sheetTitles.bancoSinBamboo}'!A1:H`,\n values: bancoSinBambooValues,\n },\n {\n range: `'${sheetTitles.diferenciasNombreBanco}'!A1:K`,\n values: buildSheetValues(\n diferenciasNombreHeader,\n diferenciasNombreRows\n ),\n },\n ...(hasCuentaMalDigitada\n ? [\n {\n range:\n `'${sheetTitles.cuentaMalDigitada}'!A1:D`,\n values: cuentaMalDigitadaValues,\n },\n ]\n : []),\n {\n range: `'${sheetTitles.resumen}'!A1:B`,\n values: buildSheetValues(\n resumenHeader,\n resumenRows\n ),\n },\n];\n\nfunction headerFormatRequest(\n sheetId,\n endColumnIndex,\n startRowIndex = 0\n) {\n return {\n repeatCell: {\n range: {\n sheetId,\n startRowIndex,\n endRowIndex: startRowIndex + 1,\n startColumnIndex: 0,\n endColumnIndex,\n },\n cell: {\n userEnteredFormat: {\n backgroundColor: {\n red: 0.29,\n green: 0.49,\n blue: 0.58,\n },\n textFormat: {\n bold: true,\n foregroundColor: {\n red: 1,\n green: 1,\n blue: 1,\n },\n },\n horizontalAlignment: 'CENTER',\n verticalAlignment: 'MIDDLE',\n wrapStrategy: 'WRAP',\n },\n },\n fields:\n 'userEnteredFormat(backgroundColor,textFormat,horizontalAlignment,verticalAlignment,wrapStrategy)',\n },\n };\n}\n\nfunction freezeHeaderRequest(sheetId, frozenRowCount = 1) {\n return {\n updateSheetProperties: {\n properties: {\n sheetId,\n gridProperties: {\n frozenRowCount,\n },\n },\n fields: 'gridProperties.frozenRowCount',\n },\n };\n}\n\nfunction autoResizeRequest(sheetId, endColumnIndex) {\n return {\n autoResizeDimensions: {\n dimensions: {\n sheetId,\n dimension: 'COLUMNS',\n startIndex: 0,\n endIndex: endColumnIndex,\n },\n },\n };\n}\n\nfunction moneyFormatRequest(\n sheetId,\n startColumnIndex,\n endColumnIndex,\n startRowIndex = 1,\n pattern = '#,##0.00',\n endRowIndex = null\n) {\n const range = {\n sheetId,\n startRowIndex,\n startColumnIndex,\n endColumnIndex,\n };\n\n if (Number.isInteger(endRowIndex)) {\n range.endRowIndex = endRowIndex;\n }\n\n return {\n repeatCell: {\n range,\n cell: {\n userEnteredFormat: {\n numberFormat: {\n type: 'NUMBER',\n pattern,\n },\n },\n },\n fields: 'userEnteredFormat.numberFormat',\n },\n };\n}\n\nfunction basicFilterRequest(\n sheetId,\n endColumnIndex,\n startRowIndex = 0,\n endRowIndex = null\n) {\n const range = {\n sheetId,\n startRowIndex,\n startColumnIndex: 0,\n endColumnIndex,\n };\n\n if (Number.isInteger(endRowIndex)) {\n range.endRowIndex = endRowIndex;\n }\n\n return {\n setBasicFilter: {\n filter: {\n range,\n },\n },\n };\n}\n\nfunction mergeRowRequest(\n sheetId,\n rowIndex,\n endColumnIndex\n) {\n return {\n mergeCells: {\n range: {\n sheetId,\n startRowIndex: rowIndex,\n endRowIndex: rowIndex + 1,\n startColumnIndex: 0,\n endColumnIndex,\n },\n mergeType: 'MERGE_ALL',\n },\n };\n}\n\nfunction titleRowFormatRequest(\n sheetId,\n rowIndex,\n endColumnIndex,\n options = {}\n) {\n const {\n fontSize = 12,\n bold = true,\n italic = false,\n horizontalAlignment = 'LEFT',\n } = options;\n\n return {\n repeatCell: {\n range: {\n sheetId,\n startRowIndex: rowIndex,\n endRowIndex: rowIndex + 1,\n startColumnIndex: 0,\n endColumnIndex,\n },\n cell: {\n userEnteredFormat: {\n backgroundColor: {\n red: 0.29,\n green: 0.49,\n blue: 0.58,\n },\n textFormat: {\n bold,\n italic,\n fontSize,\n foregroundColor: {\n red: 1,\n green: 1,\n blue: 1,\n },\n },\n horizontalAlignment,\n verticalAlignment: 'MIDDLE',\n },\n },\n fields:\n 'userEnteredFormat(backgroundColor,textFormat,horizontalAlignment,verticalAlignment)',\n },\n };\n}\n\nfunction columnWidthRequest(\n sheetId,\n startIndex,\n endIndex,\n pixelSize\n) {\n return {\n updateDimensionProperties: {\n range: {\n sheetId,\n dimension: 'COLUMNS',\n startIndex,\n endIndex,\n },\n properties: {\n pixelSize,\n },\n fields: 'pixelSize',\n },\n };\n}\n\nfunction rowHeightRequest(\n sheetId,\n startIndex,\n endIndex,\n pixelSize\n) {\n return {\n updateDimensionProperties: {\n range: {\n sheetId,\n dimension: 'ROWS',\n startIndex,\n endIndex,\n },\n properties: {\n pixelSize,\n },\n fields: 'pixelSize',\n },\n };\n}\n\nfunction bodyAlignmentRequest(\n sheetId,\n startColumnIndex,\n endColumnIndex,\n horizontalAlignment,\n endRowIndex\n) {\n return {\n repeatCell: {\n range: {\n sheetId,\n startRowIndex: 4,\n endRowIndex,\n startColumnIndex,\n endColumnIndex,\n },\n cell: {\n userEnteredFormat: {\n horizontalAlignment,\n verticalAlignment: 'MIDDLE',\n wrapStrategy: 'WRAP',\n },\n },\n fields:\n 'userEnteredFormat(horizontalAlignment,verticalAlignment,wrapStrategy)',\n },\n };\n}\n\nfunction statusFormatRequest(sheetId, endRowIndex) {\n return {\n repeatCell: {\n range: {\n sheetId,\n startRowIndex: 4,\n endRowIndex,\n startColumnIndex: 7,\n endColumnIndex: 8,\n },\n cell: {\n userEnteredFormat: {\n backgroundColor: {\n red: 1,\n green: 0.92,\n blue: 0.92,\n },\n textFormat: {\n bold: true,\n foregroundColor: {\n red: 0.85,\n green: 0.08,\n blue: 0.08,\n },\n },\n horizontalAlignment: 'CENTER',\n verticalAlignment: 'MIDDLE',\n },\n },\n fields:\n 'userEnteredFormat(backgroundColor,textFormat,horizontalAlignment,verticalAlignment)',\n },\n };\n}\n\nfunction bambooStatusFormatRequest(\n sheetId,\n endRowIndex\n) {\n return {\n repeatCell: {\n range: {\n sheetId,\n startRowIndex: 4,\n endRowIndex,\n startColumnIndex: 6,\n endColumnIndex: 7,\n },\n cell: {\n userEnteredFormat: {\n backgroundColor: {\n red: 1,\n green: 0.97,\n blue: 0.82,\n },\n textFormat: {\n bold: true,\n foregroundColor: {\n red: 0.70,\n green: 0.30,\n blue: 0.00,\n },\n },\n horizontalAlignment: 'CENTER',\n verticalAlignment: 'MIDDLE',\n wrapStrategy: 'WRAP',\n },\n },\n fields:\n 'userEnteredFormat(backgroundColor,textFormat,horizontalAlignment,verticalAlignment,wrapStrategy)',\n },\n };\n}\n\n\nfunction mergeVerticalRequest(\n sheetId,\n startRowIndex,\n endRowIndex,\n columnIndex\n) {\n return {\n mergeCells: {\n range: {\n sheetId,\n startRowIndex,\n endRowIndex,\n startColumnIndex: columnIndex,\n endColumnIndex: columnIndex + 1,\n },\n mergeType: 'MERGE_ALL',\n },\n };\n}\n\nfunction rangeFormatRequest(\n sheetId,\n startRowIndex,\n endRowIndex,\n startColumnIndex,\n endColumnIndex,\n userEnteredFormat\n) {\n return {\n repeatCell: {\n range: {\n sheetId,\n startRowIndex,\n endRowIndex,\n startColumnIndex,\n endColumnIndex,\n },\n cell: {\n userEnteredFormat,\n },\n fields:\n 'userEnteredFormat(backgroundColor,textFormat,horizontalAlignment,verticalAlignment,wrapStrategy)',\n },\n };\n}\n\nfunction conditionalDifferenceRequest(\n sheetId,\n formula,\n backgroundColor,\n textColor,\n ranges,\n index\n) {\n return {\n addConditionalFormatRule: {\n index,\n rule: {\n ranges,\n booleanRule: {\n condition: {\n type: 'CUSTOM_FORMULA',\n values: [\n {\n userEnteredValue: formula,\n },\n ],\n },\n format: {\n backgroundColor,\n textFormat: {\n bold: true,\n foregroundColor: textColor,\n },\n },\n },\n },\n },\n };\n}\n\nfunction borderRequest(\n sheetId,\n startRowIndex,\n endRowIndex,\n endColumnIndex\n) {\n const border = {\n style: 'SOLID',\n color: {\n red: 0.72,\n green: 0.82,\n blue: 0.76,\n },\n };\n\n return {\n updateBorders: {\n range: {\n sheetId,\n startRowIndex,\n endRowIndex,\n startColumnIndex: 0,\n endColumnIndex,\n },\n top: border,\n bottom: border,\n left: border,\n right: border,\n innerHorizontal: border,\n innerVertical: border,\n },\n };\n}\n\nconst mainReportEndRow = Math.max(\n 4 + mainReportRows.length,\n 4\n);\n\nconst bancoSinBambooEndRow = Math.max(\n 4 + bancoSinBambooRows.length,\n 4\n);\n\nconst mainConditionalRanges = mainReportRows.length\n ? [\n {\n sheetId: sheetIds.nominaVsBanco,\n startRowIndex: 4,\n endRowIndex: mainReportEndRow,\n startColumnIndex: 5,\n endColumnIndex: 7,\n },\n ]\n : [];\n\nconst mainDataFormatRequests = mainReportRows.length\n ? [\n moneyFormatRequest(\n sheetIds.nominaVsBanco,\n 3,\n 6,\n 4,\n 'Q#,##0.00;[Red](Q#,##0.00)',\n mainReportEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.nominaVsBanco,\n 0,\n 1,\n 'CENTER',\n mainReportEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.nominaVsBanco,\n 1,\n 2,\n 'LEFT',\n mainReportEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.nominaVsBanco,\n 2,\n 3,\n 'CENTER',\n mainReportEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.nominaVsBanco,\n 3,\n 6,\n 'RIGHT',\n mainReportEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.nominaVsBanco,\n 6,\n 8,\n 'CENTER',\n mainReportEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.nominaVsBanco,\n 8,\n 9,\n 'LEFT',\n mainReportEndRow\n ),\n statusFormatRequest(\n sheetIds.nominaVsBanco,\n mainReportEndRow\n ),\n conditionalDifferenceRequest(\n sheetIds.nominaVsBanco,\n '=$F5>0',\n {\n red: 1,\n green: 0.97,\n blue: 0.82,\n },\n {\n red: 0.25,\n green: 0.25,\n blue: 0.25,\n },\n mainConditionalRanges,\n 0\n ),\n conditionalDifferenceRequest(\n sheetIds.nominaVsBanco,\n '=$F5<0',\n {\n red: 1,\n green: 0.89,\n blue: 0.89,\n },\n {\n red: 0.9,\n green: 0.05,\n blue: 0.05,\n },\n mainConditionalRanges,\n 1\n ),\n rowHeightRequest(\n sheetIds.nominaVsBanco,\n 4,\n mainReportEndRow,\n 28\n ),\n ]\n : [];\n\n\nconst cuentaMalDigitadaEndRow = Math.max(\n 4 + cuentaMalDigitadaRows.length,\n 4\n);\n\nconst cuentaMalDigitadaCaseRequests =\n hasCuentaMalDigitada\n ? cuentaMalDigitadaCases.flatMap(\n (_, caseIndex) => {\n const startRowIndex =\n 4 + caseIndex * 6;\n const endRowIndex =\n startRowIndex + 6;\n\n return [\n mergeVerticalRequest(\n sheetIds.cuentaMalDigitada,\n startRowIndex,\n endRowIndex,\n 0\n ),\n mergeVerticalRequest(\n sheetIds.cuentaMalDigitada,\n startRowIndex,\n endRowIndex,\n 3\n ),\n rowHeightRequest(\n sheetIds.cuentaMalDigitada,\n startRowIndex,\n startRowIndex + 4,\n 34\n ),\n rowHeightRequest(\n sheetIds.cuentaMalDigitada,\n startRowIndex + 4,\n startRowIndex + 5,\n 76\n ),\n rowHeightRequest(\n sheetIds.cuentaMalDigitada,\n startRowIndex + 5,\n endRowIndex,\n 54\n ),\n rangeFormatRequest(\n sheetIds.cuentaMalDigitada,\n startRowIndex + 4,\n startRowIndex + 5,\n 2,\n 3,\n {\n backgroundColor: {\n red: 0.97,\n green: 0.97,\n blue: 0.97,\n },\n horizontalAlignment: 'LEFT',\n verticalAlignment: 'MIDDLE',\n wrapStrategy: 'WRAP',\n }\n ),\n rangeFormatRequest(\n sheetIds.cuentaMalDigitada,\n startRowIndex + 5,\n endRowIndex,\n 2,\n 3,\n {\n backgroundColor: {\n red: 1,\n green: 0.97,\n blue: 0.82,\n },\n textFormat: {\n bold: true,\n foregroundColor: {\n red: 0.55,\n green: 0.30,\n blue: 0.00,\n },\n },\n horizontalAlignment: 'LEFT',\n verticalAlignment: 'MIDDLE',\n wrapStrategy: 'WRAP',\n }\n ),\n ];\n }\n )\n : [];\n\nconst cuentaMalDigitadaFormatRequests =\n hasCuentaMalDigitada\n ? [\n mergeRowRequest(\n sheetIds.cuentaMalDigitada,\n 0,\n 4\n ),\n mergeRowRequest(\n sheetIds.cuentaMalDigitada,\n 1,\n 4\n ),\n titleRowFormatRequest(\n sheetIds.cuentaMalDigitada,\n 0,\n 4,\n {\n fontSize: 12,\n bold: true,\n italic: false,\n horizontalAlignment: 'LEFT',\n }\n ),\n titleRowFormatRequest(\n sheetIds.cuentaMalDigitada,\n 1,\n 4,\n {\n fontSize: 10,\n bold: false,\n italic: true,\n horizontalAlignment: 'LEFT',\n }\n ),\n headerFormatRequest(\n sheetIds.cuentaMalDigitada,\n 4,\n 3\n ),\n freezeHeaderRequest(\n sheetIds.cuentaMalDigitada,\n 4\n ),\n borderRequest(\n sheetIds.cuentaMalDigitada,\n 3,\n cuentaMalDigitadaEndRow,\n 4\n ),\n rowHeightRequest(\n sheetIds.cuentaMalDigitada,\n 0,\n 1,\n 30\n ),\n rowHeightRequest(\n sheetIds.cuentaMalDigitada,\n 1,\n 2,\n 26\n ),\n rowHeightRequest(\n sheetIds.cuentaMalDigitada,\n 3,\n 4,\n 40\n ),\n rangeFormatRequest(\n sheetIds.cuentaMalDigitada,\n 4,\n cuentaMalDigitadaEndRow,\n 0,\n 1,\n {\n backgroundColor: {\n red: 0.91,\n green: 0.95,\n blue: 0.99,\n },\n textFormat: {\n bold: true,\n foregroundColor: {\n red: 0.20,\n green: 0.36,\n blue: 0.45,\n },\n },\n horizontalAlignment: 'CENTER',\n verticalAlignment: 'MIDDLE',\n wrapStrategy: 'WRAP',\n }\n ),\n rangeFormatRequest(\n sheetIds.cuentaMalDigitada,\n 4,\n cuentaMalDigitadaEndRow,\n 1,\n 2,\n {\n backgroundColor: {\n red: 0.93,\n green: 0.97,\n blue: 0.90,\n },\n textFormat: {\n bold: true,\n foregroundColor: {\n red: 0.20,\n green: 0.36,\n blue: 0.45,\n },\n },\n horizontalAlignment: 'LEFT',\n verticalAlignment: 'MIDDLE',\n wrapStrategy: 'WRAP',\n }\n ),\n rangeFormatRequest(\n sheetIds.cuentaMalDigitada,\n 4,\n cuentaMalDigitadaEndRow,\n 2,\n 3,\n {\n horizontalAlignment: 'LEFT',\n verticalAlignment: 'MIDDLE',\n wrapStrategy: 'WRAP',\n }\n ),\n rangeFormatRequest(\n sheetIds.cuentaMalDigitada,\n 4,\n cuentaMalDigitadaEndRow,\n 3,\n 4,\n {\n horizontalAlignment: 'LEFT',\n verticalAlignment: 'MIDDLE',\n wrapStrategy: 'WRAP',\n }\n ),\n columnWidthRequest(\n sheetIds.cuentaMalDigitada,\n 0,\n 1,\n 48\n ),\n columnWidthRequest(\n sheetIds.cuentaMalDigitada,\n 1,\n 2,\n 285\n ),\n columnWidthRequest(\n sheetIds.cuentaMalDigitada,\n 2,\n 3,\n 520\n ),\n columnWidthRequest(\n sheetIds.cuentaMalDigitada,\n 3,\n 4,\n 260\n ),\n ...cuentaMalDigitadaCaseRequests,\n ]\n : [];\n\n\nfunction wrapRangeRequest(\n sheetId,\n startRowIndex,\n endRowIndex,\n startColumnIndex,\n endColumnIndex\n) {\n return {\n repeatCell: {\n range: {\n sheetId,\n startRowIndex,\n endRowIndex,\n startColumnIndex,\n endColumnIndex,\n },\n cell: {\n userEnteredFormat: {\n verticalAlignment: 'MIDDLE',\n wrapStrategy: 'WRAP',\n },\n },\n fields:\n 'userEnteredFormat(verticalAlignment,wrapStrategy)',\n },\n };\n}\n\nfunction autoResizeRowsRequest(\n sheetId,\n startIndex,\n endIndex\n) {\n return {\n autoResizeDimensions: {\n dimensions: {\n sheetId,\n dimension: 'ROWS',\n startIndex,\n endIndex,\n },\n },\n };\n}\n\nconst formatRequests = [\n mergeRowRequest(sheetIds.nominaVsBanco, 0, 9),\n mergeRowRequest(sheetIds.nominaVsBanco, 1, 9),\n titleRowFormatRequest(\n sheetIds.nominaVsBanco,\n 0,\n 9,\n {\n fontSize: 12,\n bold: true,\n italic: false,\n horizontalAlignment: 'LEFT',\n }\n ),\n titleRowFormatRequest(\n sheetIds.nominaVsBanco,\n 1,\n 9,\n {\n fontSize: 10,\n bold: false,\n italic: true,\n horizontalAlignment: 'LEFT',\n }\n ),\n headerFormatRequest(\n sheetIds.nominaVsBanco,\n 9,\n 3\n ),\n freezeHeaderRequest(\n sheetIds.nominaVsBanco,\n 4\n ),\n basicFilterRequest(\n sheetIds.nominaVsBanco,\n 9,\n 3,\n mainReportEndRow\n ),\n borderRequest(\n sheetIds.nominaVsBanco,\n 3,\n mainReportEndRow,\n 9\n ),\n rowHeightRequest(\n sheetIds.nominaVsBanco,\n 0,\n 1,\n 30\n ),\n rowHeightRequest(\n sheetIds.nominaVsBanco,\n 1,\n 2,\n 26\n ),\n rowHeightRequest(\n sheetIds.nominaVsBanco,\n 3,\n 4,\n 42\n ),\n ...mainDataFormatRequests,\n\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 0,\n 1,\n 48\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 1,\n 2,\n 260\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 2,\n 3,\n 130\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 3,\n 6,\n 130\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 6,\n 7,\n 155\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 7,\n 8,\n 110\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 8,\n 9,\n 260\n ),\n\n headerFormatRequest(sheetIds.bancoSinNomina, 7),\n freezeHeaderRequest(sheetIds.bancoSinNomina),\n autoResizeRequest(sheetIds.bancoSinNomina, 7),\n moneyFormatRequest(sheetIds.bancoSinNomina, 3, 4),\n basicFilterRequest(sheetIds.bancoSinNomina, 7),\n columnWidthRequest(\n sheetIds.bancoSinNomina,\n 6,\n 7,\n 260\n ),\n\n mergeRowRequest(sheetIds.bancoSinBamboo, 0, 8),\n mergeRowRequest(sheetIds.bancoSinBamboo, 1, 8),\n titleRowFormatRequest(\n sheetIds.bancoSinBamboo,\n 0,\n 8,\n {\n fontSize: 12,\n bold: true,\n italic: false,\n horizontalAlignment: 'LEFT',\n }\n ),\n titleRowFormatRequest(\n sheetIds.bancoSinBamboo,\n 1,\n 8,\n {\n fontSize: 10,\n bold: false,\n italic: true,\n horizontalAlignment: 'LEFT',\n }\n ),\n headerFormatRequest(\n sheetIds.bancoSinBamboo,\n 8,\n 3\n ),\n freezeHeaderRequest(\n sheetIds.bancoSinBamboo,\n 4\n ),\n basicFilterRequest(\n sheetIds.bancoSinBamboo,\n 8,\n 3,\n bancoSinBambooEndRow\n ),\n borderRequest(\n sheetIds.bancoSinBamboo,\n 3,\n bancoSinBambooEndRow,\n 8\n ),\n rowHeightRequest(\n sheetIds.bancoSinBamboo,\n 0,\n 1,\n 30\n ),\n rowHeightRequest(\n sheetIds.bancoSinBamboo,\n 1,\n 2,\n 26\n ),\n rowHeightRequest(\n sheetIds.bancoSinBamboo,\n 3,\n 4,\n 42\n ),\n moneyFormatRequest(\n sheetIds.bancoSinBamboo,\n 4,\n 5,\n 4,\n 'Q#,##0.00',\n bancoSinBambooEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.bancoSinBamboo,\n 0,\n 1,\n 'CENTER',\n bancoSinBambooEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.bancoSinBamboo,\n 1,\n 3,\n 'LEFT',\n bancoSinBambooEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.bancoSinBamboo,\n 3,\n 4,\n 'CENTER',\n bancoSinBambooEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.bancoSinBamboo,\n 4,\n 5,\n 'RIGHT',\n bancoSinBambooEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.bancoSinBamboo,\n 5,\n 7,\n 'CENTER',\n bancoSinBambooEndRow\n ),\n bodyAlignmentRequest(\n sheetIds.bancoSinBamboo,\n 7,\n 8,\n 'LEFT',\n bancoSinBambooEndRow\n ),\n bambooStatusFormatRequest(\n sheetIds.bancoSinBamboo,\n bancoSinBambooEndRow\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 0,\n 1,\n 48\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 1,\n 2,\n 220\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 2,\n 3,\n 270\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 3,\n 4,\n 135\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 4,\n 5,\n 130\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 5,\n 6,\n 110\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 6,\n 7,\n 140\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 7,\n 8,\n 260\n ),\n\n headerFormatRequest(\n sheetIds.diferenciasNombreBanco,\n 11\n ),\n freezeHeaderRequest(\n sheetIds.diferenciasNombreBanco\n ),\n autoResizeRequest(\n sheetIds.diferenciasNombreBanco,\n 11\n ),\n moneyFormatRequest(\n sheetIds.diferenciasNombreBanco,\n 4,\n 5\n ),\n basicFilterRequest(\n sheetIds.diferenciasNombreBanco,\n 11\n ),\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 10,\n 11,\n 260\n ),\n\n ...cuentaMalDigitadaFormatRequests,\n\n headerFormatRequest(sheetIds.resumen, 2),\n freezeHeaderRequest(sheetIds.resumen),\n autoResizeRequest(sheetIds.resumen, 2),\n moneyFormatRequest(sheetIds.resumen, 1, 2),\n];\n\n\nconst bancoSinNominaEndRow =\n 1 + bancoSinNominaRows.length;\n\nconst diferenciasNombreEndRow =\n 1 + diferenciasNombreRows.length;\n\nconst resumenReadabilityEndRow =\n 1 + resumenRows.length;\n\n/*\n * Ajuste final de legibilidad.\n *\n * Se ejecuta al final para que los anchos definitivos ya estén aplicados\n * cuando Google Sheets calcule automáticamente la altura de cada fila.\n * Así, cualquier texto largo queda envuelto y visible sin que el usuario\n * tenga que expandir columnas o filas manualmente.\n */\nformatRequests.push(\n // 01 Nómina vs Banco\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 1,\n 2,\n 300\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 2,\n 3,\n 150\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 3,\n 6,\n 145\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 6,\n 7,\n 220\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 7,\n 8,\n 140\n ),\n columnWidthRequest(\n sheetIds.nominaVsBanco,\n 8,\n 9,\n 320\n ),\n ...(mainReportRows.length > 0\n ? [\n wrapRangeRequest(\n sheetIds.nominaVsBanco,\n 4,\n mainReportEndRow,\n 0,\n 9\n ),\n autoResizeRowsRequest(\n sheetIds.nominaVsBanco,\n 4,\n mainReportEndRow\n ),\n ]\n : []),\n\n // 02 Banco sin Nómina\n columnWidthRequest(\n sheetIds.bancoSinNomina,\n 0,\n 1,\n 320\n ),\n columnWidthRequest(\n sheetIds.bancoSinNomina,\n 1,\n 2,\n 165\n ),\n columnWidthRequest(\n sheetIds.bancoSinNomina,\n 2,\n 3,\n 95\n ),\n columnWidthRequest(\n sheetIds.bancoSinNomina,\n 3,\n 4,\n 140\n ),\n columnWidthRequest(\n sheetIds.bancoSinNomina,\n 4,\n 5,\n 170\n ),\n columnWidthRequest(\n sheetIds.bancoSinNomina,\n 5,\n 6,\n 560\n ),\n columnWidthRequest(\n sheetIds.bancoSinNomina,\n 6,\n 7,\n 320\n ),\n autoResizeRowsRequest(\n sheetIds.bancoSinNomina,\n 0,\n 1\n ),\n ...(bancoSinNominaRows.length > 0\n ? [\n wrapRangeRequest(\n sheetIds.bancoSinNomina,\n 1,\n bancoSinNominaEndRow,\n 0,\n 7\n ),\n autoResizeRowsRequest(\n sheetIds.bancoSinNomina,\n 1,\n bancoSinNominaEndRow\n ),\n ]\n : []),\n\n // 03 Banco sin Bamboo\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 1,\n 2,\n 300\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 2,\n 3,\n 330\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 3,\n 4,\n 150\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 4,\n 5,\n 145\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 5,\n 6,\n 150\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 6,\n 7,\n 170\n ),\n columnWidthRequest(\n sheetIds.bancoSinBamboo,\n 7,\n 8,\n 320\n ),\n ...(bancoSinBambooRows.length > 0\n ? [\n wrapRangeRequest(\n sheetIds.bancoSinBamboo,\n 4,\n bancoSinBambooEndRow,\n 0,\n 8\n ),\n autoResizeRowsRequest(\n sheetIds.bancoSinBamboo,\n 4,\n bancoSinBambooEndRow\n ),\n ]\n : []),\n\n // 04 Diferencias nombre banco\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 0,\n 1,\n 300\n ),\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 1,\n 2,\n 330\n ),\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 2,\n 3,\n 155\n ),\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 3,\n 4,\n 95\n ),\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 4,\n 5,\n 140\n ),\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 5,\n 7,\n 150\n ),\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 7,\n 8,\n 260\n ),\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 8,\n 9,\n 170\n ),\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 9,\n 10,\n 650\n ),\n columnWidthRequest(\n sheetIds.diferenciasNombreBanco,\n 10,\n 11,\n 320\n ),\n autoResizeRowsRequest(\n sheetIds.diferenciasNombreBanco,\n 0,\n 1\n ),\n ...(diferenciasNombreRows.length > 0\n ? [\n wrapRangeRequest(\n sheetIds.diferenciasNombreBanco,\n 1,\n diferenciasNombreEndRow,\n 0,\n 11\n ),\n autoResizeRowsRequest(\n sheetIds.diferenciasNombreBanco,\n 1,\n diferenciasNombreEndRow\n ),\n ]\n : []),\n\n // 05 Cuenta Mal Digitada\n ...(hasCuentaMalDigitada\n ? [\n columnWidthRequest(\n sheetIds.cuentaMalDigitada,\n 1,\n 2,\n 300\n ),\n columnWidthRequest(\n sheetIds.cuentaMalDigitada,\n 2,\n 3,\n 600\n ),\n columnWidthRequest(\n sheetIds.cuentaMalDigitada,\n 3,\n 4,\n 320\n ),\n ]\n : []),\n\n // Resumen\n columnWidthRequest(\n sheetIds.resumen,\n 0,\n 1,\n 380\n ),\n columnWidthRequest(\n sheetIds.resumen,\n 1,\n 2,\n 320\n ),\n autoResizeRowsRequest(\n sheetIds.resumen,\n 0,\n 1\n ),\n ...(resumenRows.length > 0\n ? [\n wrapRangeRequest(\n sheetIds.resumen,\n 1,\n resumenReadabilityEndRow,\n 0,\n 2\n ),\n autoResizeRowsRequest(\n sheetIds.resumen,\n 1,\n resumenReadabilityEndRow\n ),\n ]\n : [])\n);\n\n\n\n/*\n * Protección de integridad del reporte.\n *\n * La hoja completa queda protegida para impedir que los usuarios con acceso\n * al reporte modifiquen datos calculados, nombres, cuentas, montos, estados,\n * observaciones o cualquier otro resultado del cruce.\n *\n * Únicamente las celdas de datos de la columna \"Resolución\" quedan fuera de\n * la protección para que puedan completarse después de recibir el reporte.\n * Los encabezados y las filas fuera de la tabla permanecen protegidos.\n *\n * El propietario de la hoja conserva siempre el control. Además, el usuario\n * administrativo iaracena@gomezleemarketing.com queda registrado como editor explícito del\n * rango protegido para mantenimiento de IT.\n */\nfunction protectedSheetRequest(\n sheetId,\n description,\n resolutionColumnIndex = null,\n resolutionStartRowIndex = null,\n resolutionRowsCount = 0\n) {\n const protectedRange = {\n range: {\n sheetId,\n },\n description,\n warningOnly: false,\n editors: {\n users: [\n 'iaracena@gomezleemarketing.com',\n ],\n domainUsersCanEdit: false,\n },\n };\n\n if (\n Number.isInteger(resolutionColumnIndex) &&\n Number.isInteger(resolutionStartRowIndex) &&\n Number(resolutionRowsCount) > 0\n ) {\n protectedRange.unprotectedRanges = [\n {\n sheetId,\n startRowIndex:\n resolutionStartRowIndex,\n endRowIndex:\n resolutionStartRowIndex +\n Number(resolutionRowsCount),\n startColumnIndex:\n resolutionColumnIndex,\n endColumnIndex:\n resolutionColumnIndex + 1,\n },\n ];\n }\n\n return {\n addProtectedRange: {\n protectedRange,\n },\n };\n}\n\n\nfunction protectedResolutionRequest(\n sheetId,\n resolutionColumnIndex,\n resolutionStartRowIndex,\n resolutionRowsCount\n) {\n if (\n !Number.isInteger(resolutionColumnIndex) ||\n !Number.isInteger(resolutionStartRowIndex) ||\n Number(resolutionRowsCount) <= 0\n ) {\n return null;\n }\n\n return {\n addProtectedRange: {\n protectedRange: {\n range: {\n sheetId,\n startRowIndex:\n resolutionStartRowIndex,\n endRowIndex:\n resolutionStartRowIndex +\n Number(resolutionRowsCount),\n startColumnIndex:\n resolutionColumnIndex,\n endColumnIndex:\n resolutionColumnIndex + 1,\n },\n description:\n 'Protección GLM — Resolución. RRHH República Dominicana y administración autorizada pueden editar.',\n warningOnly: false,\n editors: {\n users: [\n 'nlaureano@gomezleemarketing.com',\n 'vparamo@gomezleemarketing.com',\n 'adminregional@gomezleemarketing.com',\n ],\n domainUsersCanEdit: false,\n },\n },\n },\n };\n}\n\nfunction addResolutionProtection(\n sheetId,\n resolutionColumnIndex,\n resolutionStartRowIndex,\n resolutionRowsCount\n) {\n const request =\n protectedResolutionRequest(\n sheetId,\n resolutionColumnIndex,\n resolutionStartRowIndex,\n resolutionRowsCount\n );\n\n if (request) {\n formatRequests.push(request);\n }\n}\n\n\nformatRequests.push(\n protectedSheetRequest(\n sheetIds.nominaVsBanco,\n 'Protección GLM — datos del cruce. Solo Resolución es editable.',\n 8,\n 4,\n mainReportRows.length\n ),\n protectedSheetRequest(\n sheetIds.bancoSinNomina,\n 'Protección GLM — datos del cruce. Solo Resolución es editable.',\n 6,\n 1,\n bancoSinNominaRows.length\n ),\n protectedSheetRequest(\n sheetIds.bancoSinBamboo,\n 'Protección GLM — datos del cruce. Solo Resolución es editable.',\n 7,\n 4,\n bancoSinBambooRows.length\n ),\n protectedSheetRequest(\n sheetIds.diferenciasNombreBanco,\n 'Protección GLM — datos del cruce. Solo Resolución es editable.',\n 10,\n 1,\n diferenciasNombreRows.length\n ),\n ...(hasCuentaMalDigitada\n ? [\n protectedSheetRequest(\n sheetIds.cuentaMalDigitada,\n 'Protección GLM — datos del cruce. Solo Resolución es editable.',\n 3,\n 4,\n cuentaMalDigitadaRows.length\n ),\n ]\n : []),\n protectedSheetRequest(\n sheetIds.resumen,\n 'Protección GLM — hoja de resumen de solo lectura.'\n )\n);\n\n\naddResolutionProtection(\n sheetIds.nominaVsBanco,\n 8,\n 4,\n mainReportRows.length\n);\naddResolutionProtection(\n sheetIds.bancoSinNomina,\n 6,\n 1,\n bancoSinNominaRows.length\n);\naddResolutionProtection(\n sheetIds.bancoSinBamboo,\n 7,\n 4,\n bancoSinBambooRows.length\n);\naddResolutionProtection(\n sheetIds.diferenciasNombreBanco,\n 10,\n 1,\n diferenciasNombreRows.length\n);\nif (hasCuentaMalDigitada) {\n addResolutionProtection(\n sheetIds.cuentaMalDigitada,\n 3,\n 4,\n cuentaMalDigitadaRows.length\n );\n}\n\n\nreturn [\n {\n json: {\n ok: true,\n stage: 'preparar_google_sheet',\n metadata,\n summary,\n spreadsheetTitle,\n sheetIds,\n sheetTitles,\n createSpreadsheetBody: {\n properties: {\n title: spreadsheetTitle,\n },\n sheets: [\n {\n properties: {\n sheetId: sheetIds.nominaVsBanco,\n title: sheetTitles.nominaVsBanco,\n },\n },\n {\n properties: {\n sheetId: sheetIds.bancoSinNomina,\n title: sheetTitles.bancoSinNomina,\n },\n },\n {\n properties: {\n sheetId: sheetIds.bancoSinBamboo,\n title: sheetTitles.bancoSinBamboo,\n },\n },\n {\n properties: {\n sheetId:\n sheetIds.diferenciasNombreBanco,\n title:\n sheetTitles.diferenciasNombreBanco,\n },\n },\n ...(hasCuentaMalDigitada\n ? [\n {\n properties: {\n sheetId:\n sheetIds.cuentaMalDigitada,\n title:\n sheetTitles.cuentaMalDigitada,\n },\n },\n ]\n : []),\n {\n properties: {\n sheetId: sheetIds.resumen,\n title: sheetTitles.resumen,\n },\n },\n ],\n },\n valueBatchBody: {\n // RAW conserva los números de cuenta como texto exacto (incluidos\n // ceros iniciales) y mantiene los montos numéricos porque ya se\n // envían como números en el payload.\n valueInputOption: 'RAW',\n data: valueData,\n },\n formatBatchBody: {\n requests: formatRequests,\n },\n originalResponse: data,\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 416, + 7136 + ], + "id": "96897c35-5733-4439-b5dc-16c5d30b5028", + "name": "Preparar Google Sheet" + }, + { + "parameters": { + "method": "POST", + "url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cruce_cuentas_get_reporte_periodo", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Authorization", + "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=representation" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ { p_country: $('Preparar Google Sheet').first().json.metadata.country || 'RD', p_year: Number($('Preparar Google Sheet').first().json.metadata.year || 0), p_month: Number($('Preparar Google Sheet').first().json.metadata.month || 0), p_period_type: $('Preparar Google Sheet').first().json.metadata.period_type || '' } }}", + "options": { + "response": { + "response": { + "responseFormat": "json" + } + }, + "timeout": 30000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 656, + 7136 + ], + "id": "7bf61677-625b-47a0-9a31-de916d7c8892", + "name": "Buscar reporte existente Supabase" + }, + { + "parameters": { + "method": "POST", + "url": "={{ (() => { const lookup = $('Buscar reporte existente Supabase').first().json || {}; const report = lookup.report || {}; const id = String(report.spreadsheet_id || '').trim(); return (lookup.found === true && id) ? 'https://sheets.googleapis.com/v4/spreadsheets/' + id + ':batchUpdate' : 'https://sheets.googleapis.com/v4/spreadsheets'; })() }}", + "authentication": "predefinedCredentialType", + "nodeCredentialType": "googleOAuth2Api", + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{\n(() => {\n const prepared = $('Preparar Google Sheet').first().json || {};\n const lookup = $('Buscar reporte existente Supabase').first().json || {};\n const report = lookup.report || {};\n const existingId = String(report.spreadsheet_id || '').trim();\n\n if (lookup.found === true && existingId) {\n return {\n requests: [\n {\n updateSpreadsheetProperties: {\n properties: {\n title: prepared.spreadsheetTitle || prepared.createSpreadsheetBody?.properties?.title || 'Cruce de Cuentas GLM',\n },\n fields: 'title',\n },\n },\n ],\n };\n }\n\n const createBody = prepared.createSpreadsheetBody || {};\n\n if (!Array.isArray(createBody.sheets) || createBody.sheets.length === 0) {\n throw new Error('Preparar Google Sheet no devolvió las hojas que deben crearse.');\n }\n\n return {\n properties: {\n ...(createBody.properties || {}),\n timeZone: 'America/Santo_Domingo',\n },\n sheets: createBody.sheets.map((sheet) => ({\n properties: {\n ...(sheet.properties || {}),\n gridProperties: {\n ...((sheet.properties || {}).gridProperties || {}),\n frozenRowCount: 1,\n },\n },\n })),\n };\n})()\n}}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 896, + 7136 + ], + "id": "75c9e3ae-8d5e-44c8-9680-87c613e1b3d1", + "name": "Crear Google Sheet", + "retryOnFail": true, + "credentials": { + "googleOAuth2Api": { + "id": "eHseMeH39kRcXgOF", + "name": "Google account 2" + } + } + }, + { + "parameters": { + "url": "={{ 'https://sheets.googleapis.com/v4/spreadsheets/' + $('Crear Google Sheet').first().json.spreadsheetId + '?includeGridData=true' }}", + "authentication": "predefinedCredentialType", + "nodeCredentialType": "googleOAuth2Api", + "options": { + "timeout": 60000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 1136, + 7136 + ], + "id": "4f37d902-2200-4241-88bc-1ead75036c31", + "name": "Leer Google Sheet actual", + "retryOnFail": true, + "credentials": { + "googleOAuth2Api": { + "id": "dQ1MJSJSWcoWYcb8", + "name": "Google account - Isaac Producción" + } + } + }, + { + "parameters": { + "jsCode": "const prepared =\n $('Preparar Google Sheet').first().json || {};\n\nconst lookup =\n $('Buscar reporte existente Supabase').first().json || {};\n\nconst resolvedSheet =\n $('Crear Google Sheet').first().json || {};\n\nconst spreadsheet =\n $input.first().json || {};\n\nconst report =\n lookup && typeof lookup.report === 'object' && lookup.report\n ? lookup.report\n : {};\n\nconst historyExists =\n lookup.found === true &&\n Boolean(report.id);\n\nconst reusingSheet =\n historyExists &&\n Boolean(\n String(\n report.spreadsheet_id ||\n ''\n ).trim()\n );\n\nconst spreadsheetId =\n String(\n resolvedSheet.spreadsheetId ||\n report.spreadsheet_id ||\n spreadsheet.spreadsheetId ||\n ''\n ).trim();\n\nif (!spreadsheetId) {\n throw new Error(\n 'No se pudo resolver el spreadsheetId del reporte.'\n );\n}\n\nfunction normalizeText(value) {\n return String(value ?? '')\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalizeAccount(value) {\n return String(value ?? '')\n .replace(/\\.0$/g, '')\n .replace(/\\D/g, '')\n .trim();\n}\n\nfunction cellValue(cell) {\n if (!cell || typeof cell !== 'object') {\n return '';\n }\n\n const entered =\n cell.userEnteredValue || {};\n\n if (\n entered.stringValue !== undefined\n ) {\n return String(entered.stringValue);\n }\n\n if (\n entered.numberValue !== undefined\n ) {\n return String(entered.numberValue);\n }\n\n if (\n entered.boolValue !== undefined\n ) {\n return entered.boolValue\n ? 'TRUE'\n : 'FALSE';\n }\n\n if (\n entered.formulaValue !== undefined\n ) {\n return String(\n cell.formattedValue ??\n entered.formulaValue\n );\n }\n\n return String(\n cell.formattedValue ?? ''\n );\n}\n\nfunction sheetMatrix(sheet) {\n const matrix = [];\n const blocks =\n Array.isArray(sheet?.data)\n ? sheet.data\n : [];\n\n for (const block of blocks) {\n const startRow =\n Number(block.startRow || 0);\n const rowData =\n Array.isArray(block.rowData)\n ? block.rowData\n : [];\n\n for (\n let rowOffset = 0;\n rowOffset < rowData.length;\n rowOffset++\n ) {\n const rowIndex =\n startRow + rowOffset;\n\n const cells =\n Array.isArray(\n rowData[rowOffset]?.values\n )\n ? rowData[rowOffset].values\n : [];\n\n matrix[rowIndex] =\n cells.map(cellValue);\n }\n }\n\n return matrix;\n}\n\nfunction findHeaderInfo(matrix) {\n for (\n let rowIndex = 0;\n rowIndex < matrix.length;\n rowIndex++\n ) {\n const row =\n Array.isArray(matrix[rowIndex])\n ? matrix[rowIndex]\n : [];\n\n const normalized =\n row.map(normalizeText);\n\n const resolutionIndex =\n normalized.findIndex(\n (value) =>\n value === 'resolucion'\n );\n\n if (resolutionIndex >= 0) {\n return {\n rowIndex,\n header: row,\n normalized,\n resolutionIndex,\n };\n }\n }\n\n return null;\n}\n\nfunction indexMatching(\n normalizedHeader,\n candidates\n) {\n for (const candidate of candidates) {\n const normalizedCandidate =\n normalizeText(candidate);\n\n const exact =\n normalizedHeader.findIndex(\n (header) =>\n header === normalizedCandidate\n );\n\n if (exact >= 0) {\n return exact;\n }\n }\n\n for (const candidate of candidates) {\n const normalizedCandidate =\n normalizeText(candidate);\n\n const partial =\n normalizedHeader.findIndex(\n (header) =>\n header.includes(\n normalizedCandidate\n )\n );\n\n if (partial >= 0) {\n return partial;\n }\n }\n\n return -1;\n}\n\nfunction firstAt(row, indexes) {\n for (const index of indexes) {\n if (\n index >= 0 &&\n String(row[index] ?? '').trim()\n ) {\n return String(row[index]);\n }\n }\n\n return '';\n}\n\nconst ids =\n prepared.sheetIds || {};\n\nfunction rowIdentity(\n sheetId,\n row,\n normalizedHeader\n) {\n const accountIndex =\n indexMatching(\n normalizedHeader,\n [\n 'Cuenta',\n 'Cuenta Banco',\n 'Cuenta Destino',\n ]\n );\n\n const account =\n accountIndex >= 0\n ? normalizeAccount(\n row[accountIndex]\n )\n : '';\n\n if (account) {\n return `account:${account}`;\n }\n\n if (\n Number(sheetId) ===\n Number(ids.nominaVsBanco)\n ) {\n const employeeIndex =\n indexMatching(\n normalizedHeader,\n ['Empleado', 'Nombre en nómina']\n );\n\n return `employee:${normalizeText(\n firstAt(\n row,\n [employeeIndex]\n )\n )}`;\n }\n\n if (\n Number(sheetId) ===\n Number(ids.bancoSinNomina)\n ) {\n const nameIndex =\n indexMatching(\n normalizedHeader,\n [\n 'Empleado Banco',\n 'Nombre en banco',\n ]\n );\n\n const currencyIndex =\n indexMatching(\n normalizedHeader,\n ['Moneda']\n );\n\n return [\n 'bank-no-payroll',\n normalizeText(\n firstAt(row, [nameIndex])\n ),\n normalizeText(\n firstAt(row, [currencyIndex])\n ),\n ].join(':');\n }\n\n if (\n Number(sheetId) ===\n Number(ids.bancoSinBamboo)\n ) {\n const nameIndex =\n indexMatching(\n normalizedHeader,\n ['Nombre en banco']\n );\n\n const holderIndex =\n indexMatching(\n normalizedHeader,\n ['Nombre del cuentahabiente']\n );\n\n return [\n 'bank-no-bamboo',\n normalizeText(\n firstAt(row, [nameIndex])\n ),\n normalizeText(\n firstAt(row, [holderIndex])\n ),\n ].join(':');\n }\n\n if (\n Number(sheetId) ===\n Number(ids.diferenciasNombreBanco)\n ) {\n const nameOne =\n indexMatching(\n normalizedHeader,\n [\n 'Nombre en Archivo',\n 'Nombre en nómina',\n ]\n );\n\n const nameTwo =\n indexMatching(\n normalizedHeader,\n [\n 'Nombre del Cuentahabiente',\n 'Nombre en banco',\n ]\n );\n\n return [\n 'name-difference',\n normalizeText(\n firstAt(row, [nameOne])\n ),\n normalizeText(\n firstAt(row, [nameTwo])\n ),\n ].join(':');\n }\n\n return '';\n}\n\nfunction collectRegularResolutions(\n sheetId,\n matrix\n) {\n const result = new Map();\n const info =\n findHeaderInfo(matrix);\n\n if (!info) {\n return result;\n }\n\n for (\n let rowIndex =\n info.rowIndex + 1;\n rowIndex < matrix.length;\n rowIndex++\n ) {\n const row =\n Array.isArray(matrix[rowIndex])\n ? matrix[rowIndex]\n : [];\n\n const resolution =\n String(\n row[\n info.resolutionIndex\n ] ?? ''\n ).trim();\n\n if (!resolution) {\n continue;\n }\n\n const key =\n rowIdentity(\n sheetId,\n row,\n info.normalized\n );\n\n if (key) {\n result.set(\n key,\n resolution\n );\n }\n }\n\n return result;\n}\n\nfunction collectWrongAccountResolutions(\n matrix\n) {\n const result = new Map();\n const info =\n findHeaderInfo(matrix);\n\n if (!info) {\n return result;\n }\n\n const fieldIndex =\n indexMatching(\n info.normalized,\n ['Campo']\n );\n\n const detailIndex =\n indexMatching(\n info.normalized,\n ['Detalle']\n );\n\n let currentEmployee = '';\n\n for (\n let rowIndex =\n info.rowIndex + 1;\n rowIndex < matrix.length;\n rowIndex++\n ) {\n const row =\n Array.isArray(matrix[rowIndex])\n ? matrix[rowIndex]\n : [];\n\n const field =\n normalizeText(\n row[fieldIndex] ?? ''\n );\n\n const detail =\n String(\n row[detailIndex] ?? ''\n );\n\n if (field === 'empleado') {\n currentEmployee =\n normalizeText(detail);\n }\n\n const resolution =\n String(\n row[\n info.resolutionIndex\n ] ?? ''\n ).trim();\n\n if (\n resolution &&\n currentEmployee &&\n field\n ) {\n result.set(\n `${currentEmployee}|${field}`,\n resolution\n );\n }\n }\n\n return result;\n}\n\nconst existingSheets =\n Array.isArray(spreadsheet.sheets)\n ? spreadsheet.sheets\n : [];\n\nconst sheetById =\n new Map();\n\nfor (const sheet of existingSheets) {\n const sheetId =\n sheet?.properties?.sheetId;\n\n if (\n sheetId !== null &&\n sheetId !== undefined\n ) {\n sheetById.set(\n Number(sheetId),\n sheet\n );\n }\n}\n\nconst resolutionMaps =\n new Map();\n\nif (reusingSheet) {\n for (\n const [key, rawId]\n of Object.entries(ids)\n ) {\n const sheetId =\n Number(rawId);\n\n const sheet =\n sheetById.get(sheetId);\n\n if (!sheet) {\n continue;\n }\n\n const matrix =\n sheetMatrix(sheet);\n\n const map =\n key === 'cuentaMalDigitada'\n ? collectWrongAccountResolutions(\n matrix\n )\n : collectRegularResolutions(\n sheetId,\n matrix\n );\n\n resolutionMaps.set(\n sheetId,\n map\n );\n }\n}\n\nfunction titleFromRange(range) {\n const match =\n String(range || '')\n .match(/^'([^']+)'!/);\n\n return match?.[1] || '';\n}\n\nconst desiredTitles =\n prepared.sheetTitles || {};\n\nconst titleToId =\n new Map();\n\nfor (\n const [key, title]\n of Object.entries(desiredTitles)\n) {\n if (\n ids[key] !== undefined\n ) {\n titleToId.set(\n String(title),\n Number(ids[key])\n );\n }\n}\n\nlet preservedResolutionsCount = 0;\n\nconst valueBatchBody =\n JSON.parse(\n JSON.stringify(\n prepared.valueBatchBody || {\n valueInputOption:\n 'USER_ENTERED',\n data: [],\n }\n )\n );\n\nfor (\n const dataEntry\n of valueBatchBody.data || []\n) {\n const title =\n titleFromRange(\n dataEntry.range\n );\n\n const sheetId =\n titleToId.get(title);\n\n if (\n sheetId === undefined ||\n !Array.isArray(\n dataEntry.values\n )\n ) {\n continue;\n }\n\n const info =\n findHeaderInfo(\n dataEntry.values\n );\n\n if (!info) {\n continue;\n }\n\n const oldMap =\n resolutionMaps.get(\n Number(sheetId)\n ) || new Map();\n\n if (\n Number(sheetId) ===\n Number(ids.cuentaMalDigitada)\n ) {\n const fieldIndex =\n indexMatching(\n info.normalized,\n ['Campo']\n );\n\n const detailIndex =\n indexMatching(\n info.normalized,\n ['Detalle']\n );\n\n let currentEmployee = '';\n\n for (\n let rowIndex =\n info.rowIndex + 1;\n rowIndex <\n dataEntry.values.length;\n rowIndex++\n ) {\n const row =\n dataEntry.values[\n rowIndex\n ];\n\n const field =\n normalizeText(\n row[fieldIndex] ?? ''\n );\n\n const detail =\n String(\n row[detailIndex] ?? ''\n );\n\n if (field === 'empleado') {\n currentEmployee =\n normalizeText(detail);\n }\n\n const key =\n currentEmployee && field\n ? `${currentEmployee}|${field}`\n : '';\n\n if (\n key &&\n oldMap.has(key)\n ) {\n while (\n row.length <=\n info.resolutionIndex\n ) {\n row.push('');\n }\n\n row[\n info.resolutionIndex\n ] = oldMap.get(key);\n\n preservedResolutionsCount++;\n }\n }\n\n continue;\n }\n\n for (\n let rowIndex =\n info.rowIndex + 1;\n rowIndex <\n dataEntry.values.length;\n rowIndex++\n ) {\n const row =\n dataEntry.values[\n rowIndex\n ];\n\n const key =\n rowIdentity(\n sheetId,\n row,\n info.normalized\n );\n\n if (\n key &&\n oldMap.has(key)\n ) {\n while (\n row.length <=\n info.resolutionIndex\n ) {\n row.push('');\n }\n\n row[\n info.resolutionIndex\n ] = oldMap.get(key);\n\n preservedResolutionsCount++;\n }\n }\n}\n\nconst desiredSheets =\n Array.isArray(\n prepared\n .createSpreadsheetBody\n ?.sheets\n )\n ? prepared\n .createSpreadsheetBody\n .sheets\n : [];\n\nconst existingIds =\n new Set(\n existingSheets\n .map(\n (sheet) =>\n Number(\n sheet?.properties\n ?.sheetId\n )\n )\n .filter(\n Number.isFinite\n )\n );\n\nconst desiredIds =\n new Set(\n desiredSheets\n .map(\n (sheet) =>\n Number(\n sheet?.properties\n ?.sheetId\n )\n )\n .filter(\n Number.isFinite\n )\n );\n\nconst newlyAddedSheetIds =\n new Set();\n\nconst structureRequests = [\n {\n updateSpreadsheetProperties: {\n properties: {\n title:\n prepared.spreadsheetTitle ||\n prepared\n .createSpreadsheetBody\n ?.properties?.title ||\n spreadsheet.properties\n ?.title ||\n 'Cruce de Cuentas GLM',\n },\n fields: 'title',\n },\n },\n];\n\nif (reusingSheet) {\n const optionalId =\n Number(\n ids.cuentaMalDigitada\n );\n\n if (\n Number.isFinite(optionalId) &&\n existingIds.has(optionalId) &&\n !desiredIds.has(optionalId)\n ) {\n structureRequests.push({\n deleteSheet: {\n sheetId: optionalId,\n },\n });\n\n existingIds.delete(\n optionalId\n );\n }\n\n for (\n let desiredIndex = 0;\n desiredIndex <\n desiredSheets.length;\n desiredIndex++\n ) {\n const desired =\n desiredSheets[\n desiredIndex\n ];\n\n const props =\n desired.properties || {};\n\n const desiredId =\n Number(props.sheetId);\n\n if (\n !Number.isFinite(\n desiredId\n )\n ) {\n continue;\n }\n\n const existing =\n existingSheets.find(\n (sheet) =>\n Number(\n sheet?.properties\n ?.sheetId\n ) === desiredId\n );\n\n if (!existing) {\n const sameTitle =\n existingSheets.find(\n (sheet) =>\n String(\n sheet?.properties\n ?.title || ''\n ) ===\n String(\n props.title || ''\n )\n );\n\n if (\n sameTitle &&\n Number(\n sameTitle\n ?.properties\n ?.sheetId\n ) !== desiredId\n ) {\n structureRequests.push({\n deleteSheet: {\n sheetId:\n Number(\n sameTitle\n .properties\n .sheetId\n ),\n },\n });\n }\n\n structureRequests.push({\n addSheet: {\n properties: {\n ...props,\n // El índice es 0-based. Así \"05 Cuenta Mal Digitada\"\n // vuelve exactamente antes de \"06 Resumen\" cuando reaparece.\n index:\n desiredIndex,\n gridProperties: {\n ...(props\n .gridProperties ||\n {}),\n frozenRowCount: 1,\n },\n },\n },\n });\n\n newlyAddedSheetIds.add(\n desiredId\n );\n\n continue;\n }\n\n const currentTitle =\n String(\n existing.properties\n ?.title || ''\n );\n\n const desiredTitle =\n String(\n props.title || ''\n );\n\n const currentIndex =\n Number(\n existing.properties\n ?.index\n );\n\n const titleNeedsUpdate =\n Boolean(\n desiredTitle &&\n currentTitle !==\n desiredTitle\n );\n\n const indexNeedsUpdate =\n Number.isFinite(\n currentIndex\n ) &&\n currentIndex !==\n desiredIndex;\n\n if (\n titleNeedsUpdate ||\n indexNeedsUpdate\n ) {\n const properties = {\n sheetId:\n desiredId,\n };\n\n const fields = [];\n\n if (titleNeedsUpdate) {\n properties.title =\n desiredTitle;\n fields.push('title');\n }\n\n if (indexNeedsUpdate) {\n properties.index =\n desiredIndex;\n fields.push('index');\n }\n\n structureRequests.push({\n updateSheetProperties: {\n properties,\n fields:\n fields.join(','),\n },\n });\n }\n }\n}\n\nconst originalFormatRequests =\n Array.isArray(\n prepared\n .formatBatchBody\n ?.requests\n )\n ? prepared\n .formatBatchBody\n .requests\n : [];\n\n/*\n * IMPORTANTE AL REUTILIZAR UN REPORTE:\n *\n * \"Actualizar estructura Google Sheet\" se ejecuta ANTES de\n * \"Formatear Google Sheet\". Cuando la estructura elimina una hoja\n * (por ejemplo, \"05 Cuenta Mal Digitada\" deja de ser necesaria),\n * Google elimina automáticamente también los ProtectedRange de esa hoja.\n *\n * Por eso NO debemos intentar borrar después esos protectedRangeId en el\n * batch de formato, porque ya dejaron de existir y Google responde:\n * \"Invalid requests[x].deleteProtectedRange: No protected range with id\".\n *\n * Se identifican aquí todas las hojas que serán eliminadas por el batch\n * de estructura y se excluyen sus protecciones del batch de formato.\n */\nconst sheetIdsScheduledForDeletion =\n new Set(\n structureRequests\n .map((request) =>\n Number(\n request?.deleteSheet?.sheetId\n )\n )\n .filter(Number.isFinite)\n );\n\nconst formatRequests = [];\nconst protectedRangeIdsScheduled =\n new Set();\n\nif (reusingSheet) {\n for (\n const sheet\n of existingSheets\n ) {\n const currentSheetId =\n Number(\n sheet?.properties?.sheetId\n );\n\n // Si esta hoja será eliminada en el paso de estructura, sus\n // protecciones también desaparecerán automáticamente.\n if (\n Number.isFinite(currentSheetId) &&\n sheetIdsScheduledForDeletion.has(\n currentSheetId\n )\n ) {\n continue;\n }\n\n const protections =\n Array.isArray(\n sheet.protectedRanges\n )\n ? sheet.protectedRanges\n : [];\n\n for (\n const protection\n of protections\n ) {\n const description =\n String(\n protection.description ||\n ''\n );\n\n const protectedRangeId =\n Number(\n protection\n .protectedRangeId\n );\n\n if (\n description.startsWith(\n 'Protección GLM'\n ) &&\n Number.isFinite(\n protectedRangeId\n ) &&\n !protectedRangeIdsScheduled.has(\n protectedRangeId\n )\n ) {\n protectedRangeIdsScheduled.add(\n protectedRangeId\n );\n\n formatRequests.push({\n deleteProtectedRange: {\n protectedRangeId,\n },\n });\n }\n }\n }\n}\n\n\n/*\n * Limpieza visual al reutilizar un reporte.\n *\n * values:batchClear elimina el CONTENIDO de las filas antiguas, pero Google\n * Sheets conserva su formato. Si una ejecución anterior tenía cientos de\n * discrepancias y la nueva tiene pocas, podían quedar celdas vacías con el\n * fondo rojo/amarillo aplicado por la ejecución anterior.\n *\n * La corrección es deliberadamente limitada: solamente se limpia el\n * background de las filas que quedan DESPUÉS de la última fila escrita por\n * la nueva ejecución. No se toca ninguna fila vigente, encabezado,\n * Resolución preservada, protección, borde, ancho, fórmula ni lógica del\n * cruce.\n */\nif (reusingSheet) {\n for (\n const dataEntry\n of valueBatchBody.data || []\n ) {\n const title =\n titleFromRange(\n dataEntry.range\n );\n\n const currentSheetId =\n Number(\n titleToId.get(title)\n );\n\n if (\n !Number.isFinite(\n currentSheetId\n ) ||\n sheetIdsScheduledForDeletion.has(\n currentSheetId\n ) ||\n newlyAddedSheetIds.has(\n currentSheetId\n )\n ) {\n continue;\n }\n\n const existingSheet =\n sheetById.get(\n currentSheetId\n );\n\n if (!existingSheet) {\n continue;\n }\n\n const currentValues =\n Array.isArray(\n dataEntry.values\n )\n ? dataEntry.values\n : [];\n\n const writtenRowCount =\n currentValues.length;\n\n const writtenColumnCount =\n currentValues.reduce(\n (maximum, row) =>\n Math.max(\n maximum,\n Array.isArray(row)\n ? row.length\n : 0\n ),\n 0\n );\n\n const gridRowCount =\n Number(\n existingSheet\n ?.properties\n ?.gridProperties\n ?.rowCount || 0\n );\n\n if (\n writtenRowCount <= 0 ||\n writtenColumnCount <= 0 ||\n !Number.isFinite(\n gridRowCount\n ) ||\n gridRowCount <=\n writtenRowCount\n ) {\n continue;\n }\n\n formatRequests.push({\n repeatCell: {\n range: {\n sheetId:\n currentSheetId,\n startRowIndex:\n writtenRowCount,\n endRowIndex:\n gridRowCount,\n startColumnIndex: 0,\n endColumnIndex:\n writtenColumnCount,\n },\n cell: {\n userEnteredFormat: {\n backgroundColor: {\n red: 1,\n green: 1,\n blue: 1,\n },\n },\n },\n fields:\n 'userEnteredFormat.backgroundColor',\n },\n });\n }\n}\n\nfor (\n const request\n of originalFormatRequests\n) {\n if (\n reusingSheet &&\n request.mergeCells\n ) {\n const mergeSheetId =\n Number(\n request\n .mergeCells\n ?.range\n ?.sheetId\n );\n\n if (\n !newlyAddedSheetIds.has(\n mergeSheetId\n )\n ) {\n continue;\n }\n }\n\n formatRequests.push(\n request\n );\n}\n\nconst clearRanges =\n (valueBatchBody.data || [])\n .map(\n (entry) =>\n entry.range\n )\n .filter(Boolean);\n\nreturn [\n {\n json: {\n ok: true,\n stage:\n 'google_sheet_destino_preparado',\n spreadsheetId,\n reportUrl:\n `https://docs.google.com/spreadsheets/d/${spreadsheetId}/edit`,\n historyExists,\n reportUpdated:\n historyExists,\n reusingSheet,\n existingHistoricalId:\n report.id\n ? String(report.id)\n : '',\n reportIdentity:\n String(\n report.report_identity ||\n ''\n ),\n previousReport:\n report,\n preservedResolutionsCount,\n valueBatchBody,\n structureBatchBody: {\n requests:\n structureRequests,\n },\n clearBatchBody: {\n ranges: clearRanges,\n },\n formatBatchBody: {\n requests:\n formatRequests,\n },\n originalResponse:\n prepared.originalResponse ||\n {},\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 1376, + 7136 + ], + "id": "c14b36d8-ddba-4c94-9ced-35cb9e8e9331", + "name": "Preparar actualización Google Sheet" + }, + { + "parameters": { + "method": "POST", + "url": "={{ 'https://sheets.googleapis.com/v4/spreadsheets/' + $('Preparar actualización Google Sheet').first().json.spreadsheetId + ':batchUpdate' }}", + "authentication": "predefinedCredentialType", + "nodeCredentialType": "googleOAuth2Api", + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $('Preparar actualización Google Sheet').first().json.structureBatchBody }}", + "options": { + "timeout": 60000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 1616, + 7136 + ], + "id": "4387721b-d5d4-43f5-a8a8-8a9d44d0c7bb", + "name": "Actualizar estructura Google Sheet", + "retryOnFail": true, + "credentials": { + "googleOAuth2Api": { + "id": "dQ1MJSJSWcoWYcb8", + "name": "Google account - Isaac Producción" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "={{ 'https://sheets.googleapis.com/v4/spreadsheets/' + $('Preparar actualización Google Sheet').first().json.spreadsheetId + '/values:batchClear' }}", + "authentication": "predefinedCredentialType", + "nodeCredentialType": "googleOAuth2Api", + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $('Preparar actualización Google Sheet').first().json.clearBatchBody }}", + "options": { + "timeout": 60000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 1856, + 7136 + ], + "id": "9d75e65b-5aab-40a7-b3c7-d6212abb041c", + "name": "Limpiar Google Sheet", + "retryOnFail": true, + "credentials": { + "googleOAuth2Api": { + "id": "dQ1MJSJSWcoWYcb8", + "name": "Google account - Isaac Producción" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "={{ 'https://sheets.googleapis.com/v4/spreadsheets/' + $('Preparar actualización Google Sheet').first().json.spreadsheetId + '/values:batchUpdate' }}", + "authentication": "predefinedCredentialType", + "nodeCredentialType": "googleOAuth2Api", + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $('Preparar actualización Google Sheet').first().json.valueBatchBody }}", + "options": { + "timeout": 60000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 2096, + 7136 + ], + "id": "b0ea392e-a52e-4785-be77-d7d1c04f1a84", + "name": "Escribir Google Sheet", + "retryOnFail": true, + "credentials": { + "googleOAuth2Api": { + "id": "dQ1MJSJSWcoWYcb8", + "name": "Google account - Isaac Producción" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "={{ 'https://sheets.googleapis.com/v4/spreadsheets/' + $('Preparar actualización Google Sheet').first().json.spreadsheetId + ':batchUpdate' }}", + "authentication": "predefinedCredentialType", + "nodeCredentialType": "googleOAuth2Api", + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $('Preparar actualización Google Sheet').first().json.formatBatchBody }}", + "options": { + "timeout": 60000 + } + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 2336, + 7136 + ], + "id": "a68b8848-f9db-4a2a-8711-cc27deb265ea", + "name": "Formatear Google Sheet", + "retryOnFail": true, + "credentials": { + "googleOAuth2Api": { + "id": "dQ1MJSJSWcoWYcb8", + "name": "Google account - Isaac Producción" + } + } + }, + { + "parameters": { + "jsCode": "const context =\n $('Preparar actualización Google Sheet').first().json || {};\n\nconst spreadsheetId =\n context.spreadsheetId;\n\nif (!spreadsheetId) {\n throw new Error(\n 'No se recibió spreadsheetId para configurar permisos.'\n );\n}\n\nconst allowedEmails = [\n 'iaracena@gomezleemarketing.com',\n 'ymadera@gomezleemarketing.com',\n 'mgomez@gomezleemarketing.com',\n 'jgomez@gomezleemarketing.com',\n 'vparamo@gomezleemarketing.com',\n 'adminregional@gomezleemarketing.com',\n 'nlaureano@gomezleemarketing.com'\n];\n\nreturn allowedEmails.map((email) => ({\n json: {\n spreadsheetId,\n email,\n permissionBody: {\n type: 'user',\n role: 'writer',\n emailAddress: email,\n },\n reportUpdated:\n context.reportUpdated === true,\n },\n}));" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 2576, + 7136 + ], + "id": "845e2840-f44b-4f54-92ed-887b4bafd358", + "name": "Preparar permisos Google Sheet" + }, + { + "parameters": { + "method": "POST", + "url": "={{ 'https://www.googleapis.com/drive/v3/files/' + $json.spreadsheetId + '/permissions?sendNotificationEmail=false' }}", + "authentication": "predefinedCredentialType", + "nodeCredentialType": "googleOAuth2Api", + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $json.permissionBody }}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 2816, + 7136 + ], + "id": "c62b67d2-ee18-494d-b42b-d0fa5f45138e", + "name": "Compartir Google Sheet", + "credentials": { + "googleOAuth2Api": { + "id": "dQ1MJSJSWcoWYcb8", + "name": "Google account - Isaac Producción" + } + }, + "onError": "continueRegularOutput" + }, + { + "parameters": { + "jsCode": "const cruce = $('Cruzar Nómina vs Banco').first().json || {};\nconst sheetContext =\n $('Preparar actualización Google Sheet').first().json || {};\n\nconst metadata = cruce.metadata || {};\nconst summary = cruce.summary || {};\nconst debug = cruce.debug || {};\n\nconst spreadsheetId = sheetContext.spreadsheetId || cruce.spreadsheetId || '';\nconst reportUrl =\n sheetContext.reportUrl ||\n (spreadsheetId ? `https://docs.google.com/spreadsheets/d/${spreadsheetId}/edit` : null);\n\nfunction toNumber(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction buildPeriodKey(periodMetadata) {\n const country = periodMetadata.country || 'RD';\n const year = periodMetadata.year || '';\n const month = String(periodMetadata.month || '').padStart(2, '0');\n const periodType = periodMetadata.period_type || 'periodo';\n return `${country}-${year}-${month}-${periodType}`;\n}\n\nconst discrepancias = toNumber(summary.discrepancias);\nconst bancoSinNomina = toNumber(summary.bancoSinNomina);\nconst nominaSinCuenta = toNumber(summary.nominaSinCuenta);\nconst diferenciasNombreBanco =\n toNumber(summary.diferenciasNombreBanco);\nconst bancoSinBamboo =\n toNumber(summary.bancoSinBamboo);\nconst posiblesCuentasMalDigitadas =\n toNumber(summary.posiblesCuentasMalDigitadas);\nconst pendientes = toNumber(summary.pendientes) || (\n discrepancias +\n bancoSinNomina +\n nominaSinCuenta +\n diferenciasNombreBanco\n);\n\n// \"Pendientes cruce principal\" se mantiene separado. Sin embargo, una\n// posible cuenta mal digitada también requiere revisión humana y por eso\n// mantiene el estado GENERAL del reporte en Pendiente de revisión.\nconst requiereRevision =\n pendientes > 0 ||\n bancoSinBamboo > 0 ||\n posiblesCuentasMalDigitadas > 0;\n\n// La app final solo manejará Pendiente revisión y Resuelto.\nconst estado = requiereRevision\n ? 'pendiente_revision'\n : 'resuelto';\n\nconst reportIdentity = [\n 'RD',\n String(metadata.year || ''),\n String(metadata.month || '').padStart(2, '0'),\n String(metadata.period_type || '').trim().toLowerCase(),\n].join('-');\n\nconst reportUpdated =\n sheetContext.reportUpdated === true;\n\nconst preservedResolutionsCount =\n Number(\n sheetContext.preservedResolutionsCount || 0\n );\n\nconst payload = {\n source_app: metadata.source_app || 'cruce-cuentas-glm-republica-dominicana',\n country: metadata.country || 'RD',\n country_name: metadata.country_name || 'República Dominicana',\n client_request_id: metadata.client_request_id || null,\n report_identity: reportIdentity,\n\n year: toNumber(metadata.year),\n month: toNumber(metadata.month),\n period_type: metadata.period_type || '',\n period_label: metadata.period_label || '',\n period_start: metadata.period_start || null,\n period_end: metadata.period_end || null,\n period_key: buildPeriodKey(metadata),\n\n payroll_file_name: metadata.payroll_file_name || '',\n bank_file_names: metadata.bank_file_names || [],\n\n coincidencias: toNumber(summary.coincidencias),\n discrepancias,\n\n banco_sin_bamboo: bancoSinBamboo,\n detalle_banco_sin_bamboo:\n Array.isArray(cruce.bankWithoutBamboo)\n ? cruce.bankWithoutBamboo\n : [],\n banco_sin_nomina: bancoSinNomina,\n nomina_sin_cuenta: nominaSinCuenta,\n nomina_sin_bamboo: 0,\n bamboo_sin_nomina: 0,\n\n filas_nomina_validas: toNumber(summary.filasNominaValidas),\n cuentas_nomina_agrupadas: toNumber(summary.cuentasNominaAgrupadas),\n transacciones_banco: toNumber(summary.transaccionesBanco),\n cuentas_banco_agrupadas: toNumber(summary.cuentasBancoAgrupadas),\n\n total_nomina: toNumber(summary.totalNomina),\n total_banco: toNumber(summary.totalBanco),\n diferencia_total: toNumber(summary.diferenciaTotal),\n\n report_url: reportUrl,\n spreadsheet_id: spreadsheetId,\n estado,\n\n ejecutado_por_nombre: metadata.requested_by_name || 'Usuario GLM',\n ejecutado_por_email: metadata.requested_by_email || '',\n\n metadata: {\n ...metadata,\n report_identity: reportIdentity,\n report_updated: reportUpdated,\n preserved_resolutions_count: preservedResolutionsCount,\n diferencias_nombre_banco:\n diferenciasNombreBanco,\n banco_sin_bamboo:\n bancoSinBamboo,\n posibles_cuentas_mal_digitadas:\n posiblesCuentasMalDigitadas,\n pendientes_cruce_principal:\n pendientes,\n requiere_revision:\n requiereRevision,\n },\n summary,\n debug: {\n sheet_summaries: debug.sheet_summaries || [],\n attached_supplements: debug.attached_supplements || [],\n unattached_supplements: debug.unattached_supplements || [],\n bank_name_differences_preview:\n debug.bank_name_differences_preview || [],\n bamboo_matches:\n debug.bamboo_matches || [],\n bamboo_excluded_payments:\n debug.bamboo_excluded_payments || [],\n banco_sin_bamboo:\n cruce.bankWithoutBamboo || [],\n },\n};\n\n\nif (\n reportUpdated &&\n estado !== 'resuelto'\n) {\n payload.resuelto_por_nombre = null;\n payload.resuelto_por_email = null;\n payload.resuelto_en = null;\n payload.comentario_resolucion = null;\n}\n\nreturn [\n {\n json: {\n ...cruce,\n reportUpdated,\n preservedResolutionsCount,\n existingHistoricalId: sheetContext.existingHistoricalId || '',\n reportIdentity,\n supabaseTable: 'cruces_cuentas_gt_reportes',\n supabasePayload: payload,\n reportUrl,\n spreadsheetId,\n },\n },\n];\n" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 3056, + 7136 + ], + "id": "1bb7c133-10cb-44cc-b918-250f5d4321db", + "name": "Preparar histórico Supabase" + }, + { + "parameters": { + "method": "POST", + "url": "https://dbit.digitalcompass.agency/rest/v1/cruces_cuentas_gt_reportes?on_conflict=report_identity", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Authorization", + "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "resolution=merge-duplicates,return=representation" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ $json.supabasePayload }}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 3296, + 7136 + ], + "id": "cb3fe830-5354-44c7-ac97-55c399edb8dc", + "name": "Insertar histórico Supabase", + "onError": "continueRegularOutput" + }, + { + "parameters": { + "jsCode": "const prepared = $('Preparar Google Sheet').first().json || {};\nconst sheetContext = $('Preparar actualización Google Sheet').first().json || {};\n\nconst original =\n prepared.originalResponse ||\n prepared.original_response ||\n prepared.response ||\n {};\n\nconst spreadsheetId = sheetContext.spreadsheetId || '';\nconst reportUrl =\n sheetContext.reportUrl ||\n (spreadsheetId ? `https://docs.google.com/spreadsheets/d/${spreadsheetId}/edit` : null);\n\n\nfunction collectHistoricalObjects(value, output) {\n if (Array.isArray(value)) {\n for (const item of value) collectHistoricalObjects(item, output);\n return;\n }\n\n if (!value || typeof value !== 'object') return;\n\n output.push(value);\n\n if (Array.isArray(value.data)) {\n for (const item of value.data) collectHistoricalObjects(item, output);\n }\n}\n\nconst historicalObjects = [];\ntry {\n for (const item of $items('Insertar histórico Supabase')) {\n collectHistoricalObjects(item.json, historicalObjects);\n }\n} catch (error) {\n // Si Supabase no devolvió representación, el reporte sigue respondiendo\n // igual que antes; únicamente executionId quedará vacío.\n}\n\nconst insertedHistoricalReport =\n historicalObjects.find((item) => item && item.id) || null;\n\nconst executionId = insertedHistoricalReport?.id\n ? String(insertedHistoricalReport.id)\n : '';\n\nreturn [\n {\n json: {\n ok: original.ok ?? true,\n message: reportUrl\n ? (sheetContext.reportUpdated === true\n ? `Reporte existente actualizado correctamente. Se conservaron ${Number(sheetContext.preservedResolutionsCount || 0)} resolución(es) previamente registradas.`\n : 'Cruce procesado correctamente. Google Sheet generado.')\n : 'Cruce procesado correctamente, pero no se recibió URL del Google Sheet.',\n stage: reportUrl ? 'cruce_completado_con_reporte' : 'cruce_completado_sin_reporte',\n errors: original.errors || [],\n metadata: original.metadata || {},\n summary: original.summary || {},\n rows: original.rows || [],\n bankWithoutBamboo:\n original.bankWithoutBamboo || [],\n bambooSummary:\n original.bambooSummary || {},\n reportUrl,\n executionId: executionId || undefined,\n reportUpdated: sheetContext.reportUpdated === true,\n reusingSheet: sheetContext.reusingSheet === true,\n preservedResolutionsCount: Number(sheetContext.preservedResolutionsCount || 0),\n clientRequestId: original.metadata?.client_request_id || '',\n googleSheet: {\n spreadsheetId,\n spreadsheetUrl: reportUrl,\n },\n debug: {\n rows_returned: Array.isArray(original.rows) ? original.rows.length : 0,\n coincidencias: original.summary?.coincidencias ?? 0,\n discrepancias: original.summary?.discrepancias ?? 0,\n bancoSinBamboo:\n original.summary?.bancoSinBamboo ?? 0,\n bancoSinBambooRows:\n Array.isArray(original.bankWithoutBamboo)\n ? original.bankWithoutBamboo.length\n : 0,\n },\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 3536, + 7056 + ], + "id": "e55e23e0-548f-4c61-a2c0-ed3449e182cc", + "name": "Preparar respuesta final" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{\n(() => {\n const data = $json || {};\n\n const original =\n data.originalResponse ||\n data.original_response ||\n data.response ||\n data.cruceResponse ||\n data.cruce_response ||\n data;\n\n const summary = original.summary || data.summary || {};\n const rows = original.rows || data.rows || [];\n const bankWithoutBamboo =\n original.bankWithoutBamboo ||\n data.bankWithoutBamboo ||\n [];\n const bambooSummary =\n original.bambooSummary ||\n data.bambooSummary ||\n {};\n\n const reportUrl =\n data.reportUrl ||\n data.report_url ||\n data.googleSheetUrl ||\n data.google_sheet_url ||\n data.spreadsheetUrl ||\n data.spreadsheet_url ||\n original.reportUrl ||\n original.report_url ||\n null;\n\n return {\n ok: original.ok ?? data.ok ?? true,\n message: original.message || data.message || (reportUrl\n ? 'Cruce procesado correctamente. Google Sheet generado.'\n : 'Cruce procesado correctamente.'),\n stage: reportUrl ? 'cruce_completado_con_reporte' : 'cruce_completado',\n errors: original.errors || data.errors || [],\n metadata: original.metadata || data.metadata || {},\n summary,\n rows,\n bankWithoutBamboo,\n bambooSummary,\n reportUrl,\n executionId: original.executionId || data.executionId || null,\n reportUpdated: original.reportUpdated ?? data.reportUpdated ?? false,\n reusingSheet: original.reusingSheet ?? data.reusingSheet ?? false,\n preservedResolutionsCount: Number(original.preservedResolutionsCount ?? data.preservedResolutionsCount ?? 0),\n clientRequestId: original.clientRequestId || data.clientRequestId || original.metadata?.client_request_id || data.metadata?.client_request_id || null,\n debug: {\n source_stage: data.stage || null,\n rows_returned:\n Array.isArray(rows) ? rows.length : 0,\n banco_sin_bamboo_rows:\n Array.isArray(bankWithoutBamboo)\n ? bankWithoutBamboo.length\n : 0,\n report_url_found: Boolean(reportUrl),\n },\n };\n})()\n}}", + "options": { + "responseCode": 200, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 3776, + 7056 + ], + "id": "2b5f7c96-786d-4c69-9450-e8388108d98e", + "name": "Respond to Webhook" + }, + { + "parameters": { + "jsCode": "const prepared = $('Preparar histórico Supabase').first().json || {};\nconst payload = prepared.supabasePayload || {};\nconst metadata = payload.metadata || {};\nconst summary = payload.summary || {};\nconst reportUpdated = prepared.reportUpdated === true;\n\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction numberValue(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction formatGeneratedAt(date) {\n const timeZone = 'America/Santo_Domingo';\n\n const dateLabel = new Intl.DateTimeFormat('es-DO', {\n timeZone,\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(date);\n\n const timeLabel = new Intl.DateTimeFormat('es-DO', {\n timeZone,\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }).format(date);\n\n const hour24Raw = new Intl.DateTimeFormat('es-DO', {\n timeZone,\n hour: '2-digit',\n hour12: false,\n }).format(date);\n\n const hour24 =\n Number(String(hour24Raw).replace(/\\D/g, '')) % 24;\n\n const hourArticle =\n hour24 === 1 || hour24 === 13\n ? 'a la'\n : 'a las';\n\n return `${dateLabel} ${hourArticle} ${timeLabel}`;\n}\n\nfunction metricCard(label, value, accent, width = '20%') {\n return `\n \n \n \n \n \n ${escapeHtml(label)}\n \n\n \n ${numberValue(value).toLocaleString('es-DO')}\n \n \n \n \n \n `;\n}\n\nconst countryCode = 'RD';\nconst countryName = 'República Dominicana';\n\nconst periodLabel =\n payload.period_label ||\n metadata.period_label ||\n [\n payload.year || metadata.year,\n payload.month || metadata.month,\n payload.period_type || metadata.period_type,\n ]\n .filter(Boolean)\n .join(' · ') ||\n 'Período no especificado';\n\nconst executedByName =\n payload.ejecutado_por_nombre ||\n metadata.requested_by_name ||\n 'Usuario GLM';\n\nconst executedByEmail =\n payload.ejecutado_por_email ||\n metadata.requested_by_email ||\n '';\n\nconst reportUrl =\n payload.report_url ||\n prepared.reportUrl ||\n '';\n\nconst discrepancias = numberValue(\n payload.discrepancias ??\n summary.discrepancias\n);\n\nconst bancoSinNomina = numberValue(\n payload.banco_sin_nomina ??\n summary.bancoSinNomina\n);\n\nconst bancoSinBamboo = numberValue(\n payload.banco_sin_bamboo ??\n summary.bancoSinBamboo\n);\n\nconst diferenciasNombreBanco = numberValue(\n metadata.diferencias_nombre_banco ??\n summary.diferenciasNombreBanco\n);\n\nconst nominaSinCuenta = numberValue(\n payload.nomina_sin_cuenta ??\n summary.nominaSinCuenta\n);\n\nconst posiblesCuentasMalDigitadas = numberValue(\n metadata.posibles_cuentas_mal_digitadas ??\n summary.posiblesCuentasMalDigitadas\n);\n\nconst coincidencias = numberValue(\n payload.coincidencias ??\n summary.coincidencias\n);\n\nconst generatedAt = new Date();\nconst generatedAtLabel =\n formatGeneratedAt(generatedAt);\n\nconst statusLabel =\n String(payload.estado || '').toLowerCase() === 'resuelto'\n ? 'Resuelto'\n : 'Pendiente de revisión';\n\nconst logoUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png';\n\nconst flagUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_the_Dominican_Republic.svg.webp';\n\nconst subject = reportUpdated\n ? `Reporte actualizado - Cruce de Cuentas ${countryName} - ${periodLabel}`\n : `Nuevo reporte generado - Cruce de Cuentas ${countryName} - ${periodLabel}`;\n\n/*\n * Todos son destinatarios directos.\n * Nadie se envía en CC.\n */\n\nconst to = 'nlaureano@gomezleemarketing.com';\n\n// Paleta oficial GLM.\nconst metricCards = [\n metricCard(\n 'Discrepancias',\n discrepancias,\n '#FF6A13'\n ),\n metricCard(\n 'Banco sin nómina',\n bancoSinNomina,\n '#FF8C00'\n ),\n metricCard(\n 'Banco sin Bamboo',\n bancoSinBamboo,\n '#E87722'\n ),\n metricCard(\n 'Diferencias nombre banco',\n diferenciasNombreBanco,\n '#5B7F95'\n ),\n metricCard(\n 'Nómina sin cuenta',\n nominaSinCuenta,\n '#4F758B'\n ),\n].join('');\n\nconst wrongAccountMetricCard =\n posiblesCuentasMalDigitadas > 0\n ? metricCard(\n 'Posibles cuentas mal digitadas',\n posiblesCuentasMalDigitadas,\n '#C58B00',\n '100%'\n )\n : '';\n\nconst htmlBody = `\n\n\n\n\n \n \n ${escapeHtml(subject)}\n\n\n\n\n \n \n \n\n \n\n \n \n \n  \n \n \n\n \n \n \n\n \n \n \n \n \n\n \n \n ${reportUpdated ? 'REPORTE ACTUALIZADO' : 'REPORTE GENERADO'}\n \n \n \n \n\n \n\n \n \n\n \n \n \n\n \n\n \n Cruce de Cuentas · ${escapeHtml(countryName)}\n \n\n \n ${escapeHtml(periodLabel)}\n \n\n \n\n \n \n\n \n \n\n \n \n \n\n \n ${reportUpdated ? 'Se actualizó el reporte existente del Portal de Cruce de Cuentas GLM conservando las resoluciones previamente registradas que continúan correspondiendo a los mismos casos.' : 'Se completó una nueva ejecución del Portal de Cruce de Cuentas GLM. Este es el resumen del reporte generado.'}\n \n\n \n \n\n \n \n \n\n \n \n ${metricCards}\n \n ${\n wrongAccountMetricCard\n ? `\n \n  \n \n \n ${wrongAccountMetricCard}\n \n `\n : ''\n }\n \n\n \n \n\n \n \n \n\n \n\n \n\n \n\n \n Ejecutado por\n \n\n \n ${escapeHtml(executedByName)}\n \n\n \n ${escapeHtml(\n executedByEmail ||\n 'Correo no disponible'\n )}\n \n\n \n\n \n\n \n País\n \n\n \n \n\n \n \n \n\n \n\n \n ${escapeHtml(countryName)}\n \n\n \n ${escapeHtml(\n countryCode || '—'\n )}\n \n\n \n\n \n \n\n \n\n \n\n \n\n \n\n \n Período\n \n\n \n ${escapeHtml(periodLabel)}\n \n\n \n ${escapeHtml(generatedAtLabel)}\n \n\n \n\n \n\n \n Estado inicial\n \n\n \n ${escapeHtml(statusLabel)}\n \n\n \n Coincidencias:\n ${coincidencias.toLocaleString('es-DO')}\n \n\n \n\n \n\n \n\n \n \n\n \n ${\n reportUrl\n ? `\n \n \n\n \n Abrir reporte en Google Sheets\n \n\n \n \n `\n : ''\n }\n\n \n \n \n\n \n\n \n Notificación automática · Portal Cruce de Cuentas GLM\n
\n Los casos de revisión deben gestionarse directamente en el reporte generado.\n \n\n \n \n\n \n\n \n \n \n\n\n\n`;\n\nreturn [\n {\n json: {\n to,\n subject,\n htmlBody,\n\n notification: {\n country: countryCode,\n countryName,\n flagUrl,\n periodLabel,\n executedByName,\n executedByEmail,\n generatedAt: generatedAt.toISOString(),\n reportUrl,\n\n metrics: {\n discrepancias,\n bancoSinNomina,\n bancoSinBamboo,\n diferenciasNombreBanco,\n nominaSinCuenta,\n posiblesCuentasMalDigitadas,\n coincidencias,\n },\n },\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 3536, + 7296 + ], + "id": "2c5cfea7-6cf0-49cb-b540-951eb36862a4", + "name": "Preparar correo reporte generado" + }, + { + "parameters": { + "sendTo": "={{$json.to}}", + "subject": "={{$json.subject}}", + "message": "={{ $json.htmlBody }}", + "options": { + "appendAttribution": false + } + }, + "type": "n8n-nodes-base.gmail", + "typeVersion": 2.2, + "position": [ + 3776, + 7296 + ], + "id": "6ac3ad50-49a7-448b-81e2-661497c26695", + "name": "Enviar correo reporte generado", + "webhookId": "4bcdbd7b-503d-46ac-aeaf-9207f59f01e7", + "credentials": { + "gmailOAuth2": { + "id": "UDcO1FLJqA453V2D", + "name": "Gmail account 3" + } + }, + "onError": "continueRegularOutput" + }, + { + "parameters": { + "content": "# 🇩🇴 CRUCE DE CUENTAS — REPÚBLICA DOMINICANA\n\nFlujo quincenal para 1 Excel de nómina + todos los pagos bancarios CSV/PDF del período + BambooHR.\n\n- Moneda: DOP (RD$).\n- Q1: días 1–15. Q2: días 16–último día real del mes.\n- Banco: archivos `Pago de Nóminas_*.csv` y comprobantes ACH de Banco BHD en PDF.\n- Se cargan todos los lotes, temporales, suplementos y ACH del período antes de conciliar.\n- Tolerancia de centavos: ±RD$0.05 por fila; no convierte redondeos mínimos en discrepancias.", + "height": 260, + "width": 520 + }, + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + -2544, + 6704 + ], + "id": "7e3c7ab6-fa7c-4e86-ba33-8e5d74668002", + "name": "📌 RD · OPERACIÓN" + }, + { + "parameters": { + "content": "# 📄 NÓMINA Y CRUCE — RD\n\nHojas operativas observadas/validadas en las 16 nóminas enero–agosto 2026:\n`GLM RD`, `Whirlpool`, `Bice`, `P&G`, `KRAFT`, `Motorola`, `PMI`, `Caribe`, `Latam`, `Purina`, `Claro`, `Essity`.\n\nSe excluyen hojas auxiliares (Resumen, TSS, ISR, horas extra, AutoCrat, scripts y copias).\n\nEl cruce prioriza cuenta; admite la variante histórica RD donde una cuenta de nómina de 13 dígitos termina en `10` y el banco registra sus 11 dígitos base. Si no hay cuenta, usa nombre fuerte + monto. No fuerza coincidencias ambiguas.", + "height": 300, + "width": 700 + }, + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + -1456, + 6624 + ], + "id": "3f979cb9-2736-407c-be83-71a1cc112377", + "name": "📌 RD · NÓMINA Y MATCH" + }, + { + "parameters": { + "content": "# 📊 REPORTE / HISTÓRICOS — RD\n\nGoogle Sheet estándar de 6 pestañas:\n1. `01 Nómina vs Banco`\n2. `02 Banco sin Nómina`\n3. `03 Banco sin Bamboo`\n4. `04 Diferencias nombre banco`\n5. `05 Cuenta Mal Digitada`\n6. `06 Resumen`\n\nBambooHR se consulta con `onlyCurrent=false`. Los históricos se guardan en Supabase por `country = RD`. El reporte generado se comparte con los accesos internos y Noralmy Laureano, y el correo de RRHH se envía a `nlaureano@gomezleemarketing.com`.", + "height": 240, + "width": 620 + }, + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + -2064, + 7552 + ], + "id": "1cf3960a-1b8f-47b1-a5e6-b806ea5c879a", + "name": "📌 RD · SALIDA" + }, + { + "parameters": { + "operation": "pdf", + "options": { + "joinPages": true, + "keepSource": "json" + } + }, + "type": "n8n-nodes-base.extractFromFile", + "typeVersion": 1.1, + "position": [ + -1584, + 6896 + ], + "id": "6d6c35a5-a3e4-4c68-b1b6-9047c86a16d9", + "name": "Extract - PDF Banco RD", + "onError": "continueRegularOutput" + }, + { + "parameters": { + "jsCode": "const items=$input.all(); const base=$('Preparar entrada app').first().json||{};\nfunction clean(v){return String(v??'').replace(/\\uFEFF/g,'').replace(/\\u00A0/g,' ').replace(/\\r/g,'').replace(/[ \\t]+/g,' ').trim();}\nfunction norm(v){return clean(v).toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g,'').replace(/\\s+/g,' ').trim();}\nfunction acct(v){return clean(v).replace(/\\D/g,'').trim();} function matchAcct(v){return acct(v).replace(/^0+(?=\\d)/,'');}\nfunction money(v){const p=Number.parseFloat(String(v??'').replace(/RD\\$|DOP|\\$/gi,'').replace(/,/g,'').replace(/\\s+/g,''));return Number.isFinite(p)?Math.round(p*100)/100:0;}\nfunction iso(v){const x=clean(v);let m=x.match(/(\\d{2})[\\/-](\\d{2})[\\/-](\\d{4})/);if(m)return `${m[3]}-${m[2]}-${m[1]}`;m=x.match(/(\\d{4})-(\\d{2})-(\\d{2})/);return m?`${m[1]}-${m[2]}-${m[3]}`:'';}\nfunction inPeriod(d){const s=clean(base.metadata?.period_start),e=clean(base.metadata?.period_end);return !d||!s||!e||(d>=s&&d<=e);}\nfunction sourceMeta(i){try{return $('Preparar PDF banco RD').itemMatching(i).json||{};}catch{return {};}}\nfunction pick(text,label,nextLabel){const re=new RegExp(label+'\\\\s*:?\\\\s*([\\\\s\\\\S]*?)(?='+nextLabel+'|$)','i');const m=text.match(re);return clean(m?.[1]||'');}\nconst rows=[],summaries=[];\nfor(let i=0;iString(f.file_extension||'').toLowerCase()==='csv'):[];const out=[];for(const info of files){const key=String(info.binary_key||'');if(!key||!binary[key])continue;out.push({json:{source_file:String(binary[key]?.fileName||info.file_name||key),source_binary_key:key,currency:'DOP'},binary:{data:binary[key]}});}if(!out.length)return [{json:{no_csv_files:true,source_file:''}}];return out;" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + -1824, + 6656 + ], + "id": "cfbca2df-d207-4722-b3f9-736d77a14225", + "name": "Preparar CSV banco RD" + }, + { + "parameters": { + "jsCode": "const items=$input.all(); const base=$('Preparar entrada app').first().json||{};\nfunction clean(v){return String(v??'').replace(/\\uFEFF/g,'').replace(/\\u00A0/g,' ').replace(/\\s+/g,' ').trim();}\nfunction norm(v){return clean(v).toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g,'').replace(/[^a-z0-9 ]/g,' ').replace(/\\s+/g,' ').trim();}\nfunction parseLine(line){const out=[];let cur='',q=false;for(let i=0;i=0)return x;}for(const n of names){const e=norm(n);const x=nh.findIndex(h=>h.includes(e));if(x>=0)return x;}return -1;}\nfunction amt(v){const p=Number.parseFloat(String(v??'').replace(/DOP|RD\\$|RD|\\$/gi,'').replace(/,/g,'').replace(/\\s+/g,''));return Number.isFinite(p)?Math.round(p*100)/100:0;}\nfunction acct(v){return clean(v).replace(/\\.0$/,'').replace(/\\D/g,'').trim();}\nfunction matchAcct(v){return acct(v).replace(/^0+(?=\\d)/,'');}\nfunction origin(file){let f=String(file||'').replace(/N#U00f3minas/gi,'Nóminas');let m=f.match(/Pago de N[oó]minas_(.+?)_\\d{8}(?:\\.\\d+)?\\.csv$/i);return clean(m?.[1]||f.replace(/\\.csv$/i,''));}\nfunction dateFromFile(file){const m=String(file||'').match(/_(\\d{2})(\\d{2})(\\d{4})(?:\\.\\d+)?\\.csv$/i);return m?`${m[3]}-${m[2]}-${m[1]}`:'';}\nfunction inPeriod(d){const s=clean(base.metadata?.period_start),e=clean(base.metadata?.period_end);return !d||!s||!e||(d>=s&&d<=e);}\nfunction sourceMeta(i){try{return $('Preparar CSV banco RD').itemMatching(i).json||{};}catch{return {};}}\nconst rows=[],summaries=[];\nfor(let i=0;i5)text=buffer.toString('latin1');const lines=text.split(/\\r?\\n/).filter(l=>l.trim().length);if(!lines.length)continue;let hi=lines.findIndex(l=>{const n=norm(l);return n.includes('monto')&&(n.includes('cuenta')||n.includes('beneficiario')||n.includes('empleado'));});if(hi<0){summaries.push({file_name:sourceFile,ok:false,error:'Encabezado CSV no reconocido'});continue;}const h=parseLine(lines[hi]);const iName=idx(h,['Nombre del empleado','Beneficiario','Nombre en Archivo','Nombre']);const iAcct=idx(h,['Cuenta del empleado','No. de cuenta','No. De Cuenta','Cuenta','Cuenta destino']);const iRef=idx(h,['No. de referencia','No de referencia','Referencia']);const iConcept=idx(h,['Concepto','Descripción','Descripcion']);const iEmail=idx(h,['Correo del beneficiario','Correo','Email']);const iAmount=idx(h,['Monto']);const iStatus=idx(h,['Estado','Status']);const iReason=idx(h,['Motivo del rechazo','Motivo']);const eff=dateFromFile(sourceFile);if(!inPeriod(eff))throw new Error(`RD: ${sourceFile} pertenece a ${eff}, fuera del período seleccionado.`);const org=origin(sourceFile);let accepted=0,total=0;\n for(let j=hi+1;j=0?v[iAmount]:'');const account=acct(iAcct>=0?v[iAcct]:'');if(amount<=0||account.length<5)continue;const status=clean(iStatus>=0?v[iStatus]:'Procesada');const statusN=norm(status);const processed=statusN.includes('procesad')||statusN.includes('aplicad')||statusN.includes('complet');const rejected=statusN.includes('rechaz');const name=clean(iName>=0?v[iName]:'');const reason=clean(iReason>=0?v[iReason]:'');const row={source_file:sourceFile.replace(/N#U00f3minas/gi,'Nóminas'),row_number:j+1,bank_row_key:`RD_CSV|${sourceFile}|${j+1}`,account,account_match:matchAcct(account),raw_account:account,account_is_valid:true,reference:clean(iRef>=0?v[iRef]:''),bank_name_file:name,bank_account_holder:'',amount,currency:'DOP',application_date:eff,concept:clean(iConcept>=0?v[iConcept]:''),email:clean(iEmail>=0?v[iEmail]:'').toLowerCase(),status,status_normalized:statusN,processed,rejected,rejection_reason:reason,origin:org,is_supplement:norm(org).includes('bono bice')};rows.push(row);accepted++;if(processed)total+=amount;}\n summaries.push({file_name:sourceFile.replace(/N#U00f3minas/gi,'Nóminas'),origin:org,ok:true,rows_count:accepted,processed_total:Math.round(total*100)/100,effective_date:eff});\n}\nreturn [{json:{stage:'banco_rd_csv_parseado',bank_csv:{rows,file_summaries:summaries,rows_count:rows.length}}}];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + -1344, + 6656 + ], + "id": "d893ba59-6f82-471c-9138-6a13f02f0f29", + "name": "Parsear CSV banco RD" + }, + { + "parameters": { + "mode": "combine", + "combineBy": "combineByPosition", + "options": {} + }, + "type": "n8n-nodes-base.merge", + "typeVersion": 3.2, + "position": [ + -1120, + 6816 + ], + "id": "01613afc-0399-444e-b2c1-7ac112b3eaf1", + "name": "Merge CSV + PDF RD" + }, + { + "parameters": { + "jsCode": "const input=$input.first().json||{}; const base=$('Preparar entrada app').first().json||{};\nfunction clean(v){return String(v??'').replace(/\\s+/g,' ').trim();} function round(v){return Math.round((Number(v)||0)*100)/100;} function norm(v){return clean(v).toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g,'');}\nconst csv=input.bank_csv||{};const pdf=input.bank_pdf||{};const rows=[...(Array.isArray(csv.rows)?csv.rows:[]),...(Array.isArray(pdf.rows)?pdf.rows:[])];if(!rows.length)throw new Error('RD: no se encontró ninguna transacción bancaria válida en los archivos cargados.');\n// Protección contra duplicados exactos entre archivos/lotes. La fecha+cuenta+monto+referencia/nombre define una transacción.\nconst seen=new Map();for(const row of rows){const key=[row.application_date||'',row.account_match||row.account||'',Number(row.amount||0).toFixed(2),clean(row.reference)||norm(row.bank_name_file)].join('|');if(seen.has(key)){const prev=seen.get(key);if(prev.source_file!==row.source_file)throw new Error(`RD: transacción bancaria duplicada entre ${prev.source_file} y ${row.source_file} (${row.account}, RD$ ${Number(row.amount||0).toFixed(2)}).`);}else seen.set(key,row);}\nconst processed=rows.filter(r=>r.processed===true);const rejected=rows.filter(r=>r.rejected===true);const total=round(processed.reduce((s,r)=>s+Number(r.amount||0),0));const supplements=rows.filter(r=>r.is_supplement===true);\nreturn [{json:{...base,stage:'banco_rd_normalizado',bank:{files_count:Number(base.summary?.bank_files_count||0),file_summaries:[...(csv.file_summaries||[]),...(pdf.file_summaries||[])],rows_count:processed.length,all_rows_count:rows.length,rejected_rows_count:rejected.length,total_amount:total,totals_by_currency:{DOP:total},rows,processed_rows:processed,rejected_rows:rejected,supplement_rows:supplements}}}];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + -880, + 6816 + ], + "id": "5f8522f0-b197-4c7f-ad7e-6426fa05dadf", + "name": "Consolidar Banco RD" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "2ee21859-e9a1-4a13-a99d-75c86cd1df2d", + "leftValue": "={{ $json.no_pdf_files !== true }}", + "rightValue": "", + "operator": { + "type": "boolean", + "operation": "true", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + -1712, + 6896 + ], + "id": "8f0021c8-9b24-410e-9dbf-edc24a655618", + "name": "¿Hay PDF banco RD?" + } + ], + "pinData": {}, + "connections": { + "Webhook": { + "main": [ + [ + { + "node": "Preparar entrada app", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar entrada app": { + "main": [ + [ + { + "node": "¿Entrada RD válida?", + "type": "main", + "index": 0 + } + ] + ] + }, + "¿Entrada RD válida?": { + "main": [ + [ + { + "node": "Preparar PDF banco RD", + "type": "main", + "index": 0 + }, + { + "node": "Preparar CSV banco RD", + "type": "main", + "index": 0 + }, + { + "node": "Preparar archivos nómina RD", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Responder error entrada RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar PDF banco RD": { + "main": [ + [ + { + "node": "¿Hay PDF banco RD?", + "type": "main", + "index": 0 + } + ] + ] + }, + "Extract - PDF Banco RD": { + "main": [ + [ + { + "node": "Parsear PDF banco RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Parsear PDF banco RD": { + "main": [ + [ + { + "node": "Merge CSV + PDF RD", + "type": "main", + "index": 1 + } + ] + ] + }, + "Preparar archivos nómina RD": { + "main": [ + [ + { + "node": "Extract - Archivo Nómina RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Extract - Archivo Nómina RD": { + "main": [ + [ + { + "node": "Normalizar Nómina RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Normalizar Nómina RD": { + "main": [ + [ + { + "node": "Merge Banco + Nómina RD", + "type": "main", + "index": 1 + } + ] + ] + }, + "Merge Banco + Nómina RD": { + "main": [ + [ + { + "node": "HTTP - Empleados BambooHR RD", + "type": "main", + "index": 0 + }, + { + "node": "Merge - Agregar BambooHR RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "HTTP - Empleados BambooHR RD": { + "main": [ + [ + { + "node": "Normalizar BambooHR RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Normalizar BambooHR RD": { + "main": [ + [ + { + "node": "Merge - Agregar BambooHR RD", + "type": "main", + "index": 1 + } + ] + ] + }, + "Merge - Agregar BambooHR RD": { + "main": [ + [ + { + "node": "Obtener alias BambooHR Supabase", + "type": "main", + "index": 0 + } + ] + ] + }, + "Obtener alias BambooHR Supabase": { + "main": [ + [ + { + "node": "Cruzar Nómina vs Banco", + "type": "main", + "index": 0 + } + ] + ] + }, + "Cruzar Nómina vs Banco": { + "main": [ + [ + { + "node": "Preparar Google Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar Google Sheet": { + "main": [ + [ + { + "node": "Buscar reporte existente Supabase", + "type": "main", + "index": 0 + } + ] + ] + }, + "Buscar reporte existente Supabase": { + "main": [ + [ + { + "node": "Crear Google Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Crear Google Sheet": { + "main": [ + [ + { + "node": "Leer Google Sheet actual", + "type": "main", + "index": 0 + } + ] + ] + }, + "Leer Google Sheet actual": { + "main": [ + [ + { + "node": "Preparar actualización Google Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar actualización Google Sheet": { + "main": [ + [ + { + "node": "Actualizar estructura Google Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Actualizar estructura Google Sheet": { + "main": [ + [ + { + "node": "Limpiar Google Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Limpiar Google Sheet": { + "main": [ + [ + { + "node": "Escribir Google Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Escribir Google Sheet": { + "main": [ + [ + { + "node": "Formatear Google Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Formatear Google Sheet": { + "main": [ + [ + { + "node": "Preparar permisos Google Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar permisos Google Sheet": { + "main": [ + [ + { + "node": "Compartir Google Sheet", + "type": "main", + "index": 0 + } + ] + ] + }, + "Compartir Google Sheet": { + "main": [ + [ + { + "node": "Preparar histórico Supabase", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar histórico Supabase": { + "main": [ + [ + { + "node": "Insertar histórico Supabase", + "type": "main", + "index": 0 + } + ] + ] + }, + "Insertar histórico Supabase": { + "main": [ + [ + { + "node": "Preparar respuesta final", + "type": "main", + "index": 0 + }, + { + "node": "Preparar correo reporte generado", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar respuesta final": { + "main": [ + [ + { + "node": "Respond to Webhook", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar correo reporte generado": { + "main": [ + [ + { + "node": "Enviar correo reporte generado", + "type": "main", + "index": 0 + } + ] + ] + }, + "¿Hay PDF banco RD?": { + "main": [ + [ + { + "node": "Extract - PDF Banco RD", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Parsear PDF banco RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar CSV banco RD": { + "main": [ + [ + { + "node": "Parsear CSV banco RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Parsear CSV banco RD": { + "main": [ + [ + { + "node": "Merge CSV + PDF RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Merge CSV + PDF RD": { + "main": [ + [ + { + "node": "Consolidar Banco RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Consolidar Banco RD": { + "main": [ + [ + { + "node": "Merge Banco + Nómina RD", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": { + "executionOrder": "v1", + "binaryMode": "separate" + }, + "versionId": "8bbd433e-cf87-4d10-b1e5-f1de1c7602f3", + "meta": { + "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" + }, + "id": "", + "tags": [] +} \ No newline at end of file diff --git a/workflows_n8n/Portal de Verificaci├│n de N├│mina Rep├║blica Dominicana - Env├¡o de Reporte.json b/workflows_n8n/Portal de Verificaci├│n de N├│mina Rep├║blica Dominicana - Env├¡o de Reporte.json new file mode 100644 index 0000000..078285a --- /dev/null +++ b/workflows_n8n/Portal de Verificaci├│n de N├│mina Rep├║blica Dominicana - Env├¡o de Reporte.json @@ -0,0 +1,348 @@ +{ + "name": "Portal de Verificación de Nómina República Dominicana - Envío de Reporte", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "cruce-cuentas-rd-marcar-resuelto", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + 784, + 592 + ], + "id": "a022c055-76c6-42a4-a129-7f2c5bf62ed3", + "name": "Webhook Marcar Resuelto", + "webhookId": "fa25ffc4-8acd-4033-b585-95dc2a9fb753" + }, + { + "parameters": { + "jsCode": "const body = $input.first().json.body || $input.first().json || {};\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nconst reportId = clean(body.reportId || body.id);\nconst comentarioResolucion = clean(body.comentarioResolucion || body.comentario || '');\nconst resueltoPorNombre = clean(body.resueltoPorNombre || body.userName || 'Usuario GLM');\nconst resueltoPorEmail = clean(body.resueltoPorEmail || body.userEmail || '');\n\nconst errors = [];\n\nif (!reportId) {\n errors.push('No se recibió el ID del reporte.');\n}\n\nif (!comentarioResolucion) {\n errors.push('Debe indicar un comentario de resolución.');\n}\n\nif (comentarioResolucion.length < 10) {\n errors.push('El comentario de resolución debe ser más descriptivo.');\n}\n\nif (errors.length > 0) {\n return [\n {\n json: {\n ok: false,\n stage: 'validacion_resolucion',\n errors,\n reportId,\n },\n },\n ];\n}\n\nreturn [\n {\n json: {\n ok: true,\n stage: 'resolucion_validada',\n reportId,\n comentarioResolucion,\n resueltoPorNombre,\n resueltoPorEmail,\n resolvedAt: new Date().toISOString(),\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 992, + 592 + ], + "id": "565fac7c-9509-4a0b-b0d3-eb5ddc428200", + "name": "Validar resolución" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "c89884c6-de96-4b08-bd20-54644bb95bc7", + "leftValue": "={{ $json.ok }}", + "rightValue": "", + "operator": { + "type": "boolean", + "operation": "true", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + 1200, + 592 + ], + "id": "c97e1b04-44d4-418a-af76-3c4372302060", + "name": "¿Solicitud válida?" + }, + { + "parameters": { + "method": "PATCH", + "url": "={{ 'https://dbit.digitalcompass.agency/rest/v1/cruces_cuentas_gt_reportes?id=eq.' + encodeURIComponent($json.reportId) + '&country=eq.RD' }}", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Authorization", + "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Prefer", + "value": "return=representation" + } + ] + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{\n {\n estado: 'resuelto',\n resuelto_por_nombre: $json.resueltoPorNombre,\n resuelto_por_email: $json.resueltoPorEmail,\n resuelto_en: $json.resolvedAt,\n comentario_resolucion: $json.comentarioResolucion,\n updated_at: $json.resolvedAt\n }\n}}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 1536, + 480 + ], + "id": "79da760e-34a3-411e-9fb1-8262ed64d0f8", + "name": "Actualizar reporte Supabase" + }, + { + "parameters": { + "jsCode": "const input = $input.first().json || {};\nconst report = Array.isArray(input) ? input[0] : input;\n\nif (!report || !report.id) {\n throw new Error(\n 'No se encontró un reporte de República Dominicana con el ID recibido.'\n );\n}\n\nif (String(report.country || '').toUpperCase() !== 'RD') {\n throw new Error(\n 'El reporte localizado no pertenece a República Dominicana.'\n );\n}\nconst original = $('Validar resolución').first().json || {};\n\n\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction numberValue(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nconst periodo = report.period_label || 'Período no especificado';\nconst reportUrl = report.report_url || '';\n\nconst discrepancias = numberValue(report.discrepancias);\nconst bancoSinNomina = numberValue(report.banco_sin_nomina);\nconst bancoSinBamboo = numberValue(report.banco_sin_bamboo);\nconst nominaSinCuenta = numberValue(report.nomina_sin_cuenta);\n\nconst resolvedAt = original.resolvedAt || new Date().toISOString();\n\nconst resolvedDateLabel = new Date(resolvedAt).toLocaleString('es-DO', {\n timeZone: 'America/Santo_Domingo',\n dateStyle: 'long',\n timeStyle: 'short',\n});\n\nconst resolvedByName =\n original.resueltoPorNombre || 'Usuario GLM';\n\nconst resolvedByEmail =\n original.resueltoPorEmail || '';\n\nconst resolutionComment =\n original.comentarioResolucion || 'Sin comentario registrado.';\n\nconst logoUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png';\n\nconst flagUrl =\n 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_the_Dominican_Republic.svg.webp';\n\nconst subject =\n `Reporte resuelto - Cruce de Cuentas República Dominicana - ${periodo}`;\n\nconst textBody = `\nHola equipo,\n\nSe marcó como resuelto un reporte de Cruce de Cuentas República Dominicana.\n\nPeríodo:\n${periodo}\n\nResuelto por:\n${resolvedByName}${resolvedByEmail ? ` (${resolvedByEmail})` : ''}\n\nFecha/hora:\n${resolvedDateLabel}\n\nResumen:\n- Discrepancias: ${discrepancias}\n- Banco sin nómina: ${bancoSinNomina}\n- Banco sin Bamboo: ${bancoSinBamboo}\n- Nómina sin cuenta: ${nominaSinCuenta}\n\nComentario:\n${resolutionComment}\n\nGoogle Sheet:\n${reportUrl || 'No disponible'}\n\nSaludos,\nPortal Cruce de Cuentas GLM\n`.trim();\n\nconst htmlBody = `\n\n\n\n \n \n ${escapeHtml(subject)}\n\n\n\n\n \n \n \n\n \n\n \n \n \n \n \n\n \n  \n \n\n \n \n
\n Cruce de Cuentas República Dominicana\n \"Bandera\n
\n\n

\n Reporte marcado como resuelto\n

\n \n \n\n \n \n

\n Hola equipo,\n

\n\n

\n El siguiente reporte fue revisado y marcado como\n resuelto.\n

\n \n \n\n \n \n \n \n \n Período\n \n\n \n ${escapeHtml(periodo)}\n \n \n\n \n \n Resuelto por\n \n\n \n ${escapeHtml(resolvedByName)}\n ${\n resolvedByEmail\n ? `
${escapeHtml(resolvedByEmail)}`\n : ''\n }\n \n \n\n \n \n Fecha y hora\n \n\n \n ${escapeHtml(resolvedDateLabel)}\n \n \n \n \n \n\n \n \n
\n Resumen del reporte\n
\n \n \n\n \n \n \n \n \n
\n ${discrepancias}\n
\n\n
\n Discrepancias\n
\n \n\n \n
\n ${bancoSinBamboo}\n
\n\n
\n Banco sin Bamboo\n
\n \n\n \n
\n ${bancoSinNomina}\n
\n\n
\n Banco sin nómina\n
\n \n\n \n
\n ${nominaSinCuenta}\n
\n\n
\n Nómina sin cuenta\n
\n \n \n \n \n \n\n \n \n
\n Comentario de resolución\n
\n \n \n\n \n \n
\n ${escapeHtml(resolutionComment).replace(/\\n/g, '
')}\n
\n \n \n\n ${\n reportUrl\n ? `\n \n \n \n Abrir Google Sheet\n \n \n \n `\n : ''\n }\n\n \n \n Mensaje automático del Portal Cruce de Cuentas GLM.\n \n \n\n \n \n \n \n\n\n\n`.trim();\n\nreturn [\n {\n json: {\n to: 'nlaureano@gomezleemarketing.com',\n cc: [\n 'iaracena@gomezleemarketing.com',\n 'jgomez@gomezleemarketing.com',\n 'mgomez@gomezleemarketing.com',\n 'vparamo@gomezleemarketing.com',\n 'ymadera@gomezleemarketing.com',\n 'adminregional@gomezleemarketing.com',\n ].join(','),\n subject,\n textBody,\n htmlBody,\n report,\n resolution: original,\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 1744, + 480 + ], + "id": "02463a59-7266-4147-82fd-0ce5d3b3a266", + "name": "Preparar correo equipo RD" + }, + { + "parameters": { + "sendTo": "={{$json.to}}", + "subject": "={{$json.subject}}", + "message": "={{ $json.htmlBody }}", + "options": { + "appendAttribution": false, + "ccList": "={{ $json.cc }}" + } + }, + "type": "n8n-nodes-base.gmail", + "typeVersion": 2.2, + "position": [ + 1952, + 480 + ], + "id": "2c04b8bb-d02d-4747-be94-cb57976c75c7", + "name": "Enviar correo equipo RD", + "webhookId": "ad819366-b163-4e58-86de-a7cd158630b1", + "credentials": { + "gmailOAuth2": { + "id": "UDcO1FLJqA453V2D", + "name": "Gmail account 3" + } + } + }, + { + "parameters": { + "jsCode": "const original = $('Validar resolución').first().json || {};\nconst updatedResponse = $('Actualizar reporte Supabase').first().json || {};\nconst updatedReport = Array.isArray(updatedResponse) ? updatedResponse[0] : updatedResponse;\n\nreturn [\n {\n json: {\n ok: true,\n stage: 'reporte_resuelto',\n message: 'Reporte marcado como resuelto correctamente.',\n report: {\n id: original.reportId,\n estado: 'resuelto',\n estadoLabel: 'RESUELTO',\n country: 'RD',\n countryName: 'República Dominicana',\n resueltoPorNombre: original.resueltoPorNombre,\n resueltoPorEmail: original.resueltoPorEmail,\n resueltoEn: original.resolvedAt,\n comentarioResolucion: original.comentarioResolucion,\n reportUrl: updatedReport.report_url || '',\n },\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 2160, + 480 + ], + "id": "9764074b-94f0-4da5-a25d-b43a2d19e242", + "name": "Preparar respuesta resuelto" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{ $json }}", + "options": { + "responseCode": 200, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "name": "Access-Control-Allow-Methods", + "value": "GET,POST,OPTIONS" + }, + { + "name": "Access-Control-Allow-Headers", + "value": "Content-Type, Authorization" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 2368, + 480 + ], + "id": "5ad5c184-189e-4288-b952-3914998c199c", + "name": "Responder resuelto app" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{ $json }}", + "options": { + "responseCode": 400, + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "name": "Access-Control-Allow-Methods", + "value": "GET,POST,OPTIONS" + }, + { + "name": "Access-Control-Allow-Headers", + "value": "Content-Type, Authorization" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 1408, + 688 + ], + "id": "793a6fb2-2075-4fe3-8607-aeb5773750d4", + "name": "Responder error resolución" + }, + { + "parameters": { + "content": "# ✅ CIERRE DE REPORTE — REPÚBLICA DOMINICANA\n\nRecibe desde el Portal de Verificación de Nóminas la solicitud para marcar un reporte de República Dominicana como resuelto.\n\n## Validación inicial\n\nEl Webhook recibe la información enviada por la aplicación y valida datos como:\n\n- Identificador del reporte.\n- Usuario que realizó el cierre.\n- Estado solicitado.\n- Comentario o detalle de resolución.\n- Datos necesarios para localizar el registro en Supabase.\n\nLa solicitud solamente continúa cuando contiene información válida y suficiente.\n\n## Actualización del reporte\n\nCuando la solicitud es correcta:\n\n1. Localiza el reporte correspondiente en Supabase.\n2. Cambia su estado a RESUELTO.\n3. Registra quién realizó la resolución.\n4. Guarda la fecha y hora del cierre.\n5. Conserva el comentario o información de seguimiento disponible.\n\nSupabase es la fuente oficial del estado del reporte dentro del portal.\n\n## Notificación al equipo de República Dominicana\n\nDespués de actualizar el registro:\n\n1. Se prepara un correo para el equipo responsable de República Dominicana.\n2. Se incluyen los datos principales del reporte.\n3. Se informa que el caso fue marcado como resuelto.\n4. Se identifica al usuario que realizó el cierre.\n5. Se envía el correo mediante Gmail.\n\nLa notificación permite que el equipo conozca el cambio sin tener que revisar manualmente el portal.\n\n## Respuesta a la aplicación\n\nCuando el proceso termina correctamente:\n\n- Se construye una respuesta de éxito.\n- Se confirma que el reporte fue actualizado.\n- Se devuelve el nuevo estado a la aplicación.\n- El portal puede actualizar inmediatamente su interfaz.\n\n## Ruta de error\n\nCuando la solicitud es inválida:\n\n- No se modifica Supabase.\n- No se envía el correo al equipo de República Dominicana.\n- Se devuelve una respuesta de error a la aplicación.\n- Se informa que faltan datos o que la solicitud no pudo procesarse.\n\n## Reglas\n\n- No marcar un reporte como resuelto sin un identificador válido.\n- No enviar la notificación antes de confirmar la actualización en Supabase.\n- No declarar éxito cuando la base de datos no fue actualizada.\n- Toda respuesta del Webhook debe cerrarse correctamente para evitar solicitudes abiertas.\n- La ruta de error debe terminar sin realizar cambios parciales.", + "height": 1264, + "width": 2624, + "color": "#28765F" + }, + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 0, + 0 + ], + "id": "45a0e3c4-7cd3-4a7b-9cb5-93bf0e4dbb99", + "name": "Sticky Note" + } + ], + "pinData": {}, + "connections": { + "Webhook Marcar Resuelto": { + "main": [ + [ + { + "node": "Validar resolución", + "type": "main", + "index": 0 + } + ] + ] + }, + "Validar resolución": { + "main": [ + [ + { + "node": "¿Solicitud válida?", + "type": "main", + "index": 0 + } + ] + ] + }, + "¿Solicitud válida?": { + "main": [ + [ + { + "node": "Actualizar reporte Supabase", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Responder error resolución", + "type": "main", + "index": 0 + } + ] + ] + }, + "Actualizar reporte Supabase": { + "main": [ + [ + { + "node": "Preparar correo equipo RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar respuesta resuelto": { + "main": [ + [ + { + "node": "Responder resuelto app", + "type": "main", + "index": 0 + } + ] + ] + }, + "Preparar correo equipo RD": { + "main": [ + [ + { + "node": "Enviar correo equipo RD", + "type": "main", + "index": 0 + } + ] + ] + }, + "Enviar correo equipo RD": { + "main": [ + [ + { + "node": "Preparar respuesta resuelto", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": { + "executionOrder": "v1", + "binaryMode": "separate" + }, + "versionId": "d6f26eac-3b3b-4bfa-909d-b9cfcfaf0c7f", + "meta": { + "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" + }, + "id": "", + "tags": [] +} \ No newline at end of file diff --git a/workflows_n8n/Portal de Verificaci├│n de N├│mina Rep├║blica Dominicana - Hist├│ricos.json b/workflows_n8n/Portal de Verificaci├│n de N├│mina Rep├║blica Dominicana - Hist├│ricos.json new file mode 100644 index 0000000..84eed6c --- /dev/null +++ b/workflows_n8n/Portal de Verificaci├│n de N├│mina Rep├║blica Dominicana - Hist├│ricos.json @@ -0,0 +1,164 @@ +{ + "name": "Portal de Verificación de Nómina República Dominicana - Históricos", + "nodes": [ + { + "parameters": { + "path": "cruce-cuentas-rd-historicos", + "responseMode": "responseNode", + "options": {} + }, + "type": "n8n-nodes-base.webhook", + "typeVersion": 2.1, + "position": [ + 304, + 272 + ], + "id": "7550a9f8-2006-4330-8b6d-f0a99b53ba69", + "name": "Webhook Históricos RD", + "webhookId": "31b88d0c-ab11-4ff9-87c9-895b4fb6b097" + }, + { + "parameters": { + "jsCode": "const items = $input.all();\n\nfunction formatDate(value) {\n if (!value) return '';\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return String(value).slice(0, 10);\n return date.toISOString().slice(0, 10);\n}\n\nfunction toNumber(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction normalizeStatus(value, discrepancias) {\n const status = String(value || '').toLowerCase();\n\n if (status === 'resuelto') return 'resuelto';\n if (status === 'procesado' && toNumber(discrepancias) === 0) return 'procesado';\n\n return 'pendiente_revision';\n}\n\nfunction statusLabel(status) {\n if (status === 'resuelto') return 'RESUELTO';\n if (status === 'procesado') return 'PROCESADO';\n return 'PENDIENTE REVISIÓN';\n}\n\nconst reports = items.map((item) => {\n const row = item.json || {};\n\n const discrepancias = toNumber(row.discrepancias);\n const bancoSinNomina = toNumber(row.banco_sin_nomina);\n const nominaSinCuenta = toNumber(row.nomina_sin_cuenta);\n const bancoSinBamboo = toNumber(row.banco_sin_bamboo);\n const nominaSinBamboo = toNumber(row.nomina_sin_bamboo);\n const bambooSinNomina = toNumber(row.bamboo_sin_nomina);\n\n const diferenciasNombreBanco = toNumber(row.metadata?.diferencias_nombre_banco ?? row.summary?.diferenciasNombreBanco ?? row.diferencias_nombre_banco);\n const posiblesCuentasMalDigitadas = toNumber(row.metadata?.posibles_cuentas_mal_digitadas ?? row.summary?.posiblesCuentasMalDigitadas ?? row.posibles_cuentas_mal_digitadas);\n const fallbackPendientes = discrepancias + bancoSinNomina + nominaSinCuenta + diferenciasNombreBanco + posiblesCuentasMalDigitadas;\n const savedPendientes = Number(row.metadata?.pendientes_cruce_principal ?? row.summary?.pendientes ?? row.pendientes_cruce_principal);\n const totalPendientes = Number.isFinite(savedPendientes) ? savedPendientes : fallbackPendientes;\n\n const estado = normalizeStatus(row.estado, totalPendientes);\n\n return {\n id: row.id,\n\n fecha: formatDate(row.period_end || row.ejecutado_en || row.created_at),\n fechaEjecucion: row.ejecutado_en || row.created_at,\n\n periodo: row.period_label || '',\n year: row.year,\n month: row.month,\n periodType: row.period_type,\n periodStart: row.period_start,\n periodEnd: row.period_end,\n\n archivoNomina: row.payroll_file_name || '',\n archivosBanco: row.bank_file_names || [],\n\n coincidencias: toNumber(row.coincidencias),\n discrepancias,\n bancoSinNomina,\n nominaSinCuenta,\n bancoSinBamboo,\n nameDifferences: diferenciasNombreBanco,\n diferenciasNombreBanco,\n possibleWrongAccounts: posiblesCuentasMalDigitadas,\n posiblesCuentasMalDigitadas,\n pendientes: totalPendientes,\n totalPending: totalPendientes,\n nominaSinBamboo,\n bambooSinNomina,\n totalPendientes,\n\n totalNomina: toNumber(row.total_nomina),\n totalBanco: toNumber(row.total_banco),\n diferenciaTotal: toNumber(row.diferencia_total),\n\n estado,\n estadoLabel: statusLabel(estado),\n\n reportUrl: row.report_url || '',\n spreadsheetId: row.spreadsheet_id || '',\n\n ejecutadoPorNombre: row.ejecutado_por_nombre || '',\n ejecutadoPorEmail: row.ejecutado_por_email || '',\n\n resueltoPorNombre: row.resuelto_por_nombre || '',\n resueltoPorEmail: row.resuelto_por_email || '',\n resueltoEn: row.resuelto_en || null,\n comentarioResolucion: row.comentario_resolucion || '',\n };\n});\n\nreturn [\n {\n json: {\n ok: true,\n stage: 'historicos_rd_listos',\n count: reports.length,\n reports,\n },\n },\n];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 720, + 272 + ], + "id": "bfa3bf09-7076-4322-9ea5-abde67baa069", + "name": "Normalizar históricos para app" + }, + { + "parameters": { + "url": "https://dbit.digitalcompass.agency/rest/v1/cruces_cuentas_gt_reportes?select=*&country=eq.RD&order=ejecutado_en.desc&limit=100", + "sendHeaders": true, + "headerParameters": { + "parameters": [ + { + "name": "apikey", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Authorization", + "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" + }, + { + "name": "Content-Type", + "value": "application/json" + } + ] + }, + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.4, + "position": [ + 512, + 272 + ], + "id": "6ca12435-bafc-44ab-ba07-08d6a1d72cf4", + "name": "Consultar históricos Supabase" + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{ $json }}", + "options": { + "responseHeaders": { + "entries": [ + { + "name": "Content-Type", + "value": "application/json" + }, + { + "name": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "name": "Access-Control-Allow-Methods", + "value": "GET,POST,OPTIONS" + }, + { + "name": "Access-Control-Allow-Headers", + "value": "Content-Type, Authorization" + } + ] + } + } + }, + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.5, + "position": [ + 944, + 272 + ], + "id": "c735659d-0fb1-452d-bb88-34d4076dbba9", + "name": "Responder históricos app" + }, + { + "parameters": { + "content": "# 📚 HISTÓRICOS DE VERIFICACIÓN — REPÚBLICA DOMINICANA\n\nEntrega a la aplicación el historial de reportes procesados para República Dominicana.\n\n- Consulta únicamente registros con `country = RD`.\n- Supabase continúa usando la tabla histórica compartida `cruces_cuentas_gt_reportes`; el nombre de la tabla es legado y funciona como tabla multi-país.\n- Devuelve la misma estructura de históricos utilizada por los demás países.\n- Este webhook sirve como respaldo; la app intenta primero la RPC paginada de Supabase.", + "height": 496, + "width": 1360, + "color": 6 + }, + "type": "n8n-nodes-base.stickyNote", + "typeVersion": 1, + "position": [ + 0, + 0 + ], + "id": "b7b1d804-34f1-4da1-9cde-ac6aee727f02", + "name": "Sticky Note" + } + ], + "pinData": {}, + "connections": { + "Consultar históricos Supabase": { + "main": [ + [ + { + "node": "Normalizar históricos para app", + "type": "main", + "index": 0 + } + ] + ] + }, + "Normalizar históricos para app": { + "main": [ + [ + { + "node": "Responder históricos app", + "type": "main", + "index": 0 + } + ] + ] + }, + "Webhook Históricos RD": { + "main": [ + [ + { + "node": "Consultar históricos Supabase", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": { + "executionOrder": "v1", + "binaryMode": "separate" + }, + "versionId": "47a1ec31-b680-45cf-98d5-9e9099779ccd", + "meta": { + "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" + }, + "id": "", + "tags": [] +} \ No newline at end of file